Changeset 223125 in webkit


Ignore:
Timestamp:
Oct 10, 2017 12:58:27 AM (7 years ago)
Author:
sbarati@apple.com
Message:

The prototype cache should be aware of the Executable it generates a Structure for
https://bugs.webkit.org/show_bug.cgi?id=177907

Reviewed by Filip Pizlo.

JSTests:

  • microbenchmarks/dont-confuse-structures-from-different-executable-as-poly-proto.js: Added.

(assert):
(foo.C):
(foo):
(bar.C):
(bar):
(access):
(makeLongChain):
(accessY):

Source/JavaScriptCore:

This patch renames PrototypeMap to StructureCache because
it is no longer a map of the prototypes in the VM. It's
only used to cache Structures during object construction.

The main change of this patch is to guarantee that Structures generated
by the create_this originating from different two different Executables'
bytecode won't hash-cons to the same thing. Previously, we could hash-cons
them depending on the JSObject* prototype pointer. This would cause the last
thing that hash-consed to overwrite the Structure's poly proto watchpoint. This
happened because when we initialize a JSFunction's ObjectAllocationProfile,
we set the resulting Structure's poly proto watchpoint. This could cause a Structure
generating from some Executable e1 to end up with the poly proto watchpoint
for another Executable e2 simply because JSFunctions backed by e1 and e2
shared the same prototype. Then, based on profiling information, we may fire the
wrong Executable's poly proto watchpoint. This patch fixes this bug by
guaranteeing that Structures generating from create_this for different
Executables are unique even if they share the same prototype by adding
the FunctionExecutable* as another field in PrototypeKey.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • bytecode/InternalFunctionAllocationProfile.h:

(JSC::InternalFunctionAllocationProfile::createAllocationStructureFromBase):

  • bytecode/ObjectAllocationProfile.cpp:

(JSC::ObjectAllocationProfile::initializeProfile):

  • dfg/DFGOperations.cpp:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/InternalFunction.cpp:

(JSC::InternalFunction::createSubclassStructureSlow):

  • runtime/IteratorOperations.cpp:

(JSC::createIteratorResultObjectStructure):

  • runtime/JSBoundFunction.cpp:

(JSC::getBoundFunctionStructure):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/ObjectConstructor.h:

(JSC::constructEmptyObject):

  • runtime/PrototypeKey.h:

(JSC::PrototypeKey::PrototypeKey):
(JSC::PrototypeKey::executable const):
(JSC::PrototypeKey::operator== const):
(JSC::PrototypeKey::hash const):

  • runtime/PrototypeMap.cpp: Removed.
  • runtime/PrototypeMap.h: Removed.
  • runtime/StructureCache.cpp: Copied from Source/JavaScriptCore/runtime/PrototypeMap.cpp.

(JSC::StructureCache::createEmptyStructure):
(JSC::StructureCache::emptyStructureForPrototypeFromBaseStructure):
(JSC::StructureCache::emptyObjectStructureForPrototype):
(JSC::PrototypeMap::createEmptyStructure): Deleted.
(JSC::PrototypeMap::emptyStructureForPrototypeFromBaseStructure): Deleted.
(JSC::PrototypeMap::emptyObjectStructureForPrototype): Deleted.

  • runtime/StructureCache.h: Copied from Source/JavaScriptCore/runtime/PrototypeMap.h.

(JSC::StructureCache::StructureCache):
(JSC::PrototypeMap::PrototypeMap): Deleted.

  • runtime/VM.cpp:

(JSC::VM::VM):

  • runtime/VM.h:
