JSSegmentedVariableObject and its subclasses should have a sane destruction story
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2017 05:13:21 +0000 (05:13 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2017 05:13:21 +0000 (05:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=167193

Reviewed by Saam Barati.
Source/JavaScriptCore:

Prior to this change, JSSegmentedVariableObjects' subclasses install finalizers that call
destroy. They did this in random ways, which sometimes resulted in
JSSegmentedVariableObject::~JSSegmentedVariableObject executing more than once (which worked
because of the way that ~SegmentedVector is written). Maybe this works now, but it's a disaster
waiting to happen.

Fortunately we can now just give those things their own Subspace and teach it its own protocol of
destruction. This change introduces JSSegmentedVariableObjectSubspace and stashes a m_classInfo
in JSSegmentedVariableObject. Now, subclasses of JSSegmentedVariableObject are destructible in
much the same way as JSDestructibleObject without having to be subclasses of
JSDestructibleObject.

* API/JSCallbackObject.cpp:
(JSC::JSCallbackObject<JSGlobalObject>::create):
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* jsc.cpp:
(GlobalObject::create):
* runtime/JSGlobalLexicalEnvironment.h:
(JSC::JSGlobalLexicalEnvironment::create):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::create):
(JSC::JSGlobalObject::finishCreation):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::create): Deleted.
(JSC::JSGlobalObject::finishCreation): Deleted.
* runtime/JSSegmentedVariableObject.cpp:
(JSC::JSSegmentedVariableObject::destroy):
(JSC::JSSegmentedVariableObject::JSSegmentedVariableObject):
(JSC::JSSegmentedVariableObject::~JSSegmentedVariableObject):
(JSC::JSSegmentedVariableObject::finishCreation):
* runtime/JSSegmentedVariableObject.h:
(JSC::JSSegmentedVariableObject::subspaceFor):
(JSC::JSSegmentedVariableObject::classInfo):
(JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): Deleted.
(JSC::JSSegmentedVariableObject::finishCreation): Deleted.
* runtime/JSSegmentedVariableObjectSubspace.cpp: Added.
(JSC::JSSegmentedVariableObjectSubspace::JSSegmentedVariableObjectSubspace):
(JSC::JSSegmentedVariableObjectSubspace::~JSSegmentedVariableObjectSubspace):
(JSC::JSSegmentedVariableObjectSubspace::finishSweep):
(JSC::JSSegmentedVariableObjectSubspace::destroy):
* runtime/JSSegmentedVariableObjectSubspace.h: Added.
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* testRegExp.cpp:
(GlobalObject::create):

Source/WebCore:

No new tests because no new behavior.

JSSegmentedVariableObjects now get to have a sane destruction story. This means switching
subspace types for the DOM's global object subspace.

* bindings/js/WebCoreJSClientData.cpp:
(WebCore::JSVMClientData::JSVMClientData):
* bindings/js/WebCoreJSClientData.h:
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210912 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/JavaScriptCore/API/JSCallbackObject.cpp
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/runtime/JSGlobalLexicalEnvironment.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSSegmentedVariableObject.cpp
Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
Source/JavaScriptCore/runtime/JSSegmentedVariableObjectSubspace.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSSegmentedVariableObjectSubspace.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/testRegExp.cpp
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/WebCoreJSClientData.cpp
Source/WebCore/bindings/js/WebCoreJSClientData.h
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

index 02b38fd..dee87db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Inc.  All rights reserved.
+ * Copyright (C) 2006-2017 Apple Inc.  All rights reserved.
  * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@ JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(VM& v
 {
     JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject>>(vm.heap)) JSCallbackObject(vm, classRef, structure);
     callbackObject->finishCreation(vm);
-    vm.heap.addFinalizer(callbackObject, destroy);
     return callbackObject;
 }
 
