Changeset 245040 in webkit


Ignore:
Timestamp:
May 7, 2019 3:15:59 PM (5 years ago)
Author:
ysuzuki@apple.com
Message:

TemplateObject passed to template literal tags are not always identical for the same source location.
https://bugs.webkit.org/show_bug.cgi?id=190756

Reviewed by Saam Barati.

JSTests:

  • complex.yaml:
  • complex/tagged-template-regeneration-after.js: Added.

(shouldBe):

  • complex/tagged-template-regeneration.js: Added.

(call):
(test):

  • modules/tagged-template-inside-module.js: Added.

(from.string_appeared_here.call):

  • modules/tagged-template-inside-module/other-tagged-templates.js: Added.

(call):
(export.otherTaggedTemplates):

  • stress/call-and-construct-should-return-same-tagged-templates.js: Added.

(shouldBe):
(call):
(poly):

  • stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js: Added.

(shouldBe):
(call):

  • stress/tagged-templates-in-function-in-direct-eval.js: Added.

(shouldBe):
(call):
(test):

  • stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js: Added.

(shouldBe):
(call):

  • stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js: Added.

(shouldBe):
(call):

  • stress/tagged-templates-in-multiple-functions.js: Added.

(shouldBe):
(call):
(a):
(b):
(c):

  • stress/tagged-templates-with-same-start-offset.js: Added.

(shouldBe):

Source/JavaScriptCore:

Tagged template literal requires that the site object is allocated per source location. Previously, we create the site object
when linking CodeBlock and cache it in CodeBlock. But this is wrong because,

  1. CodeBlock can be jettisoned and regenerated. So every time CodeBlock is regenerated, we get the different site object.
  2. Call and Construct can have different CodeBlock. Even if the function is called in call-form or construct-form, we should return the same site object.

In this patch, we start caching these site objects in the top-level ScriptExecutable, this matches the spec's per source location since the only one top-level
ScriptExecutable is created for the given script code. Each ScriptExecutable of JSFunction can be created multiple times because CodeBlock creates it.
But the top-level one is not created by CodeBlock. This top-level ScriptExecutable is well-aligned to the Script itself. The top-level ScriptExecutable now has HashMap,
which maps source locations to cached site objects.

  1. This patch threads the top-level ScriptExecutable to each FunctionExecutable creation. Each FunctionExecutable has a reference to the top-level ScriptExecutable.
  2. We put TemplateObjectMap in ScriptExecutable, which manages cached template objects.
  3. We move FunctionExecutable::m_cachedPolyProtoStructure to the FunctionExecutable::RareDate to keep FunctionExecutable 128 bytes.
  4. TemplateObjectMap is indexed with endOffset of TaggedTemplate.
  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result:
  • Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result:
  • Scripts/wkbuiltins/builtins_templates.py:
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::setConstantRegisters):

  • bytecode/CodeBlock.h:
  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::UnlinkedFunctionExecutable::link):

  • bytecode/UnlinkedFunctionExecutable.h:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::addTemplateObjectConstant):
(JSC::BytecodeGenerator::emitGetTemplateObject):

  • bytecompiler/BytecodeGenerator.h:
  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createTaggedTemplate):

  • runtime/CachedTypes.cpp:

(JSC::CachedTemplateObjectDescriptor::encode):
(JSC::CachedTemplateObjectDescriptor::decode const):
(JSC::CachedJSValue::encode):
(JSC::CachedJSValue::decode const):

  • runtime/EvalExecutable.cpp:

(JSC::EvalExecutable::ensureTemplateObjectMap):
(JSC::EvalExecutable::visitChildren):

  • runtime/EvalExecutable.h:
  • runtime/FunctionExecutable.cpp:

(JSC::FunctionExecutable::finishCreation):
(JSC::FunctionExecutable::visitChildren):
(JSC::FunctionExecutable::fromGlobalCode):
(JSC::FunctionExecutable::ensureRareDataSlow):
(JSC::FunctionExecutable::ensureTemplateObjectMap):

  • runtime/FunctionExecutable.h:
  • runtime/JSModuleRecord.cpp:

(JSC::JSModuleRecord::instantiateDeclarations):

  • runtime/JSTemplateObjectDescriptor.cpp:

(JSC::JSTemplateObjectDescriptor::JSTemplateObjectDescriptor):
(JSC::JSTemplateObjectDescriptor::create):

  • runtime/JSTemplateObjectDescriptor.h:
  • runtime/ModuleProgramExecutable.cpp:

(JSC::ModuleProgramExecutable::ensureTemplateObjectMap):
(JSC::ModuleProgramExecutable::visitChildren):

  • runtime/ModuleProgramExecutable.h:
  • runtime/ProgramExecutable.cpp:

(JSC::ProgramExecutable::ensureTemplateObjectMap):
(JSC::ProgramExecutable::visitChildren):

  • runtime/ProgramExecutable.h:
  • runtime/ScriptExecutable.cpp:

(JSC::ScriptExecutable::topLevelExecutable):
(JSC::ScriptExecutable::createTemplateObject):
(JSC::ScriptExecutable::ensureTemplateObjectMapImpl):
(JSC::ScriptExecutable::ensureTemplateObjectMap):

  • runtime/ScriptExecutable.h:
  • tools/JSDollarVM.cpp:

(JSC::functionCreateBuiltin):
(JSC::functionDeleteAllCodeWhenIdle):
(JSC::JSDollarVM::finishCreation):

