Title: [223125] trunk
Revision
223125
Author
sbar...@apple.com
Date
2017-10-10 00:58:27 -0700 (Tue, 10 Oct 2017)

Log 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/_javascript_Core:

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.

* _javascript_Core.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/_javascript_Core/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/_javascript_Core/runtime/PrototypeMap.h.
(JSC::StructureCache::StructureCache):
(JSC::PrototypeMap::PrototypeMap): Deleted.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/JSTests/ChangeLog (223124 => 223125)


--- trunk/JSTests/ChangeLog	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/JSTests/ChangeLog	2017-10-10 07:58:27 UTC (rev 223125)
@@ -1,3 +1,20 @@
+2017-10-10  Saam Barati  <sbar...@apple.com>
+
+        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.
+
+        * microbenchmarks/dont-confuse-structures-from-different-executable-as-poly-proto.js: Added.
+        (assert):
+        (foo.C):
+        (foo):
+        (bar.C):
+        (bar):
+        (access):
+        (makeLongChain):
+        (accessY):
+
 2017-10-09  Yusuke Suzuki  <utatane....@gmail.com>
 
         `async` should be able to be used as an imported binding name

Added: trunk/JSTests/microbenchmarks/dont-confuse-structures-from-different-executable-as-poly-proto.js (0 => 223125)


--- trunk/JSTests/microbenchmarks/dont-confuse-structures-from-different-executable-as-poly-proto.js	                        (rev 0)
+++ trunk/JSTests/microbenchmarks/dont-confuse-structures-from-different-executable-as-poly-proto.js	2017-10-10 07:58:27 UTC (rev 223125)
@@ -0,0 +1,64 @@
+"use strict";
+
+function assert(b, m) {
+    if (!b)
+        throw new Error("Bad:" + m);
+}
+noInline(assert);
+
+function foo(p) {
+    function C() {
+        this.y = 42;
+    }
+    C.prototype = p;
+    let result = new C;
+    return result;
+}
+
+function bar(p) {
+    function C() {
+        this.y = 42;
+    }
+    C.prototype = p;
+    let result = new C;
+    return result;
+}
+
+function access(item) {
+    return item.x;
+}
+
+function makeLongChain(x) {
+    let item = {x:42};
+    for (let i = 0; i < x; ++i) {
+        item = {__proto__:item}
+    }
+    return item;
+}
+
+
+let p1 = makeLongChain(10);
+let a = foo(p1);
+let b = bar(p1);
+b.__proto__ = makeLongChain(10);
+function accessY(x) { return x.y; }
+accessY(a);
+accessY(b);
+accessY(a);
+accessY(b);
+
+let start = Date.now();
+for (let i = 0; i < 10000; ++i) {
+    let a = foo(p1);
+    for (let i = 0; i < 1000; ++i) {
+        assert(a.x === 42);
+    }
+    let proto = {x:42};
+    let b = bar(proto);
+    for (let i = 0; i < 100; ++i) {
+        assert(b.x === 42);
+    }
+}
+
+if (false)
+    print(Date.now() - start);

Modified: trunk/Source/_javascript_Core/ChangeLog (223124 => 223125)