index 997edc1..8b4162c 100644 (file)
@@ -788,6 +788,7 @@ set(JavaScriptCore_SOURCES
     runtime/JSScope.cpp
     runtime/JSScriptFetcher.cpp
     runtime/JSSegmentedVariableObject.cpp
+    runtime/JSSegmentedVariableObjectSubspace.cpp
     runtime/JSSet.cpp
     runtime/JSSetIterator.cpp
     runtime/JSSourceCode.cpp
index 6584b91..8ce258c 100644 (file)
@@ -1,3 +1,58 @@
+2017-01-18  Filip Pizlo  <fpizlo@apple.com>
+
+        JSSegmentedVariableObject and its subclasses should have a sane destruction story
+        https://bugs.webkit.org/show_bug.cgi?id=167193
+
+        Reviewed by Saam Barati.
+        
+        Prior to this change, JSSegmentedVariableObjects' subclasses install finalizers that call
+        destroy. They did this in random ways, which sometimes resulted in
+        JSSegmentedVariableObject::~JSSegmentedVariableObject executing more than once (which worked
+        because of the way that ~SegmentedVector is written). Maybe this works now, but it's a disaster
+        waiting to happen.
+
+        Fortunately we can now just give those things their own Subspace and teach it its own protocol of
+        destruction. This change introduces JSSegmentedVariableObjectSubspace and stashes a m_classInfo
+        in JSSegmentedVariableObject. Now, subclasses of JSSegmentedVariableObject are destructible in
+        much the same way as JSDestructibleObject without having to be subclasses of
+        JSDestructibleObject.
+
+        * API/JSCallbackObject.cpp:
+        (JSC::JSCallbackObject<JSGlobalObject>::create):
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * jsc.cpp:
+        (GlobalObject::create):
+        * runtime/JSGlobalLexicalEnvironment.h:
+        (JSC::JSGlobalLexicalEnvironment::create):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::create):
+        (JSC::JSGlobalObject::finishCreation):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::create): Deleted.
+        (JSC::JSGlobalObject::finishCreation): Deleted.
+        * runtime/JSSegmentedVariableObject.cpp:
+        (JSC::JSSegmentedVariableObject::destroy):
+        (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject):
+        (JSC::JSSegmentedVariableObject::~JSSegmentedVariableObject):
+        (JSC::JSSegmentedVariableObject::finishCreation):
+        * runtime/JSSegmentedVariableObject.h:
+        (JSC::JSSegmentedVariableObject::subspaceFor):
+        (JSC::JSSegmentedVariableObject::classInfo):
+        (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): Deleted.
+        (JSC::JSSegmentedVariableObject::finishCreation): Deleted.
+        * runtime/JSSegmentedVariableObjectSubspace.cpp: Added.
+        (JSC::JSSegmentedVariableObjectSubspace::JSSegmentedVariableObjectSubspace):
+        (JSC::JSSegmentedVariableObjectSubspace::~JSSegmentedVariableObjectSubspace):
+        (JSC::JSSegmentedVariableObjectSubspace::finishSweep):
+        (JSC::JSSegmentedVariableObjectSubspace::destroy):
+        * runtime/JSSegmentedVariableObjectSubspace.h: Added.
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * testRegExp.cpp:
+        (GlobalObject::create):
+
 2017-01-18  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: console.table only works for the first 5 properties
index 0986b95..65ce168 100644 (file)
                0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */; };
                0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
                0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; };
+               0F4F82871E2FFDDD0075184C /* JSSegmentedVariableObjectSubspace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F82851E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.cpp */; };
+               0F4F82881E2FFDE00075184C /* JSSegmentedVariableObjectSubspace.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F82861E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; };
                0F5513A61D5A682C00C32BD8 /* FreeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5513A51D5A682A00C32BD8 /* FreeList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F5513A81D5A68CD00C32BD8 /* FreeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5513A71D5A68CB00C32BD8 /* FreeList.cpp */; };
                147F39D5107EC37600427A48 /* JSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC02E9B60E1842FA000F9297 /* JSString.cpp */; };
                147F39D6107EC37600427A48 /* JSCJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8870255597D01FF60F7 /* JSCJSValue.cpp */; };
                147F39D7107EC37600427A48 /* JSEnvironmentRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC22A39A0E16E14800AF21C8 /* JSEnvironmentRecord.cpp */; };