Location:
trunk
Files:
12 added
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r245031 r245040  
     12019-05-07  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        TemplateObject passed to template literal tags are not always identical for the same source location.
     4        https://bugs.webkit.org/show_bug.cgi?id=190756
     5
     6        Reviewed by Saam Barati.
     7
     8        * complex.yaml:
     9        * complex/tagged-template-regeneration-after.js: Added.
     10        (shouldBe):
     11        * complex/tagged-template-regeneration.js: Added.
     12        (call):
     13        (test):
     14        * modules/tagged-template-inside-module.js: Added.
     15        (from.string_appeared_here.call):
     16        * modules/tagged-template-inside-module/other-tagged-templates.js: Added.
     17        (call):
     18        (export.otherTaggedTemplates):
     19        * stress/call-and-construct-should-return-same-tagged-templates.js: Added.
     20        (shouldBe):
     21        (call):
     22        (poly):
     23        * stress/tagged-templates-in-direct-eval-should-not-produce-same-site-object.js: Added.
     24        (shouldBe):
     25        (call):
     26        * stress/tagged-templates-in-function-in-direct-eval.js: Added.
     27        (shouldBe):
     28        (call):
     29        (test):
     30        * stress/tagged-templates-in-global-function-should-not-produce-same-site-object.js: Added.
     31        (shouldBe):
     32        (call):
     33        * stress/tagged-templates-in-indirect-eval-should-not-produce-same-site-object.js: Added.
     34        (shouldBe):
     35        (call):
     36        * stress/tagged-templates-in-multiple-functions.js: Added.
     37        (shouldBe):
     38        (call):
     39        (a):
     40        (b):
     41        (c):
     42        * stress/tagged-templates-with-same-start-offset.js: Added.
     43        (shouldBe):
     44
    1452019-05-07  Robin Morisset  <rmorisset@apple.com>
    246
  • trunk/JSTests/complex.yaml

    r245026 r245040  
    2626- path: complex/generator-regeneration.js
    2727  cmd: runComplexTest [], ["generator-regeneration-after.js"], "--useDollarVM=1"
     28
     29- path: complex/tagged-template-regeneration.js
     30  cmd: runComplexTest [], ["tagged-template-regeneration-after.js"], "--useDollarVM=1"
  • trunk/Source/JavaScriptCore/ChangeLog

    r245035 r245040  
     12019-05-07  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        TemplateObject passed to template literal tags are not always identical for the same source location.
     4        https://bugs.webkit.org/show_bug.cgi?id=190756
     5
     6        Reviewed by Saam Barati.
     7
     8        Tagged template literal requires that the site object is allocated per source location. Previously, we create the site object
     9        when linking CodeBlock and cache it in CodeBlock. But this is wrong because,
     10
     11        1. CodeBlock can be jettisoned and regenerated. So every time CodeBlock is regenerated, we get the different site object.
     12        2. Call and Construct can have different CodeBlock. Even if the function is called in call-form or construct-form, we should return the same site object.
     13
     14        In this patch, we start caching these site objects in the top-level ScriptExecutable, this matches the spec's per source location since the only one top-level
     15        ScriptExecutable is created for the given script code. Each ScriptExecutable of JSFunction can be created multiple times because CodeBlock creates it.
     16        But the top-level one is not created by CodeBlock. This top-level ScriptExecutable is well-aligned to the Script itself. The top-level ScriptExecutable now has HashMap,
     17        which maps source locations to cached site objects.
     18
     19        1. This patch threads the top-level ScriptExecutable to each FunctionExecutable creation. Each FunctionExecutable has a reference to the top-level ScriptExecutable.
     20        2. We put TemplateObjectMap in ScriptExecutable, which manages cached template objects.
     21        3. We move FunctionExecutable::m_cachedPolyProtoStructure to the FunctionExecutable::RareDate to keep FunctionExecutable 128 bytes.
     22        4. TemplateObjectMap is indexed with endOffset of TaggedTemplate.
     23
     24        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result:
     25        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result:
     26        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result:
     27        * Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result:
     28        * Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result:
     29        * Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result:
     30        * Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result:
     31        * Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result:
     32        * Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result:
     33        * Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result:
     34        * Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result:
     35        * Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result:
     36        * Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result:
     37        * Scripts/wkbuiltins/builtins_templates.py:
     38        * bytecode/CodeBlock.cpp:
     39        (JSC::CodeBlock::finishCreation):
     40        (JSC::CodeBlock::setConstantRegisters):
     41        * bytecode/CodeBlock.h:
     42        * bytecode/UnlinkedFunctionExecutable.cpp:
     43        (JSC::UnlinkedFunctionExecutable::link):
     44        * bytecode/UnlinkedFunctionExecutable.h:
     45        * bytecompiler/BytecodeGenerator.cpp:
     46        (JSC::BytecodeGenerator::addTemplateObjectConstant):
     47        (JSC::BytecodeGenerator::emitGetTemplateObject):
     48        * bytecompiler/BytecodeGenerator.h:
     49        * parser/ASTBuilder.h:
     50        (JSC::ASTBuilder::createTaggedTemplate):
     51        * runtime/CachedTypes.cpp:
     52        (JSC::CachedTemplateObjectDescriptor::encode):
     53        (JSC::CachedTemplateObjectDescriptor::decode const):
     54        (JSC::CachedJSValue::encode):
     55        (JSC::CachedJSValue::decode const):
     56        * runtime/EvalExecutable.cpp:
     57        (JSC::EvalExecutable::ensureTemplateObjectMap):
     58        (JSC::EvalExecutable::visitChildren):
     59        * runtime/EvalExecutable.h:
     60        * runtime/FunctionExecutable.cpp:
     61        (JSC::FunctionExecutable::finishCreation):
     62        (JSC::FunctionExecutable::visitChildren):
     63        (JSC::FunctionExecutable::fromGlobalCode):
     64        (JSC::FunctionExecutable::ensureRareDataSlow):
     65        (JSC::FunctionExecutable::ensureTemplateObjectMap):
     66        * runtime/FunctionExecutable.h:
     67        * runtime/JSModuleRecord.cpp:
     68        (JSC::JSModuleRecord::instantiateDeclarations):
     69        * runtime/JSTemplateObjectDescriptor.cpp:
     70        (JSC::JSTemplateObjectDescriptor::JSTemplateObjectDescriptor):
     71        (JSC::JSTemplateObjectDescriptor::create):
     72        * runtime/JSTemplateObjectDescriptor.h:
     73        * runtime/ModuleProgramExecutable.cpp:
     74        (JSC::ModuleProgramExecutable::ensureTemplateObjectMap):
     75        (JSC::ModuleProgramExecutable::visitChildren):
     76        * runtime/ModuleProgramExecutable.h:
     77        * runtime/ProgramExecutable.cpp:
     78        (JSC::ProgramExecutable::ensureTemplateObjectMap):
     79        (JSC::ProgramExecutable::visitChildren):
     80        * runtime/ProgramExecutable.h:
     81        * runtime/ScriptExecutable.cpp:
     82        (JSC::ScriptExecutable::topLevelExecutable):
     83        (JSC::ScriptExecutable::createTemplateObject):
     84        (JSC::ScriptExecutable::ensureTemplateObjectMapImpl):
     85        (JSC::ScriptExecutable::ensureTemplateObjectMap):
     86        * runtime/ScriptExecutable.h:
     87        * tools/JSDollarVM.cpp:
     88        (JSC::functionCreateBuiltin):
     89        (JSC::functionDeleteAllCodeWhenIdle):
     90        (JSC::JSDollarVM::finishCreation):
     91
    1922019-05-07  Robin Morisset  <rmorisset@apple.com>
    293
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result

    r245026 r245040  
    142142JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
    143143{\
    144     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
     144    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
    145145JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
    146146#undef DEFINE_BUILTIN_GENERATOR
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result

    r245026 r245040  
    159159JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
    160160{\
    161     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
     161    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
    162162JSC_FOREACH_BUILTIN.PROMISE_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
    163163#undef DEFINE_BUILTIN_GENERATOR
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result

    r245026 r245040  
    168168JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
    169169{\
    170     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
     170    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
    171171JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
    172172#undef DEFINE_BUILTIN_GENERATOR
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result

    r245026 r245040  
    283283JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
    284284{\
    285     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
     285    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
    286286JSC_FOREACH_BUILTIN.PROTOTYPE_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
    287287#undef DEFINE_BUILTIN_GENERATOR
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result

    r245026 r245040  
    140140JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
    141141{\
    142     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
     142    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
    143143JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
    144144#undef DEFINE_BUILTIN_GENERATOR
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result

    r245026 r245040  
    213213JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
    214214{\
    215     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
     215    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
    216216JSC_FOREACH_BUILTINCONSTRUCTOR_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
    217217#undef DEFINE_BUILTIN_GENERATOR
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result

    r245026 r245040  
    141141JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
    142142{\
    143     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
     143    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
    144144JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
    145145#undef DEFINE_BUILTIN_GENERATOR
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result

    r245026 r245040  
    221221{\
    222222    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    223     return clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     223    return clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().anotherGuardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    224224}
    225225WEBCORE_FOREACH_ANOTHERGUARDEDINTERNALBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result

    r245026 r245040  
    191191{\
    192192    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    193     return clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     193    return clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().arbitraryConditionalGuardBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    194194}
    195195WEBCORE_FOREACH_ARBITRARYCONDITIONALGUARD_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result

    r245026 r245040  
    191191{\
    192192    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    193     return clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     193    return clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().guardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    194194}
    195195WEBCORE_FOREACH_GUARDEDBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result

    r245026 r245040  
    223223{\
    224224    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    225     return clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     225    return clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().guardedInternalBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    226226}
    227227WEBCORE_FOREACH_GUARDEDINTERNALBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result

    r245026 r245040  
    185185{\
    186186    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    187     return clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     187    return clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().unguardedBuiltinBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    188188}
    189189WEBCORE_FOREACH_UNGUARDEDBUILTIN_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
  • trunk/Source/JavaScriptCore/Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result

    r245026 r245040  
    276276{\
    277277    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    278     return clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     278    return clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().xmlCasingTestBuiltins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    279279}
    280280WEBCORE_FOREACH_XMLCASINGTEST_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
  • trunk/Source/JavaScriptCore/Scripts/wkbuiltins/builtins_templates.py

    r245026 r245040  
    8686JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\
    8787{\\
    88     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     88    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    8989}
    9090${macroPrefix}_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
     
    9797JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \\
    9898{\\
    99     return vm.builtinExecutables()->codeName##Executable()->link(vm, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
     99    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \
    100100}
    101101${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
     
    109109{\\
    110110    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \\
    111     return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
     111    return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
    112112}
    113113${macroPrefix}_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
     
    121121{\\
    122122    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \\
    123     return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
     123    return clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Executable()->link(vm, nullptr, clientData->builtinFunctions().${objectNameLC}Builtins().codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); \\
    124124}
    125125${macroPrefix}_FOREACH_${objectMacro}_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r245026 r245040  
    396396        vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(vm), ownerExecutable->typeProfilingEndOffset(vm));
    397397
    398     setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
     398    ScriptExecutable* topLevelExecutable = ownerExecutable->topLevelExecutable();
     399    setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation(), topLevelExecutable);
    399400    RETURN_IF_EXCEPTION(throwScope, false);
    400401
     
    422423        if (shouldUpdateFunctionHasExecutedCache)
    423424            vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
    424         m_functionDecls[i].set(vm, this, unlinkedExecutable->link(vm, ownerExecutable->source()));
     425        m_functionDecls[i].set(vm, this, unlinkedExecutable->link(vm, topLevelExecutable, ownerExecutable->source()));
    425426    }
    426427
     
    430431        if (shouldUpdateFunctionHasExecutedCache)
    431432            vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
    432         m_functionExprs[i].set(vm, this, unlinkedExecutable->link(vm, ownerExecutable->source()));
     433        m_functionExprs[i].set(vm, this, unlinkedExecutable->link(vm, topLevelExecutable, ownerExecutable->source()));
    433434    }
    434435
     
    871872}
    872873
    873 void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
     874void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable)
    874875{
    875876    VM& vm = *m_vm;
     
    899900                    constant = clone;
    900901                } else if (auto* descriptor = jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) {
    901                     auto* templateObject = descriptor->createTemplateObject(exec);
     902                    auto* templateObject = topLevelExecutable->createTemplateObject(exec, descriptor);
    902903                    RETURN_IF_EXCEPTION(scope, void());
    903904                    constant = templateObject;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r245026 r245040  
    912912    void setConstantIdentifierSetRegisters(VM&, const Vector<ConstantIdentifierSetEntry>& constants);
    913913
    914     void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation);
     914    void setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable);
    915915
    916916    void replaceConstant(int index, JSValue value)
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r245026 r245040  
    159159}
    160160
    161 FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& passedParentSource, Optional<int> overrideLineNumber, Intrinsic intrinsic)
     161FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, ScriptExecutable* topLevelExecutable, const SourceCode& passedParentSource, Optional<int> overrideLineNumber, Intrinsic intrinsic)
    162162{
    163163    SourceCode source = linkedSourceCode(passedParentSource);
     
    167167        hasFunctionOverride = FunctionOverrides::initializeOverrideFor(source, overrideInfo);
    168168
    169     FunctionExecutable* result = FunctionExecutable::create(vm, source, this, intrinsic);
     169    FunctionExecutable* result = FunctionExecutable::create(vm, topLevelExecutable, source, this, intrinsic);
    170170    if (overrideLineNumber)
    171171        result->setOverrideLineNumber(*overrideLineNumber);
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r245026 r245040  
    127127
    128128    SourceCode linkedSourceCode(const SourceCode&) const;
    129     JS_EXPORT_PRIVATE FunctionExecutable* link(VM&, const SourceCode& parentSource, Optional<int> overrideLineNumber = WTF::nullopt, Intrinsic = NoIntrinsic);
     129    JS_EXPORT_PRIVATE FunctionExecutable* link(VM&, ScriptExecutable* topLevelExecutable, const SourceCode& parentSource, Optional<int> overrideLineNumber = WTF::nullopt, Intrinsic = NoIntrinsic);
    130130
    131131    void clearCode(VM& vm)
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r245026 r245040  
    29492949}
    29502950
    2951 RegisterID* BytecodeGenerator::addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&& descriptor)
    2952 {
    2953     JSTemplateObjectDescriptor* descriptorValue = m_templateObjectDescriptorMap.ensure(descriptor.copyRef(), [&] {
    2954         return JSTemplateObjectDescriptor::create(*vm(), WTFMove(descriptor));
     2951RegisterID* BytecodeGenerator::addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&& descriptor, int endOffset)
     2952{
     2953    auto result = m_templateObjectDescriptorSet.add(WTFMove(descriptor));
     2954    JSTemplateObjectDescriptor* descriptorValue = m_templateDescriptorMap.ensure(endOffset, [&] {
     2955        return JSTemplateObjectDescriptor::create(*vm(), result.iterator->copyRef(), endOffset);
    29552956    }).iterator->value;
    2956 
    29572957    int index = addConstantIndex();
    29582958    m_codeBlock->addConstant(descriptorValue);
     
    41424142            cookedStrings.append(string->cooked()->impl());
    41434143    }
    4144     RefPtr<RegisterID> constant = addTemplateObjectConstant(TemplateObjectDescriptor::create(WTFMove(rawStrings), WTFMove(cookedStrings)));
     4144    RefPtr<RegisterID> constant = addTemplateObjectConstant(TemplateObjectDescriptor::create(WTFMove(rawStrings), WTFMove(cookedStrings)), taggedTemplate->endOffset());
    41454145    if (!dst)
    41464146        return constant.get();
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r245026 r245040  
    10611061        using IdentifierStringMap = HashMap<UniquedStringImpl*, JSString*, IdentifierRepHash>;
    10621062        using IdentifierBigIntMap = HashMap<BigIntMapEntry, JSBigInt*>;
    1063         using TemplateObjectDescriptorMap = HashMap<Ref<TemplateObjectDescriptor>, JSTemplateObjectDescriptor*>;
     1063        using TemplateObjectDescriptorSet = HashSet<Ref<TemplateObjectDescriptor>>;
     1064        using TemplateDescriptorMap = HashMap<uint64_t, JSTemplateObjectDescriptor*, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
    10641065
    10651066        // Helper for emitCall() and emitConstruct(). This works because the set of
     
    11531154        JSString* addStringConstant(const Identifier&);
    11541155        JSValue addBigIntConstant(const Identifier&, uint8_t radix, bool sign);
    1155         RegisterID* addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&&);
     1156        RegisterID* addTemplateObjectConstant(Ref<TemplateObjectDescriptor>&&, int);
    11561157
    11571158        const InstructionStream& instructions() const { return m_writer; }
     
    12711272        IdentifierStringMap m_stringMap;
    12721273        IdentifierBigIntMap m_bigIntMap;
    1273         TemplateObjectDescriptorMap m_templateObjectDescriptorMap;
     1274        TemplateObjectDescriptorSet m_templateObjectDescriptorSet;
     1275        TemplateDescriptorMap m_templateDescriptorMap;
    12741276
    12751277        StaticPropertyAnalyzer m_staticPropertyAnalyzer;
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r244038 r245040  
    332332        auto node = new (m_parserArena) TaggedTemplateNode(location, base, templateLiteral);
    333333        setExceptionLocation(node, start, divot, end);
     334        setEndOffset(node, end.offset);
    334335        return node;
    335336    }
  • trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp

    r245026 r245040  
    11531153class CachedTemplateObjectDescriptor : public CachedObject<TemplateObjectDescriptor> {
    11541154public:
    1155     void encode(Encoder& encoder, const TemplateObjectDescriptor& templateObjectDescriptor)
    1156     {
    1157         m_rawStrings.encode(encoder, templateObjectDescriptor.rawStrings());
    1158         m_cookedStrings.encode(encoder, templateObjectDescriptor.cookedStrings());
    1159     }
    1160 
    1161     Ref<TemplateObjectDescriptor> decode(Decoder& decoder) const
     1155    void encode(Encoder& encoder, const JSTemplateObjectDescriptor& descriptor)
     1156    {
     1157        m_rawStrings.encode(encoder, descriptor.descriptor().rawStrings());
     1158        m_cookedStrings.encode(encoder, descriptor.descriptor().cookedStrings());
     1159        m_endOffset = descriptor.endOffset();
     1160    }
     1161
     1162    JSTemplateObjectDescriptor* decode(Decoder& decoder) const
    11621163    {
    11631164        TemplateObjectDescriptor::StringVector decodedRawStrings;
     
    11651166        m_rawStrings.decode(decoder, decodedRawStrings);
    11661167        m_cookedStrings.decode(decoder, decodedCookedStrings);
    1167         return TemplateObjectDescriptor::create(WTFMove(decodedRawStrings), WTFMove(decodedCookedStrings));
     1168        return JSTemplateObjectDescriptor::create(decoder.vm(), TemplateObjectDescriptor::create(WTFMove(decodedRawStrings), WTFMove(decodedCookedStrings)), m_endOffset);
    11681169    }
    11691170
     
    11711172    CachedVector<CachedString, 4> m_rawStrings;
    11721173    CachedVector<CachedOptional<CachedString>, 4> m_cookedStrings;
     1174    int m_endOffset;
    11731175};
    11741176
     
    12441246        if (auto* templateObjectDescriptor = jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) {
    12451247            m_type = EncodedType::TemplateObjectDescriptor;
    1246             this->allocate<CachedTemplateObjectDescriptor>(encoder)->encode(encoder, templateObjectDescriptor->descriptor());
     1248            this->allocate<CachedTemplateObjectDescriptor>(encoder)->encode(encoder, *templateObjectDescriptor);
    12471249            return;
    12481250        }
     
    12791281            break;
    12801282        case EncodedType::TemplateObjectDescriptor:
    1281             v = JSTemplateObjectDescriptor::create(decoder.vm(), this->buffer<CachedTemplateObjectDescriptor>()->decode(decoder));
     1283            v = this->buffer<CachedTemplateObjectDescriptor>()->decode(decoder);
    12821284            break;
    12831285        case EncodedType::BigInt:
  • trunk/Source/JavaScriptCore/runtime/EvalExecutable.cpp

    r245026 r245040  
    4545}
    4646
     47auto EvalExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
     48{
     49    return ensureTemplateObjectMapImpl(m_templateObjectMap);
     50}
     51
    4752void EvalExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
    4853{
     
    5257    visitor.append(thisObject->m_unlinkedEvalCodeBlock);
    5358    visitor.append(thisObject->m_evalCodeBlock);
     59    if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
     60        auto locker = holdLock(thisObject->cellLock());
     61        for (auto& entry : *map)
     62            visitor.append(entry.value);
     63    }
    5464}
    5565
  • trunk/Source/JavaScriptCore/runtime/EvalExecutable.h

    r245026 r245040  
    7070    bool allowDirectEvalCache() const { return m_unlinkedEvalCodeBlock->allowDirectEvalCache(); }
    7171
     72    TemplateObjectMap& ensureTemplateObjectMap(VM&);
     73
    7274protected:
    7375    friend class ExecutableBase;
     
    8183    WriteBarrier<ExecutableToCodeBlockEdge> m_evalCodeBlock;
    8284    WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
     85    std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
    8386};
    8487
  • trunk/Source/JavaScriptCore/runtime/FunctionExecutable.cpp

    r245026 r245040  
    5555}
    5656
    57 void FunctionExecutable::finishCreation(VM& vm)
     57void FunctionExecutable::finishCreation(VM& vm, ScriptExecutable* topLevelExecutable)
    5858{
    5959    Base::finishCreation(vm);
     60    m_topLevelExecutable.set(vm, this, topLevelExecutable ? topLevelExecutable : this);
    6061    if (VM::canUseJIT())
    6162        m_singletonFunction.set(vm, this, InferredValue::create(vm));
     
    8687    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    8788    Base::visitChildren(thisObject, visitor);
     89    visitor.append(thisObject->m_topLevelExecutable);
    8890    visitor.append(thisObject->m_codeBlockForCall);
    8991    visitor.append(thisObject->m_codeBlockForConstruct);
     
    9193    if (VM::canUseJIT())
    9294        visitor.append(thisObject->m_singletonFunction);
    93     visitor.append(thisObject->m_cachedPolyProtoStructure);
     95    if (RareData* rareData = thisObject->m_rareData.get()) {
     96        visitor.append(rareData->m_cachedPolyProtoStructure);
     97        if (TemplateObjectMap* map = rareData->m_templateObjectMap.get()) {
     98            auto locker = holdLock(thisObject->cellLock());
     99            for (auto& entry : *map)
     100                visitor.append(entry.value);
     101        }
     102    }
    94103}
    95104
     
    104113        return nullptr;
    105114
    106     return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
     115    return unlinkedExecutable->link(exec.vm(), nullptr, source, overrideLineNumber);
    107116}
    108117
     
    116125    rareData->m_typeProfilingStartOffset = typeProfilingStartOffset();
    117126    rareData->m_typeProfilingEndOffset = typeProfilingEndOffset();
     127    WTF::storeStoreFence();
    118128    m_rareData = WTFMove(rareData);
    119129    return *m_rareData;
     
    131141}
    132142
     143auto FunctionExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
     144{
     145    RareData& rareData = ensureRareData();
     146    return ensureTemplateObjectMapImpl(rareData.m_templateObjectMap);
     147}
     148
    133149} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h

    r245026 r245040  
    4949    }
    5050
    51     static FunctionExecutable* create(VM& vm, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, Intrinsic intrinsic)
     51    static FunctionExecutable* create(VM& vm, ScriptExecutable* topLevelExecutable, const SourceCode& source, UnlinkedFunctionExecutable* unlinkedExecutable, Intrinsic intrinsic)
    5252    {
    5353        FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(vm.heap)) FunctionExecutable(vm, source, unlinkedExecutable, intrinsic);
    54         executable->finishCreation(vm);
     54        executable->finishCreation(vm, topLevelExecutable);
    5555        return executable;
    5656    }
     
    283283
    284284    // Cached poly proto structure for the result of constructing this executable.
    285     Structure* cachedPolyProtoStructure() { return m_cachedPolyProtoStructure.get(); }
    286     void setCachedPolyProtoStructure(VM& vm, Structure* structure) { m_cachedPolyProtoStructure.set(vm, this, structure); }
     285    Structure* cachedPolyProtoStructure()
     286    {
     287        if (UNLIKELY(m_rareData))
     288            return m_rareData->m_cachedPolyProtoStructure.get();
     289        return nullptr;
     290    }
     291    void setCachedPolyProtoStructure(VM& vm, Structure* structure)
     292    {
     293        ensureRareData().m_cachedPolyProtoStructure.set(vm, this, structure);
     294    }
    287295
    288296    InlineWatchpointSet& ensurePolyProtoWatchpoint()
     
    294302
    295303    Box<InlineWatchpointSet> sharedPolyProtoWatchpoint() const { return m_polyProtoWatchpoint; }
     304
     305    ScriptExecutable* topLevelExecutable() const { return m_topLevelExecutable.get(); }
     306
     307    TemplateObjectMap& ensureTemplateObjectMap(VM&);
    296308
    297309private:
     
    299311    FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, Intrinsic);
    300312   
    301     void finishCreation(VM&);
     313    void finishCreation(VM&, ScriptExecutable* topLevelExecutable);
    302314
    303315    friend class ScriptExecutable;
     
    312324        unsigned m_typeProfilingStartOffset { UINT_MAX };
    313325        unsigned m_typeProfilingEndOffset { UINT_MAX };
     326        std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
     327        WriteBarrier<Structure> m_cachedPolyProtoStructure;
    314328    };
    315329
     
    322336    RareData& ensureRareDataSlow();
    323337
     338    // FIXME: We can merge rareData pointer and top-level executable pointer. First time, setting parent.
     339    // If RareData is required, materialize RareData, swap it, and store top-level executable pointer inside RareData.
     340    // https://bugs.webkit.org/show_bug.cgi?id=197625
    324341    std::unique_ptr<RareData> m_rareData;
     342    WriteBarrier<ScriptExecutable> m_topLevelExecutable;
    325343    WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
    326344    WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForCall;
     
    330348        WatchpointState m_singletonFunctionState;
    331349    };
    332     WriteBarrier<Structure> m_cachedPolyProtoStructure;
    333350    Box<InlineWatchpointSet> m_polyProtoWatchpoint;
    334351};
  • trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp

    r245026 r245040  
    201201                    unlinkedFunctionExecutable->typeProfilingEndOffset());
    202202            }
    203             JSFunction* function = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, moduleProgramExecutable->source()), moduleEnvironment);
     203            JSFunction* function = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, moduleProgramExecutable, moduleProgramExecutable->source()), moduleEnvironment);
    204204            bool putResult = false;
    205205            symbolTablePutTouchWatchpointSet(moduleEnvironment, exec, unlinkedFunctionExecutable->name(), function, /* shouldThrowReadOnlyError */ false, /* ignoreReadOnlyErrors */ true, putResult);
  • trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.cpp

    r245026 r245040  
    3737
    3838
    39 JSTemplateObjectDescriptor::JSTemplateObjectDescriptor(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor)
     39JSTemplateObjectDescriptor::JSTemplateObjectDescriptor(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor, int endOffset)
    4040    : Base(vm, vm.templateObjectDescriptorStructure.get())
    4141    , m_descriptor(WTFMove(descriptor))
     42    , m_endOffset(endOffset)
    4243{
    4344}
    4445
    45 JSTemplateObjectDescriptor* JSTemplateObjectDescriptor::create(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor)
     46JSTemplateObjectDescriptor* JSTemplateObjectDescriptor::create(VM& vm, Ref<TemplateObjectDescriptor>&& descriptor, int endOffset)
    4647{
    47     JSTemplateObjectDescriptor* result = new (NotNull, allocateCell<JSTemplateObjectDescriptor>(vm.heap)) JSTemplateObjectDescriptor(vm, WTFMove(descriptor));
     48    JSTemplateObjectDescriptor* result = new (NotNull, allocateCell<JSTemplateObjectDescriptor>(vm.heap)) JSTemplateObjectDescriptor(vm, WTFMove(descriptor), endOffset);
    4849    result->finishCreation(vm);
    4950    return result;
  • trunk/Source/JavaScriptCore/runtime/JSTemplateObjectDescriptor.h

    r245026 r245040  
    3939    DECLARE_INFO;
    4040
    41     static JSTemplateObjectDescriptor* create(VM&, Ref<TemplateObjectDescriptor>&&);
     41    static JSTemplateObjectDescriptor* create(VM&, Ref<TemplateObjectDescriptor>&&, int);
    4242
    4343    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     
    5050    JSArray* createTemplateObject(ExecState*);
    5151
     52    int endOffset() const { return m_endOffset; }
     53
    5254protected:
    5355    static void destroy(JSCell*);
    5456
    5557private:
    56     JSTemplateObjectDescriptor(VM&, Ref<TemplateObjectDescriptor>&&);
     58    JSTemplateObjectDescriptor(VM&, Ref<TemplateObjectDescriptor>&&, int);
    5759
    5860    Ref<TemplateObjectDescriptor> m_descriptor;
     61    int m_endOffset { 0 };
    5962};
    6063
  • trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp

    r245026 r245040  
    8686}
    8787
     88auto ModuleProgramExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
     89{
     90    return ensureTemplateObjectMapImpl(m_templateObjectMap);
     91}
     92
    8893void ModuleProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
    8994{
     
    9499    visitor.append(thisObject->m_moduleEnvironmentSymbolTable);
    95100    visitor.append(thisObject->m_moduleProgramCodeBlock);
     101    if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
     102        auto locker = holdLock(thisObject->cellLock());
     103        for (auto& entry : *map)
     104            visitor.append(entry.value);
     105    }
    96106}
    97107
  • trunk/Source/JavaScriptCore/runtime/ModuleProgramExecutable.h

    r245026 r245040  
    7070    SymbolTable* moduleEnvironmentSymbolTable() { return m_moduleEnvironmentSymbolTable.get(); }
    7171
     72    TemplateObjectMap& ensureTemplateObjectMap(VM&);
     73
    7274private:
    7375    friend class ExecutableBase;
     
    8183    WriteBarrier<SymbolTable> m_moduleEnvironmentSymbolTable;
    8284    WriteBarrier<ExecutableToCodeBlockEdge> m_moduleProgramCodeBlock;
     85    std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
    8386};
    8487
  • trunk/Source/JavaScriptCore/runtime/ProgramExecutable.cpp

    r245026 r245040  
    217217}
    218218
     219auto ProgramExecutable::ensureTemplateObjectMap(VM&) -> TemplateObjectMap&
     220{
     221    return ensureTemplateObjectMapImpl(m_templateObjectMap);
     222}
     223
    219224void ProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor)
    220225{
     
    224229    visitor.append(thisObject->m_unlinkedProgramCodeBlock);
    225230    visitor.append(thisObject->m_programCodeBlock);
     231    if (TemplateObjectMap* map = thisObject->m_templateObjectMap.get()) {
     232        auto locker = holdLock(thisObject->cellLock());
     233        for (auto& entry : *map)
     234            visitor.append(entry.value);
     235    }
    226236}
    227237
  • trunk/Source/JavaScriptCore/runtime/ProgramExecutable.h

    r245026 r245040  
    7474    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, EvalContextType::None); }
    7575
     76    TemplateObjectMap& ensureTemplateObjectMap(VM&);
     77
    7678private:
    7779    friend class ExecutableBase;
     
    8486    WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
    8587    WriteBarrier<ExecutableToCodeBlockEdge> m_programCodeBlock;
     88    std::unique_ptr<TemplateObjectMap> m_templateObjectMap;
    8689};
    8790
  • trunk/Source/JavaScriptCore/runtime/ScriptExecutable.cpp

    r245026 r245040  
    3535#include "JIT.h"
    3636#include "JSCInlines.h"
     37#include "JSTemplateObjectDescriptor.h"
    3738#include "LLIntEntrypoint.h"
    3839#include "ModuleProgramCodeBlock.h"
     
    436437}
    437438
     439ScriptExecutable* ScriptExecutable::topLevelExecutable()
     440{
     441    switch (type()) {
     442    case FunctionExecutableType:
     443        return jsCast<FunctionExecutable*>(this)->topLevelExecutable();
     444    default:
     445        return this;
     446    }
     447}
     448
     449JSArray* ScriptExecutable::createTemplateObject(ExecState* exec, JSTemplateObjectDescriptor* descriptor)
     450{
     451    VM& vm = exec->vm();
     452    auto scope = DECLARE_THROW_SCOPE(vm);
     453
     454    TemplateObjectMap& templateObjectMap = ensureTemplateObjectMap(vm);
     455    TemplateObjectMap::AddResult result;
     456    {
     457        auto locker = holdLock(cellLock());
     458        result = templateObjectMap.add(descriptor->endOffset(), WriteBarrier<JSArray>());
     459    }
     460    if (JSArray* array = result.iterator->value.get())
     461        return array;
     462    JSArray* templateObject = descriptor->createTemplateObject(exec);
     463    RETURN_IF_EXCEPTION(scope, nullptr);
     464    result.iterator->value.set(vm, this, templateObject);
     465    return templateObject;
     466}
     467
     468auto ScriptExecutable::ensureTemplateObjectMapImpl(std::unique_ptr<TemplateObjectMap>& dest) -> TemplateObjectMap&
     469{
     470    if (dest)
     471        return *dest;
     472    auto result = std::make_unique<TemplateObjectMap>();
     473    WTF::storeStoreFence();
     474    dest = WTFMove(result);
     475    return *dest;
     476}
     477
     478auto ScriptExecutable::ensureTemplateObjectMap(VM& vm) -> TemplateObjectMap&
     479{
     480    switch (type()) {
     481    case FunctionExecutableType:
     482        return static_cast<FunctionExecutable*>(this)->ensureTemplateObjectMap(vm);
     483    case EvalExecutableType:
     484        return static_cast<EvalExecutable*>(this)->ensureTemplateObjectMap(vm);
     485    case ProgramExecutableType:
     486        return static_cast<ProgramExecutable*>(this)->ensureTemplateObjectMap(vm);
     487    case ModuleProgramExecutableType:
     488    default:
     489        ASSERT(type() == ModuleProgramExecutableType);
     490        return static_cast<ModuleProgramExecutable*>(this)->ensureTemplateObjectMap(vm);
     491    }
     492}
     493
    438494CodeBlockHash ScriptExecutable::hashFor(CodeSpecializationKind kind) const
    439495{
  • trunk/Source/JavaScriptCore/runtime/ScriptExecutable.h

    r245026 r245040  
    3030namespace JSC {
    3131
     32class JSArray;
     33class JSTemplateObjectDescriptor;
    3234class IsoCellSet;
    3335
     
    3840
    3941    static void destroy(JSCell*);
     42
     43    using TemplateObjectMap = HashMap<uint64_t, WriteBarrier<JSArray>, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
    4044       
    4145    CodeBlockHash hashFor(CodeSpecializationKind) const;
     
    113117    Exception* prepareForExecution(VM&, JSFunction*, JSScope*, CodeSpecializationKind, CodeBlock*& resultCodeBlock);
    114118
     119    ScriptExecutable* topLevelExecutable();
     120    JSArray* createTemplateObject(ExecState*, JSTemplateObjectDescriptor*);
     121
    115122private:
    116123    friend class ExecutableBase;
     
    118125
    119126    bool hasClearableCode(VM&) const;
     127
     128    TemplateObjectMap& ensureTemplateObjectMap(VM&);
    120129
    121130protected:
     
    138147    }
    139148
     149    static TemplateObjectMap& ensureTemplateObjectMapImpl(std::unique_ptr<TemplateObjectMap>& dest);
     150
    140151    SourceCode m_source;
    141152    Intrinsic m_intrinsic { NoIntrinsic };
  • trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp

    r245026 r245040  
    18471847
    18481848    const SourceCode& source = makeSource(functionText, { });
    1849     JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, source), exec->lexicalGlobalObject());
     1849    JSFunction* func = JSFunction::create(vm, createBuiltinExecutable(vm, source, Identifier::fromString(&vm, "foo"), ConstructorKind::None, ConstructAbility::CannotConstruct)->link(vm, nullptr, source), exec->lexicalGlobalObject());
    18501850
    18511851    return JSValue::encode(func);
     
    20862086{
    20872087    return changeDebuggerModeWhenIdle(exec, { });
     2088}
     2089
     2090static EncodedJSValue JSC_HOST_CALL functionDeleteAllCodeWhenIdle(ExecState* exec)
     2091{
     2092    VM* vm = &exec->vm();
     2093    vm->whenIdle([=] () {
     2094        vm->deleteAllCode(PreventCollectionAndDeleteAllCode);
     2095    });
     2096    return JSValue::encode(jsUndefined());
    20882097}
    20892098
     
    22772286    addFunction(vm, "disableDebuggerModeWhenIdle", functionDisableDebuggerModeWhenIdle, 0);
    22782287
     2288    addFunction(vm, "deleteAllCodeWhenIdle", functionDeleteAllCodeWhenIdle, 0);
     2289
    22792290    addFunction(vm, "globalObjectCount", functionGlobalObjectCount, 0);
    22802291    addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
Note: See TracChangeset for help on using the changeset viewer.