--- trunk/Source/_javascript_Core/ChangeLog	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-10-10 07:58:27 UTC (rev 223125)
@@ -1,3 +1,69 @@
+2017-10-10  Saam Barati  <sbar...@apple.com>
+
+        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.
+
+        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.
+
+        * _javascript_Core.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/_javascript_Core/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/_javascript_Core/runtime/PrototypeMap.h.
+        (JSC::StructureCache::StructureCache):
+        (JSC::PrototypeMap::PrototypeMap): Deleted.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
 2017-10-09  Yusuke Suzuki  <utatane....@gmail.com>
 
         `async` should be able to be used as an imported binding name

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (223124 => 223125)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-10-10 07:58:27 UTC (rev 223125)
@@ -739,7 +739,6 @@
 		147341D41DC02E6D00AA29BA /* ProgramExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 147341D31DC02E6D00AA29BA /* ProgramExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		147341D61DC02EB900AA29BA /* ModuleProgramExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 147341D51DC02EB900AA29BA /* ModuleProgramExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		147341D81DC02F9900AA29BA /* FunctionExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 147341D71DC02F9900AA29BA /* FunctionExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D844A316AA2C7000A65AF0 /* PrototypeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1478297B1379E8A800A7C2A3 /* HandleTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 146FA5A81378F6B0003627A3 /* HandleTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1067,6 +1066,7 @@
 		796FB43A1DFF8C3F0039C95D /* JSWebAssemblyHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 796FB4391DFF8C3F0039C95D /* JSWebAssemblyHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7980C16D1E3A940E00B71615 /* DFGRegisteredStructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7986943A1F8C0AC8009232AE /* StructureCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		798937791DCAB57300F8D4FB /* JSFixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 798937771DCAB57300F8D4FB /* JSFixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		79A090801D768465008B889B /* HashMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A0907E1D768465008B889B /* HashMapImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3040,8 +3040,6 @@
 		14D2F3D8139F4BE200491031 /* MarkedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedSpace.cpp; sourceTree = "<group>"; };
 		14D2F3D9139F4BE200491031 /* MarkedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpace.h; sourceTree = "<group>"; };
 		14D792640DAA03FB001A9F05 /* CLoopStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLoopStack.h; sourceTree = "<group>"; };
-		14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrototypeMap.cpp; sourceTree = "<group>"; };
-		14D844A316AA2C7000A65AF0 /* PrototypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrototypeMap.h; sourceTree = "<group>"; };
 		14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; };
 		14DA818E0D99FD2000B0A4FB /* JSLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSLexicalEnvironment.h; sourceTree = "<group>"; };
 		14DA818F0D99FD2000B0A4FB /* JSLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSLexicalEnvironment.cpp; sourceTree = "<group>"; };
@@ -3515,6 +3513,8 @@
 		797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = "<group>"; };
 		7980C16A1E3A940E00B71615 /* DFGRegisteredStructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGRegisteredStructureSet.cpp; path = dfg/DFGRegisteredStructureSet.cpp; sourceTree = "<group>"; };
 		7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGRegisteredStructureSet.h; path = dfg/DFGRegisteredStructureSet.h; sourceTree = "<group>"; };
+		798694391F8C0AC7009232AE /* StructureCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StructureCache.cpp; sourceTree = "<group>"; };
+		7986943A1F8C0AC8009232AE /* StructureCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StructureCache.h; sourceTree = "<group>"; };
 		798937761DCAB57300F8D4FB /* JSFixedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFixedArray.cpp; sourceTree = "<group>"; };
 		798937771DCAB57300F8D4FB /* JSFixedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFixedArray.h; sourceTree = "<group>"; };
 		799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3PCToOriginMap.h; path = b3/B3PCToOriginMap.h; sourceTree = "<group>"; };
@@ -6605,8 +6605,6 @@
 				AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */,
 				65C02FBB0637462A003E7EE6 /* Protect.h */,
 				0F74B93A1F89614500B935D3 /* PrototypeKey.h */,
-				14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */,
-				14D844A316AA2C7000A65AF0 /* PrototypeMap.h */,
 				79B00CB81C6AB07E0088C65D /* ProxyConstructor.cpp */,
 				79B00CB91C6AB07E0088C65D /* ProxyConstructor.h */,
 				79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */,
@@ -6682,6 +6680,8 @@
 				93345A8812D838C400302BE3 /* StringRecursionChecker.h */,
 				BCDE3AB00E6C82CF001453A7 /* Structure.cpp */,
 				BCDE3AB10E6C82CF001453A7 /* Structure.h */,
+				798694391F8C0AC7009232AE /* StructureCache.cpp */,
+				7986943A1F8C0AC8009232AE /* StructureCache.h */,
 				7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */,
 				7E4EE7080EBB7963005934AA /* StructureChain.h */,
 				2AAAA31018BD49D100394CC8 /* StructureIDBlob.h */,