+               14815F5F991C46BEB98D0016 /* JSScriptFetcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11C197C2624848EDA84CED7F /* JSScriptFetcher.cpp */; };
                1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B74C0A43032800517CFC /* JSStringRef.cpp */; };
                1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482B7E20A43076000517CFC /* JSObjectRef.cpp */; };
                14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14874AE115EBDE4A002E3587 /* JSScope.cpp */; };
                8B9F6D561D5912FA001C739F /* IterationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B9F6D551D5912FA001C739F /* IterationKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
                90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */; };
                90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 90213E3C123A40C200D422F3 /* MemoryStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               9064337DD4B0402BAF34A592 /* JSScriptFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93052C320FB792190048FDC3 /* ParserArena.cpp */; };
                93052C350FB792190048FDC3 /* ParserArena.h in Headers */ = {isa = PBXBuildFile; fileRef = 93052C330FB792190048FDC3 /* ParserArena.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5BD30822A1C700736975 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
                BCF605140E203EF800B9A64D /* ArgList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF605120E203EF800B9A64D /* ArgList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCFD8C900EEB2EE700283848 /* JumpTable.cpp */; };
                BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               BDFCB2BBE90F41349E1B0BED /* JSSourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3032175DF1AD47D8998B34E1 /* JSSourceCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C20328201981979D0088B499 /* CustomGlobalObjectClassTest.c in Sources */ = {isa = PBXBuildFile; fileRef = C203281E1981979D0088B499 /* CustomGlobalObjectClassTest.c */; };
                C20BA92D16BB1C1500B3AEA2 /* StructureRareDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C20BA92C16BB1C1500B3AEA2 /* StructureRareDataInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCB408515C0A3C30048932B /* SlotVisitorInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D01A05C76F005CAB76 /* cpp_generator.py */; settings = {ATTRIBUTES = (Private, ); }; };
                C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
                C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
+               CEAE7D7B889B477BA93ABA6C /* ScriptFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 8852151A9C3842389B3215B7 /* ScriptFetcher.h */; settings = {ATTRIBUTES = (Private, ); }; };
                D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */; };
                DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; };
                DC0184191D10C1890057B053 /* JITWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0184181D10C1870057B053 /* JITWorklist.h */; };
                E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49DC15512EF277200184A1F /* SourceProviderCache.cpp */; };
                E49DC16C12EF294E00184A1F /* SourceProviderCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC15112EF272200184A1F /* SourceProviderCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FA3AB211C8494524AB390267 /* JSSourceCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F73926918DC64330AFCDF0D7 /* JSSourceCode.cpp */; };
                FE0D4A061AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */; };
                FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */; };
                FE1220271BE7F58C0039E6F2 /* JITAddGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1220261BE7F5640039E6F2 /* JITAddGenerator.h */; };
                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
                FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               FA3AB211C8494524AB390267 /* JSSourceCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F73926918DC64330AFCDF0D7 /* JSSourceCode.cpp */; };
