Changeset 157539 in webkit
- Timestamp:
- Oct 16, 2013, 4:47:45 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r157424 r157539 182 182 heap/CopiedSpace.cpp 183 183 heap/CopyVisitor.cpp 184 heap/DeferGC.cpp 184 185 heap/GCThread.cpp 185 186 heap/GCThreadSharedData.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r157537 r157539 1 2013-10-16 Mark Hahnenberg <mhahnenberg@apple.com> 2 3 llint_slow_path_put_by_id can deadlock on a ConcurrentJITLock 4 https://bugs.webkit.org/show_bug.cgi?id=122667 5 6 Reviewed by Geoffrey Garen. 7 8 The issue this patch is attempting to fix is that there are places in our codebase 9 where we acquire the ConcurrentJITLock for a particular CodeBlock, then we do some 10 operations that can initiate a garbage collection. Garbage collection then calls 11 some methods of CodeBlock that also take the ConcurrentJITLock (because they don't 12 always necessarily run during garbage collection). This causes a deadlock. 13 14 To fix this issue, this patch adds a new RAII-style object (DisallowGC) that stores 15 into a thread-local field that indicates that it is unsafe to perform any operation 16 that could trigger garbage collection on the current thread. In debug builds, 17 ConcurrentJITLocker contains one of these DisallowGC objects so that we can eagerly 18 detect deadlocks. 19 20 This patch also adds a new type of ConcurrentJITLocker, GCSafeConcurrentJITLocker, 21 which uses the DeferGC mechanism to prevent collections from occurring while the 22 lock is held. 23 24 * CMakeLists.txt: 25 * GNUmakefile.list.am: 26 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj: 27 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters: 28 * JavaScriptCore.xcodeproj/project.pbxproj: 29 * heap/DeferGC.h: 30 (JSC::DisallowGC::DisallowGC): 31 (JSC::DisallowGC::~DisallowGC): 32 (JSC::DisallowGC::isGCDisallowedOnCurrentThread): 33 (JSC::DisallowGC::initialize): 34 * jit/Repatch.cpp: 35 (JSC::repatchPutByID): 36 (JSC::buildPutByIdList): 37 * llint/LLIntSlowPaths.cpp: 38 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 39 * runtime/ConcurrentJITLock.h: 40 (JSC::ConcurrentJITLockerBase::ConcurrentJITLockerBase): 41 (JSC::ConcurrentJITLockerBase::~ConcurrentJITLockerBase): 42 (JSC::ConcurrentJITLockerBase::unlockEarly): 43 (JSC::GCSafeConcurrentJITLocker::GCSafeConcurrentJITLocker): 44 (JSC::GCSafeConcurrentJITLocker::~GCSafeConcurrentJITLocker): 45 (JSC::GCSafeConcurrentJITLocker::NoDefer::NoDefer): 46 (JSC::ConcurrentJITLocker::ConcurrentJITLocker): 47 * runtime/InitializeThreading.cpp: 48 (JSC::initializeThreadingOnce): 49 * runtime/JSCellInlines.h: 50 (JSC::allocateCell): 51 * runtime/JSSymbolTableObject.h: 52 (JSC::symbolTablePut): 53 * runtime/Structure.cpp: materializePropertyMapIfNecessary* now has a problem in that it 54 can start a garbage collection when the GCSafeConcurrentJITLocker goes out of scope, but 55 before the caller has a chance to use the newly created PropertyTable. The garbage collection 56 clears the PropertyTable, and then the caller uses it assuming it's valid. To avoid this, 57 we must DeferGC until the caller is done getting the newly materialized PropertyTable from 58 the Structure. 59 (JSC::Structure::materializePropertyMap): 60 (JSC::Structure::despecifyDictionaryFunction): 61 (JSC::Structure::changePrototypeTransition): 62 (JSC::Structure::despecifyFunctionTransition): 63 (JSC::Structure::attributeChangeTransition): 64 (JSC::Structure::toDictionaryTransition): 65 (JSC::Structure::preventExtensionsTransition): 66 (JSC::Structure::takePropertyTableOrCloneIfPinned): 67 (JSC::Structure::isSealed): 68 (JSC::Structure::isFrozen): 69 (JSC::Structure::addPropertyWithoutTransition): 70 (JSC::Structure::removePropertyWithoutTransition): 71 (JSC::Structure::get): 72 (JSC::Structure::despecifyFunction): 73 (JSC::Structure::despecifyAllFunctions): 74 (JSC::Structure::putSpecificValue): 75 (JSC::Structure::createPropertyMap): 76 (JSC::Structure::getPropertyNamesFromStructure): 77 * runtime/Structure.h: 78 (JSC::Structure::materializePropertyMapIfNecessary): 79 (JSC::Structure::materializePropertyMapIfNecessaryForPinning): 80 * runtime/StructureInlines.h: 81 (JSC::Structure::get): 82 * runtime/SymbolTable.h: 83 (JSC::SymbolTable::find): 84 (JSC::SymbolTable::end): 85 1 86 2013-10-16 Daniel Bates <dabates@apple.com> 2 87 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r157424 r157539 468 468 Source/JavaScriptCore/heap/ConservativeRoots.cpp \ 469 469 Source/JavaScriptCore/heap/ConservativeRoots.h \ 470 Source/JavaScriptCore/heap/DeferGC.cpp \ 470 471 Source/JavaScriptCore/heap/DeferGC.h \ 471 472 Source/JavaScriptCore/heap/GCAssertions.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
r157424 r157539 337 337 <ClCompile Include="..\heap\CopiedSpace.cpp" /> 338 338 <ClCompile Include="..\heap\CopyVisitor.cpp" /> 339 <ClCompile Include="..\heap\DeferGC.cpp" /> 339 340 <ClCompile Include="..\heap\GCThread.cpp" /> 340 341 <ClCompile Include="..\heap\GCThreadSharedData.cpp" /> … … 705 706 <ClInclude Include="..\heap\CopyVisitorInlines.h" /> 706 707 <ClInclude Include="..\heap\CopyWorkList.h" /> 708 <ClInclude Include="..\heap\DeferGC.h" /> 707 709 <ClInclude Include="..\heap\GCAssertions.h" /> 708 710 <ClInclude Include="..\heap\GCThread.h" /> -
trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters
r157424 r157539 874 874 <Filter>heap</Filter> 875 875 </ClCompile> 876 <ClCompile Include="..\heap\DeferGC.cpp"> 877 <Filter>heap</Filter> 878 </ClCompile> 876 879 <ClCompile Include="..\bytecode\DeferredCompilationCallback.cpp"> 877 880 <Filter>bytecode</Filter> … … 1222 1225 </ClInclude> 1223 1226 <ClInclude Include="..\heap\CopyWorkList.h"> 1227 <Filter>heap</Filter> 1228 </ClInclude> 1229 <ClInclude Include="..\heap\DeferGC.h"> 1224 1230 <Filter>heap</Filter> 1225 1231 </ClInclude> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r157474 r157539 374 374 0FC815151405119B00CFA603 /* VTableSpectrum.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC815141405118D00CFA603 /* VTableSpectrum.h */; settings = {ATTRIBUTES = (Private, ); }; }; 375 375 0FC81516140511B500CFA603 /* VTableSpectrum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC815121405118600CFA603 /* VTableSpectrum.cpp */; }; 376 0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */; }; 377 0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */; settings = {ATTRIBUTES = (Private, ); }; }; 376 378 0FCCAE4516D0CF7400D0C65B /* ParserError.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCCAE4316D0CF6E00D0C65B /* ParserError.h */; settings = {ATTRIBUTES = (Private, ); }; }; 377 379 0FCEFAB01805CA6D00472CE4 /* InitializeLLVM.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCEFAAE1805CA6D00472CE4 /* InitializeLLVM.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 685 687 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACF7376171CA6FB00C9BB1E /* Weak.cpp */; }; 686 688 2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */; }; 689 2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */; }; 687 690 2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; }; 688 691 2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = C211B574176A224D000E2A23 /* APICallbackFunction.h */; }; … … 1628 1631 0FC712E117CD878F008CC93C /* JITToDFGDeferredCompilationCallback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JITToDFGDeferredCompilationCallback.h; sourceTree = "<group>"; }; 1629 1632 0FC8150814043BCA00CFA603 /* WriteBarrierSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierSupport.cpp; sourceTree = "<group>"; }; 1633 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLSaveRestore.cpp; path = ftl/FTLSaveRestore.cpp; sourceTree = "<group>"; }; 1634 0FCEFAAA1804C13E00472CE4 /* FTLSaveRestore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLSaveRestore.h; path = ftl/FTLSaveRestore.h; sourceTree = "<group>"; }; 1630 1635 0FC8150914043BD200CFA603 /* WriteBarrierSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierSupport.h; sourceTree = "<group>"; }; 1631 1636 0FC815121405118600CFA603 /* VTableSpectrum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTableSpectrum.cpp; sourceTree = "<group>"; }; … … 1892 1897 1C9051440BA9E8A70081E9D0 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; }; 1893 1898 1C9051450BA9E8A70081E9D0 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; }; 1899 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferGC.cpp; sourceTree = "<group>"; }; 1894 1900 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScript.h; sourceTree = "<group>"; }; 1895 1901 1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCore.h; sourceTree = "<group>"; }; … … 2917 2923 isa = PBXGroup; 2918 2924 children = ( 2925 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */, 2919 2926 14816E19154CC56C00B8054C /* BlockAllocator.cpp */, 2920 2927 14816E1A154CC56C00B8054C /* BlockAllocator.h */, … … 5481 5488 0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */, 5482 5489 14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */, 5490 2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */, 5483 5491 8642C512151C083D0046D4EF /* RegExpMatchesArray.cpp in Sources */, 5484 5492 14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */, -
trunk/Source/JavaScriptCore/heap/DeferGC.h
r157424 r157539 29 29 #include "Heap.h" 30 30 #include <wtf/Noncopyable.h> 31 #include <wtf/ThreadSpecific.h> 31 32 32 33 namespace JSC { … … 68 69 }; 69 70 71 #ifndef NDEBUG 72 class DisallowGC { 73 WTF_MAKE_NONCOPYABLE(DisallowGC); 74 public: 75 DisallowGC() 76 { 77 WTF::threadSpecificSet(s_isGCDisallowedOnCurrentThread, reinterpret_cast<void*>(true)); 78 } 79 80 ~DisallowGC() 81 { 82 WTF::threadSpecificSet(s_isGCDisallowedOnCurrentThread, reinterpret_cast<void*>(false)); 83 } 84 85 static bool isGCDisallowedOnCurrentThread() 86 { 87 return !!WTF::threadSpecificGet(s_isGCDisallowedOnCurrentThread); 88 } 89 static void initialize() 90 { 91 WTF::threadSpecificKeyCreate(&s_isGCDisallowedOnCurrentThread, 0); 92 } 93 94 private: 95 JS_EXPORT_PRIVATE static WTF::ThreadSpecificKey s_isGCDisallowedOnCurrentThread; 96 }; 97 #endif // NDEBUG 98 70 99 } // namespace JSC 71 100 -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r157489 r157539 361 361 void repatchGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo) 362 362 { 363 ConcurrentJITLocker locker(exec->codeBlock()->m_lock);363 GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); 364 364 365 365 bool cached = tryCacheGetByID(exec, baseValue, propertyName, slot, stubInfo); … … 602 602 void buildGetByIDList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo) 603 603 { 604 ConcurrentJITLocker locker(exec->codeBlock()->m_lock);604 GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); 605 605 606 606 bool dontChangeCall = tryBuildGetByIDList(exec, baseValue, propertyName, slot, stubInfo); … … 1007 1007 void repatchPutByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) 1008 1008 { 1009 ConcurrentJITLocker locker(exec->codeBlock()->m_lock);1009 GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); 1010 1010 1011 1011 bool cached = tryCachePutByID(exec, baseValue, propertyName, slot, stubInfo, putKind); … … 1102 1102 void buildPutByIdList(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PutPropertySlot& slot, StructureStubInfo& stubInfo, PutKind putKind) 1103 1103 { 1104 ConcurrentJITLocker locker(exec->codeBlock()->m_lock);1104 GCSafeConcurrentJITLocker locker(exec->codeBlock()->m_lock, exec->vm().heap); 1105 1105 1106 1106 bool cached = tryBuildPutByIdList(exec, baseValue, propertyName, slot, stubInfo, putKind); -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r157474 r157539 597 597 598 598 if (slot.type() == PutPropertySlot::NewProperty) { 599 ConcurrentJITLocker locker(codeBlock->m_lock);599 GCSafeConcurrentJITLocker locker(codeBlock->m_lock, vm.heap); 600 600 601 601 if (!structure->isDictionary() && structure->previousID()->outOfLineCapacity() == structure->outOfLineCapacity()) { -
trunk/Source/JavaScriptCore/runtime/ConcurrentJITLock.h
r157424 r157539 27 27 #define ConcurrentJITLock_h 28 28 29 #include "DeferGC.h" 29 30 #include <wtf/ByteSpinLock.h> 30 31 #include <wtf/NoLock.h> … … 34 35 #if ENABLE(CONCURRENT_JIT) 35 36 typedef ByteSpinLock ConcurrentJITLock; 36 typedef ByteSpinLocker ConcurrentJITLocker ;37 typedef ByteSpinLocker ConcurrentJITLockerImpl; 37 38 #else 38 39 typedef NoLock ConcurrentJITLock; 39 typedef NoLockLocker ConcurrentJITLocker ;40 typedef NoLockLocker ConcurrentJITLockerImpl; 40 41 #endif 42 43 class ConcurrentJITLockerBase { 44 WTF_MAKE_NONCOPYABLE(ConcurrentJITLockerBase); 45 public: 46 explicit ConcurrentJITLockerBase(ConcurrentJITLock& lockable) 47 : m_locker(&lockable) 48 { 49 } 50 explicit ConcurrentJITLockerBase(ConcurrentJITLock* lockable) 51 : m_locker(lockable) 52 { 53 } 54 55 ~ConcurrentJITLockerBase() 56 { 57 } 58 59 void unlockEarly() 60 { 61 m_locker.unlockEarly(); 62 } 63 64 private: 65 ConcurrentJITLockerImpl m_locker; 66 }; 67 68 class GCSafeConcurrentJITLocker : public ConcurrentJITLockerBase { 69 public: 70 GCSafeConcurrentJITLocker(ConcurrentJITLock& lockable, Heap& heap) 71 : ConcurrentJITLockerBase(lockable) 72 , m_deferGC(heap) 73 { 74 } 75 76 GCSafeConcurrentJITLocker(ConcurrentJITLock* lockable, Heap& heap) 77 : ConcurrentJITLockerBase(lockable) 78 , m_deferGC(heap) 79 { 80 } 81 82 ~GCSafeConcurrentJITLocker() 83 { 84 // We have to unlock early due to the destruction order of base 85 // vs. derived classes. If we didn't, then we would destroy the 86 // DeferGC object before unlocking the lock which could cause a GC 87 // and resulting deadlock. 88 unlockEarly(); 89 } 90 91 private: 92 #if ENABLE(CONCURRENT_JIT) 93 DeferGC m_deferGC; 94 #else 95 struct NoDefer { 96 NoDefer(Heap& heap) : m_heap(heap) { } 97 Heap& m_heap; 98 }; 99 NoDefer m_deferGC; 100 #endif 101 }; 102 103 class ConcurrentJITLocker : public ConcurrentJITLockerBase { 104 public: 105 ConcurrentJITLocker(ConcurrentJITLock& lockable) 106 : ConcurrentJITLockerBase(lockable) 107 { 108 } 109 110 ConcurrentJITLocker(ConcurrentJITLock* lockable) 111 : ConcurrentJITLockerBase(lockable) 112 { 113 } 114 115 #if ENABLE(CONCURRENT_JIT) && !defined(NDEBUG) 116 private: 117 DisallowGC m_disallowGC; 118 #endif 119 }; 41 120 42 121 } // namespace JSC 43 122 44 123 #endif // ConcurrentJITLock_h 45 -
trunk/Source/JavaScriptCore/runtime/InitializeThreading.cpp
r157424 r157539 70 70 LLInt::initialize(); 71 71 #endif 72 #ifndef NDEBUG 73 DisallowGC::initialize(); 74 #endif 72 75 } 73 76 -
trunk/Source/JavaScriptCore/runtime/JSCellInlines.h
r157424 r157539 28 28 29 29 #include "CallFrame.h" 30 #include "DeferGC.h" 30 31 #include "Handle.h" 31 32 #include "JSCell.h" … … 86 87 void* allocateCell(Heap& heap, size_t size) 87 88 { 89 ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread()); 88 90 ASSERT(size >= sizeof(T)); 89 91 #if ENABLE(GC_VALIDATION) -
trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
r154459 r157539 126 126 { 127 127 SymbolTable& symbolTable = *object->symbolTable(); 128 ConcurrentJITLocker locker(symbolTable.m_lock);128 GCSafeConcurrentJITLocker locker(symbolTable.m_lock, exec->vm().heap); 129 129 SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName()); 130 130 if (iter == symbolTable.end(locker)) -
trunk/Source/JavaScriptCore/runtime/Structure.cpp
r157424 r157539 281 281 // property map. We don't want getConcurrently() to see the property map in a half-baked 282 282 // state. 283 ConcurrentJITLocker locker(m_lock);283 GCSafeConcurrentJITLocker locker(m_lock, vm.heap); 284 284 if (!table) 285 285 createPropertyMap(locker, vm, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)); … … 314 314 StringImpl* rep = propertyName.uid(); 315 315 316 materializePropertyMapIfNecessary(vm); 316 DeferGC deferGC(vm.heap); 317 materializePropertyMapIfNecessary(vm, deferGC); 317 318 318 319 ASSERT(isDictionary()); … … 452 453 transition->m_prototype.set(vm, transition, prototype); 453 454 454 structure->materializePropertyMapIfNecessary(vm); 455 DeferGC deferGC(vm.heap); 456 structure->materializePropertyMapIfNecessary(vm, deferGC); 455 457 transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition)); 456 458 transition->m_offset = structure->m_offset; … … 468 470 ++transition->m_specificFunctionThrashCount; 469 471 470 structure->materializePropertyMapIfNecessary(vm); 472 DeferGC deferGC(vm.heap); 473 structure->materializePropertyMapIfNecessary(vm, deferGC); 471 474 transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition)); 472 475 transition->m_offset = structure->m_offset; … … 486 489 Structure* Structure::attributeChangeTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes) 487 490 { 491 DeferGC deferGC(vm.heap); 488 492 if (!structure->isUncacheableDictionary()) { 489 493 Structure* transition = create(vm, structure); 490 494 491 structure->materializePropertyMapIfNecessary(vm );495 structure->materializePropertyMapIfNecessary(vm, deferGC); 492 496 transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition)); 493 497 transition->m_offset = structure->m_offset; … … 512 516 Structure* transition = create(vm, structure); 513 517 514 structure->materializePropertyMapIfNecessary(vm); 518 DeferGC deferGC(vm.heap); 519 structure->materializePropertyMapIfNecessary(vm, deferGC); 515 520 transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition)); 516 521 transition->m_offset = structure->m_offset; … … 572 577 // Don't set m_offset, as one can not transition to this. 573 578 574 structure->materializePropertyMapIfNecessary(vm); 579 DeferGC deferGC(vm.heap); 580 structure->materializePropertyMapIfNecessary(vm, deferGC); 575 581 transition->propertyTable().set(vm, transition, structure->copyPropertyTableForPinning(vm, transition)); 576 582 transition->m_offset = structure->m_offset; … … 584 590 PropertyTable* Structure::takePropertyTableOrCloneIfPinned(VM& vm, Structure* owner) 585 591 { 586 materializePropertyMapIfNecessaryForPinning(vm); 592 DeferGC deferGC(vm.heap); 593 materializePropertyMapIfNecessaryForPinning(vm, deferGC); 587 594 588 595 if (m_isPinnedPropertyTable) … … 641 648 return false; 642 649 643 materializePropertyMapIfNecessary(vm); 650 DeferGC deferGC(vm.heap); 651 materializePropertyMapIfNecessary(vm, deferGC); 644 652 if (!propertyTable()) 645 653 return true; … … 659 667 return false; 660 668 661 materializePropertyMapIfNecessary(vm); 669 DeferGC deferGC(vm.heap); 670 materializePropertyMapIfNecessary(vm, deferGC); 662 671 if (!propertyTable()) 663 672 return true; … … 719 728 specificValue = 0; 720 729 721 materializePropertyMapIfNecessaryForPinning(vm); 730 DeferGC deferGC(vm.heap); 731 materializePropertyMapIfNecessaryForPinning(vm, deferGC); 722 732 723 733 pin(); … … 731 741 ASSERT(!enumerationCache()); 732 742 733 materializePropertyMapIfNecessaryForPinning(vm); 743 DeferGC deferGC(vm.heap); 744 materializePropertyMapIfNecessaryForPinning(vm, deferGC); 734 745 735 746 pin(); … … 841 852 ASSERT(structure()->classInfo() == info()); 842 853 843 materializePropertyMapIfNecessary(vm); 854 DeferGC deferGC(vm.heap); 855 materializePropertyMapIfNecessary(vm, deferGC); 844 856 if (!propertyTable()) 845 857 return invalidOffset; … … 856 868 bool Structure::despecifyFunction(VM& vm, PropertyName propertyName) 857 869 { 858 materializePropertyMapIfNecessary(vm); 870 DeferGC deferGC(vm.heap); 871 materializePropertyMapIfNecessary(vm, deferGC); 859 872 if (!propertyTable()) 860 873 return false; … … 871 884 void Structure::despecifyAllFunctions(VM& vm) 872 885 { 873 materializePropertyMapIfNecessary(vm); 886 DeferGC deferGC(vm.heap); 887 materializePropertyMapIfNecessary(vm, deferGC); 874 888 if (!propertyTable()) 875 889 return; … … 882 896 PropertyOffset Structure::putSpecificValue(VM& vm, PropertyName propertyName, unsigned attributes, JSCell* specificValue) 883 897 { 884 ConcurrentJITLocker locker(m_lock);898 GCSafeConcurrentJITLocker locker(m_lock, vm.heap); 885 899 886 900 ASSERT(!JSC::isValidOffset(get(vm, propertyName))); … … 927 941 } 928 942 929 void Structure::createPropertyMap(const ConcurrentJITLocker&, VM& vm, unsigned capacity)943 void Structure::createPropertyMap(const GCSafeConcurrentJITLocker&, VM& vm, unsigned capacity) 930 944 { 931 945 ASSERT(!propertyTable()); … … 937 951 void Structure::getPropertyNamesFromStructure(VM& vm, PropertyNameArray& propertyNames, EnumerationMode mode) 938 952 { 939 materializePropertyMapIfNecessary(vm); 953 DeferGC deferGC(vm.heap); 954 materializePropertyMapIfNecessary(vm, deferGC); 940 955 if (!propertyTable()) 941 956 return; -
trunk/Source/JavaScriptCore/runtime/Structure.h
r157424 r157539 52 52 namespace JSC { 53 53 54 class DeferGC; 54 55 class LLIntOffsetsExtractor; 55 56 class PropertyNameArray; … … 394 395 PropertyOffset remove(PropertyName); 395 396 396 void createPropertyMap(const ConcurrentJITLocker&, VM&, unsigned keyCount = 0);397 void createPropertyMap(const GCSafeConcurrentJITLocker&, VM&, unsigned keyCount = 0); 397 398 void checkConsistency(); 398 399 … … 405 406 PropertyTable* copyPropertyTableForPinning(VM&, Structure* owner); 406 407 JS_EXPORT_PRIVATE void materializePropertyMap(VM&); 407 void materializePropertyMapIfNecessary(VM& vm )408 void materializePropertyMapIfNecessary(VM& vm, DeferGC&) 408 409 { 409 410 ASSERT(!isCompilationThread()); … … 413 414 materializePropertyMap(vm); 414 415 } 415 void materializePropertyMapIfNecessaryForPinning(VM& vm )416 void materializePropertyMapIfNecessaryForPinning(VM& vm, DeferGC&) 416 417 { 417 418 ASSERT(structure()->classInfo() == info()); -
trunk/Source/JavaScriptCore/runtime/StructureInlines.h
r154127 r157539 78 78 ASSERT(!isCompilationThread()); 79 79 ASSERT(structure()->classInfo() == info()); 80 materializePropertyMapIfNecessary(vm); 80 DeferGC deferGC(vm.heap); 81 materializePropertyMapIfNecessary(vm, deferGC); 81 82 if (!propertyTable()) 82 83 return invalidOffset; … … 90 91 ASSERT(!isCompilationThread()); 91 92 ASSERT(structure()->classInfo() == info()); 92 materializePropertyMapIfNecessary(vm); 93 DeferGC deferGC(vm.heap); 94 materializePropertyMapIfNecessary(vm, deferGC); 93 95 if (!propertyTable()) 94 96 return invalidOffset; -
trunk/Source/JavaScriptCore/runtime/SymbolTable.h
r156079 r157539 355 355 } 356 356 357 Map::iterator find(const GCSafeConcurrentJITLocker&, StringImpl* key) 358 { 359 return m_map.find(key); 360 } 361 357 362 SymbolTableEntry get(const ConcurrentJITLocker&, StringImpl* key) 358 363 { … … 383 388 384 389 Map::iterator end(const ConcurrentJITLocker&) 390 { 391 return m_map.end(); 392 } 393 394 Map::iterator end(const GCSafeConcurrentJITLocker&) 385 395 { 386 396 return m_map.end();
Note:
See TracChangeset
for help on using the changeset viewer.