@@ -8943,7 +8943,6 @@
 				0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */,
 				BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
 				0F74B93B1F89614800B935D3 /* PrototypeKey.h in Headers */,
-				1474C33B16AA2D950062F01D /* PrototypeMap.h in Headers */,
 				534E03561E53BEDE00213F64 /* ProxyableAccessCase.h in Headers */,
 				79B00CBD1C6AB07E0088C65D /* ProxyConstructor.h in Headers */,
 				79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */,
@@ -8956,6 +8955,7 @@
 				0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */,
 				147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
 				0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */,
+				7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */,
 				E33637A61B63220200EE0840 /* ReflectObject.h in Headers */,
 				996B73231BDA08EF00331B84 /* ReflectObject.lut.h in Headers */,
 				0FA7A8EC18B413C80052371D /* Reg.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (223124 => 223125)


--- trunk/Source/_javascript_Core/Sources.txt	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/Sources.txt	2017-10-10 07:58:27 UTC (rev 223125)
@@ -858,7 +858,6 @@
 runtime/PropertyDescriptor.cpp
 runtime/PropertySlot.cpp
 runtime/PropertyTable.cpp
-runtime/PrototypeMap.cpp
 runtime/ProxyConstructor.cpp
 runtime/ProxyObject.cpp
 runtime/ProxyRevoke.cpp
@@ -891,6 +890,7 @@
 runtime/StringPrototype.cpp
 runtime/StringRecursionChecker.cpp
 runtime/Structure.cpp
+runtime/StructureCache.cpp
 runtime/StructureChain.cpp
 runtime/StructureIDTable.cpp
 runtime/StructureRareData.cpp

Modified: trunk/Source/_javascript_Core/bytecode/InternalFunctionAllocationProfile.h (223124 => 223125)


--- trunk/Source/_javascript_Core/bytecode/InternalFunctionAllocationProfile.h	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/bytecode/InternalFunctionAllocationProfile.h	2017-10-10 07:58:27 UTC (rev 223125)
@@ -54,7 +54,7 @@
     if (prototype == baseStructure->storedPrototype())
         structure = baseStructure;
     else
-        structure = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype, baseStructure);
+        structure = vm.structureCache.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype, baseStructure);
 
     // Ensure that if another thread sees the structure, it will see it properly created.
     WTF::storeStoreFence();

Modified: trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -50,21 +50,20 @@
         // https://bugs.webkit.org/show_bug.cgi?id=177792
 
         executable = constructor->jsExecutable();
+
+        if (Structure* structure = executable->cachedPolyProtoStructure()) {
+            RELEASE_ASSERT(structure->typeInfo().type() == FinalObjectType);
+            m_allocator = nullptr;
+            m_structure.set(vm, owner, structure);
+            m_inlineCapacity = structure->inlineCapacity();
+            return;
+        }
+
         isPolyProto = false;
         if (Options::forcePolyProto())
             isPolyProto = true;
         else
             isPolyProto = executable->ensurePolyProtoWatchpoint().hasBeenInvalidated() && executable->singletonFunction()->hasBeenInvalidated();
-
-        if (isPolyProto) {
-            if (Structure* structure = executable->cachedPolyProtoStructure()) {
-                RELEASE_ASSERT(structure->typeInfo().type() == FinalObjectType);
-                m_allocator = nullptr;
-                m_structure.set(vm, owner, structure);
-                m_inlineCapacity = structure->inlineCapacity();
-                return;
-            }
-        }
     }
 
     unsigned inlineCapacity = 0;
@@ -110,7 +109,7 @@
             inlineCapacity = JSFinalObject::maxInlineCapacity();
     }
 
-    Structure* structure = vm.prototypeMap.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity, isPolyProto);
+    Structure* structure = vm.structureCache.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity, isPolyProto, executable);
 
     if (isPolyProto) {
         ASSERT(structure->hasPolyProto());

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -250,6 +250,7 @@
             JSObject* prototype = jsCast<JSFunction*>(constructor)->prototypeForConstruction(vm, exec);
             result->putDirect(vm, structure->polyProtoOffset(), prototype);
             prototype->didBecomePrototype();
+            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");
         }
         return result;
     }

Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -250,6 +250,7 @@
             JSObject* prototype = constructor->prototypeForConstruction(vm, exec);
             result->putDirect(vm, structure->polyProtoOffset(), prototype);
             prototype->didBecomePrototype();
+            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");
         }
     } else {
         // http://ecma-international.org/ecma-262/6.0/#sec-ordinarycreatefromconstructor

Modified: trunk/Source/_javascript_Core/runtime/InternalFunction.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/InternalFunction.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/InternalFunction.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -123,7 +123,7 @@
         if (JSObject* prototype = jsDynamicCast<JSObject*>(vm, prototypeValue)) {
             // This only happens if someone Reflect.constructs our builtin constructor with another builtin constructor as the new.target.
             // Thus, we don't care about the cost of looking up the structure from our hash table every time.
-            return vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(lexicalGlobalObject, prototype, baseClass);
+            return vm.structureCache.emptyStructureForPrototypeFromBaseStructure(lexicalGlobalObject, prototype, baseClass);
         }
     }
     

Modified: trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -137,7 +137,7 @@
 
 Structure* createIteratorResultObjectStructure(VM& vm, JSGlobalObject& globalObject)
 {
-    Structure* iteratorResultStructure = vm.prototypeMap.emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), JSFinalObject::defaultInlineCapacity());
+    Structure* iteratorResultStructure = vm.structureCache.emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), JSFinalObject::defaultInlineCapacity());
     PropertyOffset offset;
     iteratorResultStructure = Structure::addPropertyTransition(vm, iteratorResultStructure, vm.propertyNames->done, 0, offset);
     RELEASE_ASSERT(offset == donePropertyOffset);

Modified: trunk/Source/_javascript_Core/runtime/JSBoundFunction.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/JSBoundFunction.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/JSBoundFunction.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -145,7 +145,7 @@
     // currently. Whoever works on caching structure changes for prototype transistions should consider this problem as well.
     // See: https://bugs.webkit.org/show_bug.cgi?id=152738
     if (prototype.isObject() && prototype.getObject()->globalObject() == globalObject) {
-        result = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype.getObject(), result);
+        result = vm.structureCache.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype.getObject(), result);
         ASSERT_WITH_SECURITY_IMPLICATION(result->globalObject() == globalObject);
     } else
         result = Structure::create(vm, globalObject, prototype, result->typeInfo(), result->classInfo());

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -454,7 +454,7 @@
     protoAccessor->setSetter(vm, this, JSFunction::create(vm, this, 0, makeString("set ", vm.propertyNames->underscoreProto.string()), globalFuncProtoSetter));
     m_objectPrototype->putDirectNonIndexAccessor(vm, vm.propertyNames->underscoreProto, protoAccessor, PropertyAttribute::Accessor | PropertyAttribute::DontEnum);
     m_functionPrototype->structure()->setPrototypeWithoutTransition(vm, m_objectPrototype.get());
-    m_objectStructureForObjectConstructor.set(vm, this, vm.prototypeMap.emptyObjectStructureForPrototype(this, m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity()));
+    m_objectStructureForObjectConstructor.set(vm, this, vm.structureCache.emptyObjectStructureForPrototype(this, m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity()));
     m_objectProtoValueOfFunction.set(vm, this, jsCast<JSFunction*>(objectPrototype()->getDirect(vm, vm.propertyNames->valueOf)));
     
     JSFunction* thrower = JSFunction::create(vm, this, 0, String(), globalFuncThrowTypeErrorArgumentsCalleeAndCaller);

Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.h (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.h	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.h	2017-10-10 07:58:27 UTC (rev 223125)
@@ -70,8 +70,8 @@
 inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype, unsigned inlineCapacity)
 {
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-    PrototypeMap& prototypeMap = globalObject->vm().prototypeMap;
-    Structure* structure = prototypeMap.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity);
+    StructureCache& structureCache = globalObject->vm().structureCache;
+    Structure* structure = structureCache.emptyObjectStructureForPrototype(globalObject, prototype, inlineCapacity);
     return constructEmptyObject(exec, structure);
 }
 

Modified: trunk/Source/_javascript_Core/runtime/PrototypeKey.h (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/PrototypeKey.h	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/PrototypeKey.h	2017-10-10 07:58:27 UTC (rev 223125)
@@ -33,8 +33,9 @@
 public:
     PrototypeKey() { }
     
-    PrototypeKey(JSObject* prototype, unsigned inlineCapacity, const ClassInfo* classInfo, JSGlobalObject* globalObject)
+    PrototypeKey(JSObject* prototype, FunctionExecutable* executable, unsigned inlineCapacity, const ClassInfo* classInfo, JSGlobalObject* globalObject)
         : m_prototype(prototype)
+        , m_executable(executable)
         , m_inlineCapacity(inlineCapacity)
         , m_classInfo(classInfo)
         , m_globalObject(globalObject)
@@ -47,6 +48,7 @@
     }
     
     JSObject* prototype() const { return m_prototype; }
+    FunctionExecutable* executable() const { return m_executable; }
     unsigned inlineCapacity() const { return m_inlineCapacity; }
     const ClassInfo* classInfo() const { return m_classInfo; }
     JSGlobalObject* globalObject() const { return m_globalObject; }
@@ -54,6 +56,7 @@
     bool operator==(const PrototypeKey& other) const
     {
         return m_prototype == other.m_prototype
+            && m_executable == other.m_executable
             && m_inlineCapacity == other.m_inlineCapacity
             && m_classInfo == other.m_classInfo
             && m_globalObject == other.m_globalObject;
@@ -65,13 +68,14 @@
     
     unsigned hash() const
     {
-        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;
+        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;
     }
     
 private:
     // WARNING: We require all of these default values to be zero. Otherwise, you'll need to add
     // "static const bool emptyValueIsZero = false;" to the HashTraits at the bottom of this file.
-    JSObject* m_prototype { nullptr };
+    JSObject* m_prototype { nullptr }; 
+    FunctionExecutable* m_executable { nullptr }; 
     unsigned m_inlineCapacity { 0 };
     const ClassInfo* m_classInfo { nullptr };
     JSGlobalObject* m_globalObject { nullptr };

Deleted: trunk/Source/_javascript_Core/runtime/PrototypeMap.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/PrototypeMap.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/PrototypeMap.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#include "config.h"
-#include "PrototypeMap.h"
-
-#include "IndexingType.h"
-#include "JSGlobalObject.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-inline Structure* PrototypeMap::createEmptyStructure(JSGlobalObject* globalObject, JSObject* prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity, bool makePolyProtoStructure)
-{
-    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.
-
-    auto key = PrototypeKey(makePolyProtoStructure ? nullptr : prototype, inlineCapacity, classInfo, globalObject);
-    if (Structure* structure = m_structures.get(key)) {
-        if (makePolyProtoStructure) {
-            prototype->didBecomePrototype();
-            RELEASE_ASSERT(structure->hasPolyProto());
-        } else
-            RELEASE_ASSERT(structure->hasMonoProto());
-        ASSERT(prototype->mayBePrototype());
-        return structure;
-    }
-
-    prototype->didBecomePrototype();
-
-    VM& vm = globalObject->vm();
-    Structure* structure;
-    if (makePolyProtoStructure) {
-        structure = Structure::create(
-            Structure::PolyProto, vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
-    } else {
-        structure = Structure::create(
-            vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
-    }
-    m_structures.set(key, Weak<Structure>(structure));
-
-    return structure;
-}
-
-Structure* PrototypeMap::emptyStructureForPrototypeFromBaseStructure(JSGlobalObject* globalObject, JSObject* prototype, Structure* baseStructure)
-{
-    // We currently do not have inline capacity static analysis for subclasses and all internal function constructors have a default inline capacity of 0.
-    IndexingType indexingType = baseStructure->indexingType();
-    if (prototype->anyObjectInChainMayInterceptIndexedAccesses() && hasIndexedProperties(indexingType))
-        indexingType = (indexingType & ~IndexingShapeMask) | SlowPutArrayStorageShape;
-
-    return createEmptyStructure(globalObject, prototype, baseStructure->typeInfo(), baseStructure->classInfo(), indexingType, 0, false);
-}
-
-Structure* PrototypeMap::emptyObjectStructureForPrototype(JSGlobalObject* globalObject, JSObject* prototype, unsigned inlineCapacity, bool makePolyProtoStructure)
-{
-    return createEmptyStructure(globalObject, prototype, JSFinalObject::typeInfo(), JSFinalObject::info(), JSFinalObject::defaultIndexingType, inlineCapacity, makePolyProtoStructure);
-}
-
-} // namespace JSC

Deleted: trunk/Source/_javascript_Core/runtime/PrototypeMap.h (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/PrototypeMap.h	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/PrototypeMap.h	2017-10-10 07:58:27 UTC (rev 223125)
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-#pragma once
-
-#include "IndexingType.h"
-#include "JSTypeInfo.h"
-#include "PrototypeKey.h"
-#include "WeakGCMap.h"
-#include <wtf/TriState.h>
-
-namespace JSC {
-
-class JSGlobalObject;
-class JSObject;
-class Structure;
-class VM;
-
-// Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
-class PrototypeMap {
-public:
-    explicit PrototypeMap(VM& vm)
-        : m_structures(vm)
-    {
-    }
-
-    JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSGlobalObject*, JSObject*, unsigned inlineCapacity, bool makePolyProtoStructure = false);
-    JS_EXPORT_PRIVATE Structure* emptyStructureForPrototypeFromBaseStructure(JSGlobalObject*, JSObject*, Structure*);
-
-private:
-    Structure* createEmptyStructure(JSGlobalObject*, JSObject* prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity, bool makePolyProtoStructure);
-
-    using StructureMap = WeakGCMap<PrototypeKey, Structure>;
-    StructureMap m_structures;
-};
-
-} // namespace JSC

Copied: trunk/Source/_javascript_Core/runtime/StructureCache.cpp (from rev 223124, trunk/Source/_javascript_Core/runtime/PrototypeMap.cpp) (0 => 223125)


--- trunk/Source/_javascript_Core/runtime/StructureCache.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/StructureCache.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "StructureCache.h"
+
+#include "IndexingType.h"
+#include "JSGlobalObject.h"
+#include "JSCInlines.h"
+
+namespace JSC {
+
+inline Structure* StructureCache::createEmptyStructure(JSGlobalObject* globalObject, JSObject* prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity, bool makePolyProtoStructure, FunctionExecutable* executable)
+{
+    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.
+
+    PrototypeKey key { makePolyProtoStructure ? nullptr : prototype, executable, inlineCapacity, classInfo, globalObject };
+    if (Structure* structure = m_structures.get(key)) {
+        if (makePolyProtoStructure) {
+            prototype->didBecomePrototype();
+            RELEASE_ASSERT(structure->hasPolyProto());
+        } else
+            RELEASE_ASSERT(structure->hasMonoProto());
+        ASSERT(prototype->mayBePrototype());
+        return structure;
+    }
+
+    prototype->didBecomePrototype();
+
+    VM& vm = globalObject->vm();
+    Structure* structure;
+    if (makePolyProtoStructure) {
+        structure = Structure::create(
+            Structure::PolyProto, vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
+    } else {
+        structure = Structure::create(
+            vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
+    }
+    m_structures.set(key, structure);
+
+    return structure;
+}
+
+Structure* StructureCache::emptyStructureForPrototypeFromBaseStructure(JSGlobalObject* globalObject, JSObject* prototype, Structure* baseStructure)
+{
+    // We currently do not have inline capacity static analysis for subclasses and all internal function constructors have a default inline capacity of 0.
+    IndexingType indexingType = baseStructure->indexingType();
+    if (prototype->anyObjectInChainMayInterceptIndexedAccesses() && hasIndexedProperties(indexingType))
+        indexingType = (indexingType & ~IndexingShapeMask) | SlowPutArrayStorageShape;
+
+    return createEmptyStructure(globalObject, prototype, baseStructure->typeInfo(), baseStructure->classInfo(), indexingType, 0, false, nullptr);
+}
+
+Structure* StructureCache::emptyObjectStructureForPrototype(JSGlobalObject* globalObject, JSObject* prototype, unsigned inlineCapacity, bool makePolyProtoStructure, FunctionExecutable* executable)
+{
+    return createEmptyStructure(globalObject, prototype, JSFinalObject::typeInfo(), JSFinalObject::info(), JSFinalObject::defaultIndexingType, inlineCapacity, makePolyProtoStructure, executable);
+}
+
+} // namespace JSC

Copied: trunk/Source/_javascript_Core/runtime/StructureCache.h (from rev 223124, trunk/Source/_javascript_Core/runtime/PrototypeMap.h) (0 => 223125)


--- trunk/Source/_javascript_Core/runtime/StructureCache.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/StructureCache.h	2017-10-10 07:58:27 UTC (rev 223125)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#pragma once
+
+#include "IndexingType.h"
+#include "JSTypeInfo.h"
+#include "PrototypeKey.h"
+#include "WeakGCMap.h"
+#include <wtf/TriState.h>
+
+namespace JSC {
+
+class JSGlobalObject;
+class JSObject;
+class Structure;
+class VM;
+
+// Tracks the canonical structure an object should be allocated with when inheriting from a given prototype.
+class StructureCache {
+public:
+    explicit StructureCache(VM& vm)
+        : m_structures(vm)
+    {
+    }
+
+    JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSGlobalObject*, JSObject*, unsigned inlineCapacity, bool makePolyProtoStructure = false, FunctionExecutable* = nullptr);
+    JS_EXPORT_PRIVATE Structure* emptyStructureForPrototypeFromBaseStructure(JSGlobalObject*, JSObject*, Structure*);
+
+private:
+    Structure* createEmptyStructure(JSGlobalObject*, JSObject* prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity, bool makePolyProtoStructure, FunctionExecutable*);
+
+    using StructureMap = WeakGCMap<PrototypeKey, Structure>;
+    StructureMap m_structures;
+};
+
+} // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2017-10-10 07:58:27 UTC (rev 223125)
@@ -194,7 +194,7 @@
     , customGetterSetterFunctionMap(*this)
     , stringCache(*this)
     , symbolImplToSymbolMap(*this)
-    , prototypeMap(*this)
+    , structureCache(*this)
     , interpreter(0)
     , entryScope(0)
     , m_regExpCache(new RegExpCache(this))

Modified: trunk/Source/_javascript_Core/runtime/VM.h (223124 => 223125)


--- trunk/Source/_javascript_Core/runtime/VM.h	2017-10-10 05:53:12 UTC (rev 223124)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2017-10-10 07:58:27 UTC (rev 223125)
@@ -48,9 +48,9 @@
 #include "MacroAssemblerCodeRef.h"
 #include "Microtask.h"
 #include "NumericStrings.h"
-#include "PrototypeMap.h"
 #include "SmallStrings.h"
 #include "Strong.h"
+#include "StructureCache.h"
 #include "Subspace.h"
 #include "TemplateRegistryKeyTable.h"
 #include "VMEntryRecord.h"
@@ -464,7 +464,7 @@
     SourceProviderCache* addSourceProviderCache(SourceProvider*);
     void clearSourceProviderCaches();
 
-    PrototypeMap prototypeMap;
+    StructureCache structureCache;
 
     typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache>> SourceProviderCacheMap;
     SourceProviderCacheMap sourceProviderCacheMap;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to