-               BDFCB2BBE90F41349E1B0BED /* JSSourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3032175DF1AD47D8998B34E1 /* JSSourceCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               14815F5F991C46BEB98D0016 /* JSScriptFetcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11C197C2624848EDA84CED7F /* JSScriptFetcher.cpp */; };
-               9064337DD4B0402BAF34A592 /* JSScriptFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               CEAE7D7B889B477BA93ABA6C /* ScriptFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 8852151A9C3842389B3215B7 /* ScriptFetcher.h */; settings = {ATTRIBUTES = (Private, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
                0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3OriginDump.cpp; path = b3/B3OriginDump.cpp; sourceTree = "<group>"; };
                0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
                0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
+               0F4F82851E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSegmentedVariableObjectSubspace.cpp; sourceTree = "<group>"; };
+               0F4F82861E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSegmentedVariableObjectSubspace.h; sourceTree = "<group>"; };
                0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = "<group>"; };
                0F5513A51D5A682A00C32BD8 /* FreeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FreeList.h; sourceTree = "<group>"; };
                0F5513A71D5A68CB00C32BD8 /* FreeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FreeList.cpp; sourceTree = "<group>"; };
                0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPredictionPropagationPhase.h; path = dfg/DFGPredictionPropagationPhase.h; sourceTree = "<group>"; };
                0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVirtualRegisterAllocationPhase.cpp; path = dfg/DFGVirtualRegisterAllocationPhase.cpp; sourceTree = "<group>"; };
                0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVirtualRegisterAllocationPhase.h; path = dfg/DFGVirtualRegisterAllocationPhase.h; sourceTree = "<group>"; };
+               11C197C2624848EDA84CED7F /* JSScriptFetcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSScriptFetcher.cpp; sourceTree = "<group>"; };
                140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
                141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
                1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = minidom.js; path = tests/minidom.js; sourceTree = "<group>"; };
                2ADFA26218EF3540004F9FCC /* GCLogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCLogging.cpp; sourceTree = "<group>"; };
                2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureIDTable.cpp; sourceTree = "<group>"; };
                2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureIDTable.h; sourceTree = "<group>"; };
+               3032175DF1AD47D8998B34E1 /* JSSourceCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSourceCode.h; sourceTree = "<group>"; };
                371D842C17C98B6E00ECF994 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
                412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_internals_wrapper_header.py; sourceTree = "<group>"; };
                412952741D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_internals_wrapper_implementation.py; sourceTree = "<group>"; };
                65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProtoCallFrame.h; sourceTree = "<group>"; };
                65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProtoCallFrame.cpp; sourceTree = "<group>"; };
                6AD2CB4C19B9140100065719 /* DebuggerEvalEnabler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebuggerEvalEnabler.h; sourceTree = "<group>"; };
+               6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSScriptFetcher.h; sourceTree = "<group>"; };
                70113D491A8DB093003848C4 /* IteratorOperations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IteratorOperations.cpp; sourceTree = "<group>"; };
                70113D4A1A8DB093003848C4 /* IteratorOperations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IteratorOperations.h; sourceTree = "<group>"; };
                7013CA891B491A9400CAE613 /* JSJob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSJob.cpp; sourceTree = "<group>"; };
                86F75EFD151C062F007C9BA3 /* RegExpMatchesArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpMatchesArray.cpp; sourceTree = "<group>"; };
                86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBoundFunction.cpp; sourceTree = "<group>"; };
                86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBoundFunction.h; sourceTree = "<group>"; };
+               8852151A9C3842389B3215B7 /* ScriptFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptFetcher.h; sourceTree = "<group>"; };
                8B47F234366C4B72AC852A7E /* TemplateRegistryKeyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TemplateRegistryKeyTable.cpp; sourceTree = "<group>"; };
                8B9F6D551D5912FA001C739F /* IterationKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IterationKind.h; sourceTree = "<group>"; };
                90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryStatistics.cpp; sourceTree = "<group>"; };
                F692A87D0255597D01FF60F7 /* RegExp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExp.cpp; sourceTree = "<group>"; tabWidth = 8; };
                F692A87E0255597D01FF60F7 /* RegExp.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = RegExp.h; sourceTree = "<group>"; tabWidth = 8; };
                F692A8870255597D01FF60F7 /* JSCJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCJSValue.cpp; sourceTree = "<group>"; tabWidth = 8; };
+               F73926918DC64330AFCDF0D7 /* JSSourceCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSourceCode.cpp; sourceTree = "<group>"; };
                FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExecutionTimeLimitTest.cpp; path = API/tests/ExecutionTimeLimitTest.cpp; sourceTree = "<group>"; };
                FE0D4A051AB8DD0A002F54BF /* ExecutionTimeLimitTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExecutionTimeLimitTest.h; path = API/tests/ExecutionTimeLimitTest.h; sourceTree = "<group>"; };
                FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GlobalContextWithFinalizerTest.cpp; path = API/tests/GlobalContextWithFinalizerTest.cpp; sourceTree = "<group>"; };
                FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
                FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
                FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
-               F73926918DC64330AFCDF0D7 /* JSSourceCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSSourceCode.cpp; path = JSSourceCode.cpp; sourceTree = "<group>"; };
-               3032175DF1AD47D8998B34E1 /* JSSourceCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSSourceCode.h; path = JSSourceCode.h; sourceTree = "<group>"; };
-               11C197C2624848EDA84CED7F /* JSScriptFetcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSScriptFetcher.cpp; path = JSScriptFetcher.cpp; sourceTree = "<group>"; };
-               6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSScriptFetcher.h; path = JSScriptFetcher.h; sourceTree = "<group>"; };
-               8852151A9C3842389B3215B7 /* ScriptFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptFetcher.h; path = ScriptFetcher.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                862553CF16136AA5009F17D0 /* JSProxy.h */,
                                14874AE115EBDE4A002E3587 /* JSScope.cpp */,
                                14874AE215EBDE4A002E3587 /* JSScope.h */,