Location:
trunk
Files:
1 added
16 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r223124 r223125  
     12017-10-10  Saam Barati  <sbarati@apple.com>
     2
     3        The prototype cache should be aware of the Executable it generates a Structure for
     4        https://bugs.webkit.org/show_bug.cgi?id=177907
     5
     6        Reviewed by Filip Pizlo.
     7
     8        * microbenchmarks/dont-confuse-structures-from-different-executable-as-poly-proto.js: Added.
     9        (assert):
     10        (foo.C):
     11        (foo):
     12        (bar.C):
     13        (bar):
     14        (access):
     15        (makeLongChain):
     16        (accessY):
     17
    1182017-10-09  Yusuke Suzuki  <utatane.tea@gmail.com>
    219
  • trunk/Source/JavaScriptCore/ChangeLog

    r223124 r223125  
     12017-10-10  Saam Barati  <sbarati@apple.com>
     2
     3        The prototype cache should be aware of the Executable it generates a Structure for
     4        https://bugs.webkit.org/show_bug.cgi?id=177907
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch renames PrototypeMap to StructureCache because
     9        it is no longer a map of the prototypes in the VM. It's
     10        only used to cache Structures during object construction.
     11       
     12        The main change of this patch is to guarantee that Structures generated
     13        by the create_this originating from different two different Executables'
     14        bytecode won't hash-cons to the same thing. Previously, we could hash-cons
     15        them depending on the JSObject* prototype pointer. This would cause the last
     16        thing that hash-consed to overwrite the Structure's poly proto watchpoint. This
     17        happened because when we initialize a JSFunction's ObjectAllocationProfile,
     18        we set the resulting Structure's poly proto watchpoint. This could cause a Structure
     19        generating from some Executable e1 to end up with the poly proto watchpoint
     20        for another Executable e2 simply because JSFunctions backed by e1 and e2
     21        shared the same prototype. Then, based on profiling information, we may fire the
     22        wrong Executable's poly proto watchpoint. This patch fixes this bug by
     23        guaranteeing that Structures generating from create_this for different
     24        Executables are unique even if they share the same prototype by adding
     25        the FunctionExecutable* as another field in PrototypeKey.
     26
     27        * JavaScriptCore.xcodeproj/project.pbxproj:
     28        * Sources.txt:
     29        * bytecode/InternalFunctionAllocationProfile.h:
     30        (JSC::InternalFunctionAllocationProfile::createAllocationStructureFromBase):
     31        * bytecode/ObjectAllocationProfile.cpp:
     32        (JSC::ObjectAllocationProfile::initializeProfile):
     33        * dfg/DFGOperations.cpp:
     34        * runtime/CommonSlowPaths.cpp:
     35        (JSC::SLOW_PATH_DECL):
     36        * runtime/InternalFunction.cpp:
     37        (JSC::InternalFunction::createSubclassStructureSlow):
     38        * runtime/IteratorOperations.cpp:
     39        (JSC::createIteratorResultObjectStructure):
     40        * runtime/JSBoundFunction.cpp:
     41        (JSC::getBoundFunctionStructure):
     42        * runtime/JSGlobalObject.cpp:
     43        (JSC::JSGlobalObject::init):
     44        * runtime/ObjectConstructor.h:
     45        (JSC::constructEmptyObject):
     46        * runtime/PrototypeKey.h:
     47        (JSC::PrototypeKey::PrototypeKey):
     48        (JSC::PrototypeKey::executable const):
     49        (JSC::PrototypeKey::operator== const):
     50        (JSC::PrototypeKey::hash const):
     51        * runtime/PrototypeMap.cpp: Removed.
     52        * runtime/PrototypeMap.h: Removed.
     53        * runtime/StructureCache.cpp: Copied from Source/JavaScriptCore/runtime/PrototypeMap.cpp.
     54        (JSC::StructureCache::createEmptyStructure):
     55        (JSC::StructureCache::emptyStructureForPrototypeFromBaseStructure):
     56        (JSC::StructureCache::emptyObjectStructureForPrototype):
     57        (JSC::PrototypeMap::createEmptyStructure): Deleted.
     58        (JSC::PrototypeMap::emptyStructureForPrototypeFromBaseStructure): Deleted.
     59        (JSC::PrototypeMap::emptyObjectStructureForPrototype): Deleted.
     60        * runtime/StructureCache.h: Copied from Source/JavaScriptCore/runtime/PrototypeMap.h.
     61        (JSC::StructureCache::StructureCache):
     62        (JSC::PrototypeMap::PrototypeMap): Deleted.
     63        * runtime/VM.cpp:
     64        (JSC::VM::VM):
     65        * runtime/VM.h:
     66
    1672017-10-09  Yusuke Suzuki  <utatane.tea@gmail.com>
    268
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r223081 r223125  
    740740                147341D61DC02EB900AA29BA /* ModuleProgramExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 147341D51DC02EB900AA29BA /* ModuleProgramExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; };
    741741                147341D81DC02F9900AA29BA /* FunctionExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 147341D71DC02F9900AA29BA /* FunctionExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; };
    742                 1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
    743742                1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 146FA5A81378F6B0003627A3 /* HandleTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
    744743                147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    10681067                797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10691068                7980C16D1E3A940E00B71615 /* DFGRegisteredStructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1069                7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7986943A1F8C0AC8009232AE /* StructureCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10701070                798937791DCAB57300F8D4FB /* JSFixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 798937771DCAB57300F8D4FB /* JSFixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10711071                799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    30413041                14D2F3D9139F4BE200491031 /* MarkedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpace.h; sourceTree = "<group>"; };
    30423042                14D792640DAA03FB001A9F05 /* CLoopStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLoopStack.h; sourceTree = "<group>"; };
    3043                 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrototypeMap.cpp; sourceTree = "<group>"; };
    3044                 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrototypeMap.h; sourceTree = "<group>"; };
    30453043                14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; };
    30463044                14DA818E0D99FD2000B0A4FB /* JSLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSLexicalEnvironment.h; sourceTree = "<group>"; };
     
    35163514                7980C16A1E3A940E00B71615 /* DFGRegisteredStructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGRegisteredStructureSet.cpp; path = dfg/DFGRegisteredStructureSet.cpp; sourceTree = "<group>"; };
    35173515                7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRegisteredStructureSet.h; path = dfg/DFGRegisteredStructureSet.h; sourceTree = "<group>"; };
     3516                798694391F8C0AC7009232AE /* StructureCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StructureCache.cpp; sourceTree = "<group>"; };
     3517                7986943A1F8C0AC8009232AE /* StructureCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StructureCache.h; sourceTree = "<group>"; };
    35183518                798937761DCAB57300F8D4FB /* JSFixedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFixedArray.cpp; sourceTree = "<group>"; };
    35193519                798937771DCAB57300F8D4FB /* JSFixedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFixedArray.h; sourceTree = "<group>"; };
     
    66066606                                65C02FBB0637462A003E7EE6 /* Protect.h */,
    66076607                                0F74B93A1F89614500B935D3 /* PrototypeKey.h */,
    6608                                 14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */,
    6609                                 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */,
    66106608                                79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */,
    66116609                                79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */,
     
    66836681                                BCDE3AB00E6C82CF001453A7 /* Structure.cpp */,
    66846682                                BCDE3AB10E6C82CF001453A7 /* Structure.h */,
     6683                                798694391F8C0AC7009232AE /* StructureCache.cpp */,
     6684                                7986943A1F8C0AC8009232AE /* StructureCache.h */,
    66856685                                7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */,
    66866686                                7E4EE7080EBB7963005934AA /* StructureChain.h */,
     
    89448944                                BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
    89458945                                0F74B93B1F89614800B935D3 /* PrototypeKey.h in Headers */,
    8946                                 1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
    89478946                                534E03561E53BEDE00213F64 /* ProxyableAccessCase.h in Headers */,
    89488947                                79B00CBD1C6AB07E0088C65D /* ProxyConstructor.h in Headers */,
     
    89578956                                147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
    89588957                                0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */,
     8958                                7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */,
    89598959                                E33637A61B63220200EE0840 /* ReflectObject.h in Headers */,
    89608960                                996B73231BDA08EF00331B84 /* ReflectObject.lut.h in Headers */,
  • trunk/Source/JavaScriptCore/Sources.txt

    r223081 r223125  
    859859runtime/PropertySlot.cpp
    860860runtime/PropertyTable.cpp
    861 runtime/PrototypeMap.cpp
    862861runtime/ProxyConstructor.cpp
    863862runtime/ProxyObject.cpp
     
    892891runtime/StringRecursionChecker.cpp
    893892runtime/Structure.cpp
     893runtime/StructureCache.cpp
    894894runtime/StructureChain.cpp
    895895runtime/StructureIDTable.cpp
  • trunk/Source/JavaScriptCore/bytecode/InternalFunctionAllocationProfile.h

    r222827 r223125  
    5555        structure = baseStructure;
    5656    else
    57         structure = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype, baseStructure);
     57        structure = vm.structureCache.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype, baseStructure);
    5858
    5959    // Ensure that if another thread sees the structure, it will see it properly created.
  • trunk/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.cpp

    r222827 r223125  
    5151
    5252        executable = constructor->jsExecutable();
     53
     54        if (Structure* structure = executable->cachedPolyProtoStructure()) {
     55            RELEASE_ASSERT(structure->typeInfo().type() == FinalObjectType);
     56            m_allocator = nullptr;
     57            m_structure.set(vm, owner, structure);
     58            m_inlineCapacity = structure->inlineCapacity();
     59            return;
     60        }
     61
    5362        isPolyProto = false;
    5463        if (Options::forcePolyProto())
     
    5665        else
    5766            isPolyProto = executable->ensurePolyProtoWatchpoint().hasBeenInvalidated() && executable->singletonFunction()->hasBeenInvalidated();
    58 
    59         if (isPolyProto) {
    60             if (Structure* structure = executable->cachedPolyProtoStructure()) {
    61                 RELEASE_ASSERT(structure->typeInfo().type() == FinalObjectType);
    62                 m_allocator = nullptr;
    63                 m_structure.set(vm, owner, structure);
    64                 m_inlineCapacity = structure->inlineCapacity();
    65                 return;
    66             }
    67         }
    6867    }
    6968
     
    111110    }
    112111
    113     Structure* structure = vm.prototypeMap.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity, isPolyProto);
     112    Structure* structure = vm.structureCache.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity, isPolyProto, executable);
    114113
    115114    if (isPolyProto) {
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r223027 r223125  
    251251            result->putDirect(vm, structure->polyProtoOffset(), prototype);
    252252            prototype->didBecomePrototype();
     253            ASSERT_WITH_MESSAGE(!hasIndexedProperties(result->indexingType()), "We rely on JSFinalObject not starting out with an indexing type otherwise we would potentially need to convert to slow put storage");
    253254        }
    254255        return result;
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r223027 r223125  
    251251            result->putDirect(vm, structure->polyProtoOffset(), prototype);
    252252            prototype->didBecomePrototype();
     253            ASSERT_WITH_MESSAGE(!hasIndexedProperties(result->indexingType()), "We rely on JSFinalObject not starting out with an indexing type otherwise we would potentially need to convert to slow put storage");
    253254        }
    254255    } else {
  • trunk/Source/JavaScriptCore/runtime/InternalFunction.cpp

    r222827 r223125  
    124124            // This only happens if someone Reflect.constructs our builtin constructor with another builtin constructor as the new.target.
    125125            // Thus, we don't care about the cost of looking up the structure from our hash table every time.
    126             return vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(lexicalGlobalObject, prototype, baseClass);
     126            return vm.structureCache.emptyStructureForPrototypeFromBaseStructure(lexicalGlobalObject, prototype, baseClass);
    127127        }
    128128    }
  • trunk/Source/JavaScriptCore/runtime/IteratorOperations.cpp

    r222421 r223125  
    138138Structure* createIteratorResultObjectStructure(VM& vm, JSGlobalObject& globalObject)
    139139{
    140     Structure* iteratorResultStructure = vm.prototypeMap.emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), JSFinalObject::defaultInlineCapacity());
     140    Structure* iteratorResultStructure = vm.structureCache.emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), JSFinalObject::defaultInlineCapacity());
    141141    PropertyOffset offset;
    142142    iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames->done, 0, offset);
  • trunk/Source/JavaScriptCore/runtime/JSBoundFunction.cpp

    r222473 r223125  
    146146    // See: https://bugs.webkit.org/show_bug.cgi?id=152738
    147147    if (prototype.isObject() && prototype.getObject()->globalObject() == globalObject) {
    148         result = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype.getObject(), result);
     148        result = vm.structureCache.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype.getObject(), result);
    149149        ASSERT_WITH_SECURITY_IMPLICATION(result->globalObject() == globalObject);
    150150    } else
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r222895 r223125  
    455455    m_objectPrototype->putDirectNonIndexAccessor(vm, vm.propertyNames->underscoreProto, protoAccessor, PropertyAttribute::Accessor | PropertyAttribute::DontEnum);
    456456    m_functionPrototype->structure()->setPrototypeWithoutTransition(vm, m_objectPrototype.get());
    457     m_objectStructureForObjectConstructor.set(vm, this, vm.prototypeMap.emptyObjectStructureForPrototype(this, m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity()));
     457    m_objectStructureForObjectConstructor.set(vm, this, vm.structureCache.emptyObjectStructureForPrototype(this, m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity()));
    458458    m_objectProtoValueOfFunction.set(vm, this, jsCast<JSFunction*>(objectPrototype()->getDirect(vm, vm.propertyNames->valueOf)));
    459459   
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h

    r218790 r223125  
    7171{
    7272    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    73     PrototypeMap& prototypeMap = globalObject->vm().prototypeMap;
    74     Structure* structure = prototypeMap.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity);
     73    StructureCache& structureCache = globalObject->vm().structureCache;
     74    Structure* structure = structureCache.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity);
    7575    return constructEmptyObject(exec, structure);
    7676}
  • trunk/Source/JavaScriptCore/runtime/PrototypeKey.h

    r223027 r223125  
    3434    PrototypeKey() { }
    3535   
    36     PrototypeKey(JSObject* prototype, unsigned inlineCapacity, const ClassInfo* classInfo, JSGlobalObject* globalObject)
     36    PrototypeKey(JSObject* prototype, FunctionExecutable* executable, unsigned inlineCapacity, const ClassInfo* classInfo, JSGlobalObject* globalObject)
    3737        : m_prototype(prototype)
     38        , m_executable(executable)
    3839        , m_inlineCapacity(inlineCapacity)
    3940        , m_classInfo(classInfo)
     
    4849   
    4950    JSObject* prototype() const { return m_prototype; }
     51    FunctionExecutable* executable() const { return m_executable; }
    5052    unsigned inlineCapacity() const { return m_inlineCapacity; }
    5153    const ClassInfo* classInfo() const { return m_classInfo; }
     
    5557    {
    5658        return m_prototype == other.m_prototype
     59            && m_executable == other.m_executable
    5760            && m_inlineCapacity == other.m_inlineCapacity
    5861            && m_classInfo == other.m_classInfo
     
    6669    unsigned hash() const
    6770    {
    68         return WTF::IntHash<uintptr_t>::hash(bitwise_cast<uintptr_t>(m_prototype) ^ bitwise_cast<uintptr_t>(m_classInfo) ^ bitwise_cast<uintptr_t>(m_globalObject)) + m_inlineCapacity;
     71        return WTF::IntHash<uintptr_t>::hash(bitwise_cast<uintptr_t>(m_prototype) ^ bitwise_cast<uintptr_t>(m_executable) ^ bitwise_cast<uintptr_t>(m_classInfo) ^ bitwise_cast<uintptr_t>(m_globalObject)) + m_inlineCapacity;
    6972    }
    7073   
     
    7275    // WARNING: We require all of these default values to be zero. Otherwise, you'll need to add
    7376    // "static const bool emptyValueIsZero = false;" to the HashTraits at the bottom of this file.
    74     JSObject* m_prototype { nullptr };
     77    JSObject* m_prototype { nullptr };
     78    FunctionExecutable* m_executable { nullptr };
    7579    unsigned m_inlineCapacity { 0 };
    7680    const ClassInfo* m_classInfo { nullptr };
  • trunk/Source/JavaScriptCore/runtime/StructureCache.cpp

    r223124 r223125  
    2525
    2626#include "config.h"
    27 #include "PrototypeMap.h"
     27#include "StructureCache.h"
    2828
    2929#include "IndexingType.h"
     
    3333namespace JSC {
    3434
    35 inline Structure* PrototypeMap::createEmptyStructure(JSGlobalObject* globalObject, JSObject* prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity, bool makePolyProtoStructure)
     35inline Structure* StructureCache::createEmptyStructure(JSGlobalObject* globalObject, JSObject* prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity, bool makePolyProtoStructure, FunctionExecutable* executable)
    3636{
    3737    RELEASE_ASSERT(!!prototype); // We use nullptr inside the HashMap for prototype to mean poly proto, so user's of this API must provide non-null prototypes.
    3838
    39     auto key = PrototypeKey(makePolyProtoStructure ? nullptr : prototype, inlineCapacity, classInfo, globalObject);
     39    PrototypeKey key { makePolyProtoStructure ? nullptr : prototype, executable, inlineCapacity, classInfo, globalObject };
    4040    if (Structure* structure = m_structures.get(key)) {
    4141        if (makePolyProtoStructure) {
     
    5959            vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
    6060    }
    61     m_structures.set(key, Weak<Structure>(structure));
     61    m_structures.set(key, structure);
    6262
    6363    return structure;
    6464}
    6565
    66 Structure* PrototypeMap::emptyStructureForPrototypeFromBaseStructure(JSGlobalObject* globalObject, JSObject* prototype, Structure* baseStructure)
     66Structure* StructureCache::emptyStructureForPrototypeFromBaseStructure(JSGlobalObject* globalObject, JSObject* prototype, Structure* baseStructure)
    6767{
    6868    // We currently do not have inline capacity static analysis for subclasses and all internal function constructors have a default inline capacity of 0.
     
    7171        indexingType = (indexingType & ~IndexingShapeMask) | SlowPutArrayStorageShape;
    7272
    73     return createEmptyStructure(globalObject, prototype, baseStructure->typeInfo(), baseStructure->classInfo(), indexingType, 0, false);
     73    return createEmptyStructure(globalObject, prototype, baseStructure->typeInfo(), baseStructure->classInfo(), indexingType, 0, false, nullptr);
    7474}
    7575
    76 Structure* PrototypeMap::emptyObjectStructureForPrototype(JSGlobalObject* globalObject, JSObject* prototype, unsigned inlineCapacity, bool makePolyProtoStructure)
     76Structure* StructureCache::emptyObjectStructureForPrototype(JSGlobalObject* globalObject, JSObject* prototype, unsigned inlineCapacity, bool makePolyProtoStructure, FunctionExecutable* executable)
    7777{
    78     return createEmptyStructure(globalObject, prototype, JSFinalObject::typeInfo(), JSFinalObject::info(), JSFinalObject::defaultIndexingType, inlineCapacity, makePolyProtoStructure);
     78    return createEmptyStructure(globalObject, prototype, JSFinalObject::typeInfo(), JSFinalObject::info(), JSFinalObject::defaultIndexingType, inlineCapacity, makePolyProtoStructure, executable);
    7979}
    8080
  • trunk/Source/JavaScriptCore/runtime/StructureCache.h

    r223124 r223125  
    4040
    4141// Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
    42 class PrototypeMap {
     42class StructureCache {
    4343public:
    44     explicit PrototypeMap(VM& vm)
     44    explicit StructureCache(VM& vm)
    4545        : m_structures(vm)
    4646    {
    4747    }
    4848
    49     JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSGlobalObject*, JSObject*, unsigned inlineCapacity, bool makePolyProtoStructure = false);
     49    JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSGlobalObject*, JSObject*, unsigned inlineCapacity, bool makePolyProtoStructure = false, FunctionExecutable* = nullptr);
    5050    JS_EXPORT_PRIVATE Structure* emptyStructureForPrototypeFromBaseStructure(JSGlobalObject*, JSObject*, Structure*);
    5151
    5252private:
    53     Structure* createEmptyStructure(JSGlobalObject*, JSObject* prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity, bool makePolyProtoStructure);
     53    Structure* createEmptyStructure(JSGlobalObject*, JSObject* prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity, bool makePolyProtoStructure, FunctionExecutable*);
    5454
    5555    using StructureMap = WeakGCMap<PrototypeKey, Structure>;
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r223002 r223125  
    195195    , stringCache(*this)
    196196    , symbolImplToSymbolMap(*this)
    197     , prototypeMap(*this)
     197    , structureCache(*this)
    198198    , interpreter(0)
    199199    , entryScope(0)
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r223024 r223125  
    4949#include "Microtask.h"
    5050#include "NumericStrings.h"
    51 #include "PrototypeMap.h"
    5251#include "SmallStrings.h"
    5352#include "Strong.h"
     53#include "StructureCache.h"
    5454#include "Subspace.h"
    5555#include "TemplateRegistryKeyTable.h"
     
    465465    void clearSourceProviderCaches();
    466466
    467     PrototypeMap prototypeMap;
     467    StructureCache structureCache;
    468468
    469469    typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache>> SourceProviderCacheMap;
Note: See TracChangeset for help on using the changeset viewer.