Changeset 181806 in webkit
- Timestamp:
- Mar 20, 2015, 11:08:29 AM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/Source/JavaScriptCore/API/JSCallbackObject.cpp ¶
r171824 r181806 62 62 } 63 63 64 void JSCallbackObjectData::finalize(Handle<Unknown> handle, void* context)65 {66 JSClassRef jsClass = static_cast<JSClassRef>(context);67 JSObjectRef thisRef = toRef(static_cast<JSObject*>(handle.get().asCell()));68 69 for (; jsClass; jsClass = jsClass->parentClass)70 if (JSObjectFinalizeCallback finalize = jsClass->finalize)71 finalize(thisRef);72 WeakSet::deallocate(WeakImpl::asWeakImpl(handle.slot()));73 }74 75 64 } // namespace JSC -
TabularUnified trunk/Source/JavaScriptCore/API/JSCallbackObject.h ¶
r175651 r181806 34 34 namespace JSC { 35 35 36 struct JSCallbackObjectData : WeakHandleOwner{36 struct JSCallbackObjectData { 37 37 JSCallbackObjectData(void* privateData, JSClassRef jsClass) 38 38 : privateData(privateData) … … 42 42 } 43 43 44 virtual~JSCallbackObjectData()44 ~JSCallbackObjectData() 45 45 { 46 46 JSClassRelease(jsClass); … … 110 110 }; 111 111 std::unique_ptr<JSPrivatePropertyMap> m_privateProperties; 112 virtual void finalize(Handle<Unknown>, void*) override;113 112 }; 114 113 … … 125 124 public: 126 125 typedef Parent Base; 126 127 ~JSCallbackObject(); 127 128 128 129 static JSCallbackObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, void* data) -
TabularUnified trunk/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h ¶
r181064 r181806 75 75 76 76 template <class Parent> 77 JSCallbackObject<Parent>::~JSCallbackObject() 78 { 79 JSObjectRef thisRef = toRef(static_cast<JSObject*>(this)); 80 for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { 81 if (JSObjectFinalizeCallback finalize = jsClass->finalize) 82 finalize(thisRef); 83 } 84 } 85 86 template <class Parent> 77 87 void JSCallbackObject<Parent>::finishCreation(ExecState* exec) 78 88 { … … 109 119 JSObjectInitializeCallback initialize = initRoutines[i]; 110 120 initialize(toRef(exec), toRef(this)); 111 }112 113 for (JSClassRef jsClassPtr = classRef(); jsClassPtr; jsClassPtr = jsClassPtr->parentClass) {114 if (jsClassPtr->finalize) {115 WeakSet::allocate(this, m_callbackObjectData.get(), classRef());116 break;117 }118 121 } 119 122 } -
TabularUnified trunk/Source/JavaScriptCore/API/tests/testapi.c ¶
r181670 r181806 42 42 #include "CompareAndSwapTest.h" 43 43 #include "CustomGlobalObjectClassTest.h" 44 #include "GlobalContextWithFinalizerTest.h" 44 45 45 46 #if OS(DARWIN) … … 1857 1858 failed = testExecutionTimeLimit(&context) || failed; 1858 1859 #endif /* OS(DARWIN) */ 1860 failed = testGlobalContextWithFinalizer() || failed; 1859 1861 1860 1862 // Clear out local variables pointing at JSObjectRefs to allow their values to be collected -
TabularUnified trunk/Source/JavaScriptCore/ChangeLog ¶
r181765 r181806 1 2015-03-19 Mark Lam <mark.lam@apple.com> 2 3 JSCallbackObject<JSGlobalObject> should not destroy its JSCallbackObjectData before all its finalizers have been called. 4 <https://webkit.org/b/142846> 5 6 Reviewed by Geoffrey Garen. 7 8 Currently, JSCallbackObject<JSGlobalObject> registers weak finalizers via 2 mechanisms: 9 1. JSCallbackObject<Parent>::init() registers a weak finalizer for all JSClassRef 10 that a JSCallbackObject references. 11 2. JSCallbackObject<JSGlobalObject>::create() registers a finalizer via 12 vm.heap.addFinalizer() which destroys the JSCallbackObject. 13 14 The first finalizer is implemented as a virtual function of a JSCallbackObjectData 15 instance that will be destructed if the 2nd finalizer is called. Hence, if the 16 2nd finalizer if called first, the later invocation of the 1st finalizer will 17 result in a crash. 18 19 This patch fixes the issue by eliminating the finalizer registration in init(). 20 Instead, we'll have the JSCallbackObject destructor call all the JSClassRef finalizers 21 if needed. This ensures that these finalizers are called before the JSCallbackObject 22 is destructor. 23 24 Also added assertions to a few Heap functions because JSCell::classInfo() expects 25 all objects that are allocated from MarkedBlock::Normal blocks to be derived from 26 JSDestructibleObject. These assertions will help us catch violations of this 27 expectation earlier. 28 29 * API/JSCallbackObject.cpp: 30 (JSC::JSCallbackObjectData::finalize): Deleted. 31 * API/JSCallbackObject.h: 32 (JSC::JSCallbackObjectData::~JSCallbackObjectData): 33 * API/JSCallbackObjectFunctions.h: 34 (JSC::JSCallbackObject<Parent>::~JSCallbackObject): 35 (JSC::JSCallbackObject<Parent>::init): 36 * API/tests/GlobalContextWithFinalizerTest.cpp: Added. 37 (finalize): 38 (testGlobalContextWithFinalizer): 39 * API/tests/GlobalContextWithFinalizerTest.h: Added. 40 * API/tests/testapi.c: 41 (main): 42 * JavaScriptCore.vcxproj/testapi/testapi.vcxproj: 43 * JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters: 44 * JavaScriptCore.xcodeproj/project.pbxproj: 45 * heap/HeapInlines.h: 46 (JSC::Heap::allocateObjectOfType): 47 (JSC::Heap::subspaceForObjectOfType): 48 (JSC::Heap::allocatorForObjectOfType): 49 1 50 2015-03-19 Andreas Kling <akling@apple.com> 2 51 -
TabularUnified trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj ¶
r181315 r181806 297 297 <ClCompile Include="..\..\API\tests\CustomGlobalObjectClassTest.c" /> 298 298 <ClInclude Include="..\..\API\tests\CustomGlobalObjectClassTest.h" /> 299 <ClCompile Include="..\..\API\tests\GlobalContextWithFinalizerTest.cpp" /> 300 <ClInclude Include="..\..\API\tests\GlobalContextWithFinalizerTest.h" /> 299 301 </ItemGroup> 300 302 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> -
TabularUnified trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/testapi/testapi.vcxproj.filters ¶
r181315 r181806 13 13 <ClCompile Include="..\..\API\tests\CustomGlobalObjectClassTest.c" /> 14 14 <ClInclude Include="..\..\API\tests\CustomGlobalObjectClassTest.h" /> 15 <ClCompile Include="..\..\API\tests\GlobalContextWithFinalizerTest.cpp" /> 16 <ClInclude Include="..\..\API\tests\GlobalContextWithFinalizerTest.h" /> 15 17 </ItemGroup> 16 18 </Project> -
TabularUnified trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj ¶
r181670 r181806 1613 1613 E49DC16D12EF295300184A1F /* SourceProviderCacheItem.h in Headers */ = {isa = PBXBuildFile; fileRef = E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1614 1614 FE0D4A061AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */; }; 1615 FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */; }; 1615 1616 FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */; }; 1616 1617 FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 3361 3362 FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExecutionTimeLimitTest.cpp; path = API/tests/ExecutionTimeLimitTest.cpp; sourceTree = "<group>"; }; 3362 3363 FE0D4A051AB8DD0A002F54BF /* ExecutionTimeLimitTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExecutionTimeLimitTest.h; path = API/tests/ExecutionTimeLimitTest.h; sourceTree = "<group>"; }; 3364 FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GlobalContextWithFinalizerTest.cpp; path = API/tests/GlobalContextWithFinalizerTest.cpp; sourceTree = "<group>"; }; 3365 FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GlobalContextWithFinalizerTest.h; path = API/tests/GlobalContextWithFinalizerTest.h; sourceTree = "<group>"; }; 3363 3366 FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; }; 3364 3367 FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; }; … … 3748 3751 FE0D4A041AB8DD0A002F54BF /* ExecutionTimeLimitTest.cpp */, 3749 3752 FE0D4A051AB8DD0A002F54BF /* ExecutionTimeLimitTest.h */, 3753 FE0D4A071ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp */, 3754 FE0D4A081ABA2437002F54BF /* GlobalContextWithFinalizerTest.h */, 3750 3755 C2181FC018A948FB0025A235 /* JSExportTests.h */, 3751 3756 C2181FC118A948FB0025A235 /* JSExportTests.mm */, … … 6788 6793 buildActionMask = 2147483647; 6789 6794 files = ( 6795 FE0D4A091ABA2437002F54BF /* GlobalContextWithFinalizerTest.cpp in Sources */, 6790 6796 65570F5A1AA4C3EA009B3C23 /* Regress141275.mm in Sources */, 6791 6797 C29ECB031804D0ED00D2CBB4 /* CurrentThisInsideBlockGetterTest.mm in Sources */, -
TabularUnified trunk/Source/JavaScriptCore/heap/HeapInlines.h ¶
r181407 r181806 30 30 #include "JSCell.h" 31 31 #include "Structure.h" 32 #include <type_traits> 33 #include <wtf/Assertions.h> 32 34 33 35 namespace JSC { … … 238 240 void* Heap::allocateObjectOfType(size_t bytes) 239 241 { 242 // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject. 243 ASSERT((!ClassType::needsDestruction || ClassType::hasImmortalStructure || std::is_convertible<ClassType, JSDestructibleObject>::value)); 244 240 245 if (ClassType::needsDestruction && ClassType::hasImmortalStructure) 241 246 return allocateWithImmortalStructureDestructor(bytes); … … 248 253 MarkedSpace::Subspace& Heap::subspaceForObjectOfType() 249 254 { 255 // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject. 256 ASSERT((!ClassType::needsDestruction || ClassType::hasImmortalStructure || std::is_convertible<ClassType, JSDestructibleObject>::value)); 257 250 258 if (ClassType::needsDestruction && ClassType::hasImmortalStructure) 251 259 return subspaceForObjectsWithImmortalStructure(); … … 258 266 MarkedAllocator& Heap::allocatorForObjectOfType(size_t bytes) 259 267 { 268 // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject. 269 ASSERT((!ClassType::needsDestruction || ClassType::hasImmortalStructure || std::is_convertible<ClassType, JSDestructibleObject>::value)); 270 260 271 if (ClassType::needsDestruction && ClassType::hasImmortalStructure) 261 272 return allocatorForObjectWithImmortalStructureDestructor(bytes);
Note:
See TracChangeset
for help on using the changeset viewer.