+                               11C197C2624848EDA84CED7F /* JSScriptFetcher.cpp */,
+                               6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */,
                                0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */,
                                0F919D0F157F3327004A4E7D /* JSSegmentedVariableObject.h */,
+                               0F4F82851E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.cpp */,
+                               0F4F82861E2FFDDB0075184C /* JSSegmentedVariableObjectSubspace.h */,
                                A7299D9B17D12837005F5FF9 /* JSSet.cpp */,
                                A7299D9C17D12837005F5FF9 /* JSSet.h */,
                                A790DD69182F499700588807 /* JSSetIterator.cpp */,
                                A790DD6A182F499700588807 /* JSSetIterator.h */,
+                               F73926918DC64330AFCDF0D7 /* JSSourceCode.cpp */,
+                               3032175DF1AD47D8998B34E1 /* JSSourceCode.h */,
                                BC02E9B60E1842FA000F9297 /* JSString.cpp */,
                                F692A8620255597D01FF60F7 /* JSString.h */,
                                86E85538111B9968001AF51E /* JSStringBuilder.h */,
                                0FE050221AA9095600D33B33 /* ScopeOffset.h */,
                                147341E01DC2CE9600AA29BA /* ScriptExecutable.cpp */,
                                147341CD1DC02D7900AA29BA /* ScriptExecutable.h */,
+                               8852151A9C3842389B3215B7 /* ScriptFetcher.h */,
                                A7299DA317D12858005F5FF9 /* SetConstructor.cpp */,
                                A7299DA417D12858005F5FF9 /* SetConstructor.h */,
                                A790DD67182F499700588807 /* SetIteratorPrototype.cpp */,
                                709FB8661AE335C60039D069 /* WeakSetPrototype.h */,
                                A7DCB77912E3D90500911940 /* WriteBarrier.h */,
                                C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */,
-                               F73926918DC64330AFCDF0D7 /* JSSourceCode.cpp */,
-                               3032175DF1AD47D8998B34E1 /* JSSourceCode.h */,
-                               11C197C2624848EDA84CED7F /* JSScriptFetcher.cpp */,
-                               6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */,
-                               8852151A9C3842389B3215B7 /* ScriptFetcher.h */,
                        );
                        path = runtime;
                        sourceTree = "<group>";
                                0F2DD8141AB3D8BE00BBB8E8 /* DFGArgumentsUtilities.h in Headers */,
                                0F485322187750560083B687 /* DFGArithMode.h in Headers */,
                                0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */,
+                               0F4F82881E2FFDE00075184C /* JSSegmentedVariableObjectSubspace.h in Headers */,
                                0F63948515E4811B006A597C /* DFGArrayMode.h in Headers */,
                                A7D9A29517A0BC7400EE2618 /* DFGAtTailAbstractState.h in Headers */,
                                0F666EC71835672B00D017F1 /* DFGAvailability.h in Headers */,
                                0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */,
                                14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
                                14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
+                               0F4F82871E2FFDDD0075184C /* JSSegmentedVariableObjectSubspace.cpp in Sources */,
                                ADB6F67D1E15D7600082F384 /* WasmPageCount.cpp in Sources */,
                                14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */,
                                DE26E9071CB5DEFB00D2BE82 /* BuiltinExecutableCreator.cpp in Sources */,
index a347de5..d941869 100644 (file)
@@ -1119,7 +1119,6 @@ public:
     {
         GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure);
         object->finishCreation(vm, arguments);
-        vm.heap.addFinalizer(object, destroy);
         return object;
     }
 
index 3832987..493d7e7 100644 (file)
@@ -42,7 +42,6 @@ public:
             new (NotNull, allocateCell<JSGlobalLexicalEnvironment>(vm.heap)) JSGlobalLexicalEnvironment(vm, structure, parentScope);
         result->finishCreation(vm);
         result->symbolTable()->setScopeType(SymbolTable::ScopeType::GlobalLexicalScope);
-        vm.heap.addFinalizer(result, destroy);
         return result;
     }
 
index 8e68efb..e0b1e7b 100644 (file)
@@ -1449,4 +1449,29 @@ bool JSGlobalObject::hasInteractiveDebugger() const
     return m_debugger && m_debugger->isInteractivelyDebugging();
 }
 
+JSGlobalObject* JSGlobalObject::create(VM& vm, Structure* structure)
+{
+    JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure);
+    globalObject->finishCreation(vm);
+    return globalObject;
+}
+
+void JSGlobalObject::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    structure()->setGlobalObject(vm, this);
+    m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
+    init(vm);
+    setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(), PureForwardingProxyType), this));
+}
+
+void JSGlobalObject::finishCreation(VM& vm, JSObject* thisValue)
+{
+    Base::finishCreation(vm);
+    structure()->setGlobalObject(vm, this);
+    m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
+    init(vm);
+    setGlobalThis(vm, thisValue);
+}
+
 } // namespace JSC
index 5c5c1a5..f9de641 100644 (file)
@@ -433,13 +433,7 @@ public:
     typedef JSSegmentedVariableObject Base;
     static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | OverridesToThis;
 
-    static JSGlobalObject* create(VM& vm, Structure* structure)
-    {
-        JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(vm.heap)) JSGlobalObject(vm, structure);
-        globalObject->finishCreation(vm);
-        vm.heap.addFinalizer(globalObject, destroy);
-        return globalObject;
-    }
+    JS_EXPORT_PRIVATE static JSGlobalObject* create(VM&, Structure*);
 
     DECLARE_EXPORT_INFO;
 
@@ -450,31 +444,15 @@ public:
 protected:
     JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0);
 
-    void finishCreation(VM& vm)
-    {
-        Base::finishCreation(vm);
-        structure()->setGlobalObject(vm, this);
-        m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
-        init(vm);
-        setGlobalThis(vm, JSProxy::create(vm, JSProxy::createStructure(vm, this, getPrototypeDirect(), PureForwardingProxyType), this));
-    }
+    JS_EXPORT_PRIVATE void finishCreation(VM&);
 
-    void finishCreation(VM& vm, JSObject* thisValue)
-    {
-        Base::finishCreation(vm);
-        structure()->setGlobalObject(vm, this);
-        m_runtimeFlags = m_globalObjectMethodTable->javaScriptRuntimeFlags(this);
-        init(vm);
-        setGlobalThis(vm, thisValue);
-    }
+    JS_EXPORT_PRIVATE void finishCreation(VM&, JSObject*);
 
     void addGlobalVar(const Identifier&);
 
 public:
     JS_EXPORT_PRIVATE ~JSGlobalObject();
     JS_EXPORT_PRIVATE static void destroy(JSCell*);
-    // We don't need a destructor because we use a finalizer instead.
-    static const bool needsDestruction = false;
 
     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
 
index f371f32..b7487f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-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
@@ -93,5 +93,28 @@ void JSSegmentedVariableObject::heapSnapshot(JSCell* cell, HeapSnapshotBuilder&
     }
 }
 
+void JSSegmentedVariableObject::destroy(JSCell* cell)
+{
+    static_cast<JSSegmentedVariableObject*>(cell)->JSSegmentedVariableObject::~JSSegmentedVariableObject();
+}
+
+JSSegmentedVariableObject::JSSegmentedVariableObject(VM& vm, Structure* structure, JSScope* scope)
+    : JSSymbolTableObject(vm, structure, scope)
+    , m_classInfo(structure->classInfo())
+{
+}
+
+JSSegmentedVariableObject::~JSSegmentedVariableObject()
+{
+    RELEASE_ASSERT(!m_alreadyDestroyed);
+    m_alreadyDestroyed = true;
+}
+
+void JSSegmentedVariableObject::finishCreation(VM& vm)
+{
+    Base::finishCreation(vm);
+    setSymbolTable(vm, SymbolTable::create(vm));
+}
+
 } // namespace JSC
 
index 212f957..b02426c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-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
@@ -86,23 +86,28 @@ public:
     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
     JS_EXPORT_PRIVATE static void heapSnapshot(JSCell*, HeapSnapshotBuilder&);
     
-protected:
-    JSSegmentedVariableObject(VM& vm, Structure* structure, JSScope* scope)
-        : JSSymbolTableObject(vm, structure, scope)
+    static void destroy(JSCell*);
+    
+    template<typename>
+    static Subspace* subspaceFor(VM& vm)
     {
+        return &vm.segmentedVariableObjectSpace;
     }
+    
+    const ClassInfo* classInfo() const { return m_classInfo; }
+    
+protected:
+    JSSegmentedVariableObject(VM&, Structure*, JSScope*);
+    
+    ~JSSegmentedVariableObject();
 
-    void finishCreation(VM& vm)
-    {
-        Base::finishCreation(vm);
-        setSymbolTable(vm, SymbolTable::create(vm));
-    }
+    void finishCreation(VM&);
     
 private:
-    // FIXME: This needs a destructor, which can only be added using custom subspace.
-    
     SegmentedVector<WriteBarrier<Unknown>, 16> m_variables;
     ConcurrentJSLock m_lock;
+    bool m_alreadyDestroyed { false }; // We use these assertions to check that we aren't doing ancient hacks that result in this being destroyed more than once.
+    const ClassInfo* m_classInfo;
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSSegmentedVariableObjectSubspace.cpp b/Source/JavaScriptCore/runtime/JSSegmentedVariableObjectSubspace.cpp
new file mode 100644 (file)
index 0000000..d2f28a3
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 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 "JSSegmentedVariableObjectSubspace.h"
+
+#include "JSCInlines.h"
+#include "MarkedBlockInlines.h"
+#include "SubspaceInlines.h"
+
+namespace JSC {
+
+namespace {
+
+struct DestroyFunc {
+    ALWAYS_INLINE void operator()(VM&, JSCell* cell) const
+    {
+        static_cast<JSSegmentedVariableObject*>(cell)->classInfo()->methodTable.destroy(cell);
+    }
+};
+
+} // anonymous namespace
+
+JSSegmentedVariableObjectSubspace::JSSegmentedVariableObjectSubspace(CString name, Heap& heap)
+    : Subspace(name, heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
+{
+}
+
+JSSegmentedVariableObjectSubspace::~JSSegmentedVariableObjectSubspace()
+{
+}
+
+FreeList JSSegmentedVariableObjectSubspace::finishSweep(MarkedBlock::Handle& handle, MarkedBlock::Handle::SweepMode sweepMode)
+{
+    return handle.finishSweepKnowingSubspace(sweepMode, DestroyFunc());
+}
+
+void JSSegmentedVariableObjectSubspace::destroy(VM& vm, JSCell* cell)
+{
+    DestroyFunc()(vm, cell);
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/runtime/JSSegmentedVariableObjectSubspace.h b/Source/JavaScriptCore/runtime/JSSegmentedVariableObjectSubspace.h
new file mode 100644 (file)
index 0000000..baf0f73
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 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 "Subspace.h"
+
+namespace JSC {
+
+class JSSegmentedVariableObjectSubspace : public Subspace {
+public:
+    JS_EXPORT_PRIVATE JSSegmentedVariableObjectSubspace(CString name, Heap&);
+    JS_EXPORT_PRIVATE virtual ~JSSegmentedVariableObjectSubspace();
+    
+    FreeList finishSweep(MarkedBlock::Handle&, MarkedBlock::Handle::SweepMode) override;
+    void destroy(VM&, JSCell*) override;
+};
+
+} // namespace JSC
+
index 2e14ee0..ca65efe 100644 (file)
@@ -171,6 +171,7 @@ VM::VM(VMType vmType, HeapType heapType)
     , destructibleCellSpace("Destructible JSCell", heap, AllocatorAttributes(NeedsDestruction, HeapCell::JSCell))
     , stringSpace("JSString", heap)
     , destructibleObjectSpace("JSDestructibleObject", heap)
+    , segmentedVariableObjectSpace("JSSegmentedVariableObjectSpace", heap)
     , vmType(vmType)
     , clientData(0)
     , topVMEntryFrame(nullptr)
index 0c6e134..658c0db 100644 (file)
@@ -42,6 +42,7 @@
 #include "JSCJSValue.h"
 #include "JSDestructibleObjectSubspace.h"
 #include "JSLock.h"
+#include "JSSegmentedVariableObjectSubspace.h"
 #include "JSStringSubspace.h"
 #include "MacroAssemblerCodeRef.h"
 #include "Microtask.h"
@@ -298,6 +299,7 @@ public:
     Subspace destructibleCellSpace;
     JSStringSubspace stringSpace;
     JSDestructibleObjectSubspace destructibleObjectSpace;
+    JSSegmentedVariableObjectSubspace segmentedVariableObjectSpace;
 
 #if ENABLE(DFG_JIT)
     std::unique_ptr<DFG::LongLivedState> dfgState;
index 6d6f280..d762a3a 100644 (file)
@@ -112,7 +112,6 @@ public:
     static GlobalObject* create(VM& vm, Structure* structure, const Vector<String>& arguments)
     {
         GlobalObject* globalObject = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure, arguments);
-        vm.heap.addFinalizer(globalObject, destroy);
         return globalObject;
     }
 
index 7ada951..1a74b58 100644 (file)
@@ -1,3 +1,21 @@
+2017-01-18  Filip Pizlo  <fpizlo@apple.com>
+
+        JSSegmentedVariableObject and its subclasses should have a sane destruction story
+        https://bugs.webkit.org/show_bug.cgi?id=167193
+
+        Reviewed by Saam Barati.
+
+        No new tests because no new behavior.
+        
+        JSSegmentedVariableObjects now get to have a sane destruction story. This means switching
+        subspace types for the DOM's global object subspace.
+
+        * bindings/js/WebCoreJSClientData.cpp:
+        (WebCore::JSVMClientData::JSVMClientData):
+        * bindings/js/WebCoreJSClientData.h:
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateHeader):
+
 2017-01-18  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r210848.
index 5464e91..d87931f 100644 (file)
@@ -44,7 +44,7 @@ JSVMClientData::JSVMClientData(VM& vm)
     : m_builtinFunctions(vm)
     , m_builtinNames(&vm)
     , m_outputConstraintSpace("WebCore Wrapper w/ Output Constraint", vm.heap)
-    , m_globalObjectOutputConstraintSpace("WebCore Global Object w/ Output Constraint", vm.heap, AllocatorAttributes(DoesNotNeedDestruction, HeapCell::JSCell))
+    , m_globalObjectOutputConstraintSpace("WebCore Global Object w/ Output Constraint", vm.heap)
 {
 }
 
index 9ef6819..47243c6 100644 (file)
@@ -78,7 +78,7 @@ private:
     WebCoreBuiltinNames m_builtinNames;
     
     JSC::JSDestructibleObjectSubspace m_outputConstraintSpace;
-    JSC::Subspace m_globalObjectOutputConstraintSpace;
+    JSC::JSSegmentedVariableObjectSubspace m_globalObjectOutputConstraintSpace;
 };
 
 } // namespace WebCore
index 37fc740..a01cb7c 100644 (file)
@@ -3,7 +3,7 @@
 # Copyright (C) 2006 Anders Carlsson <andersca@mac.com>
 # Copyright (C) 2006, 2007 Samuel Weinig <sam@webkit.org>
 # Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
-# Copyright (C) 2006-2010, 2013-2016 Apple Inc. All rights reserved.
+# Copyright (C) 2006-2017 Apple Inc. All rights reserved.
 # Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au>
 # Copyright (C) Research In Motion Limited 2010. All rights reserved.
 # Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
@@ -1751,7 +1751,6 @@ sub GenerateHeader
         push(@headerContent, "    {\n");
         push(@headerContent, "        $className* ptr = new (NotNull, JSC::allocateCell<$className>(vm.heap)) ${className}(vm, structure, WTFMove(impl), windowShell);\n");
         push(@headerContent, "        ptr->finishCreation(vm, windowShell);\n");
-        push(@headerContent, "        vm.heap.addFinalizer(ptr, destroy);\n");
         push(@headerContent, "        return ptr;\n");
         push(@headerContent, "    }\n\n");
     } elsif ($codeGenerator->InheritsInterface($interface, "WorkerGlobalScope")) {
@@ -1759,7 +1758,6 @@ sub GenerateHeader
         push(@headerContent, "    {\n");
         push(@headerContent, "        $className* ptr = new (NotNull, JSC::allocateCell<$className>(vm.heap)) ${className}(vm, structure, WTFMove(impl));\n");
         push(@headerContent, "        ptr->finishCreation(vm, proxy);\n");
-        push(@headerContent, "        vm.heap.addFinalizer(ptr, destroy);\n");
         push(@headerContent, "        return ptr;\n");
         push(@headerContent, "    }\n\n");
     } elsif ($interface->extendedAttributes->{MasqueradesAsUndefined}) {