Changeset 164627 in webkit
- Timestamp:
- Feb 24, 2014 8:44:09 PM (10 years ago)
- Location:
- trunk/Source
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/APIShims.h
r164147 r164627 59 59 APIEntryShim(ExecState* exec, bool registerThread = true) 60 60 : APIEntryShimWithoutLock(&exec->vm(), registerThread) 61 , m_lockHolder( exec->vm().exclusiveThread ? 0 : exec)61 , m_lockHolder(&exec->vm()) 62 62 { 63 63 } … … 65 65 APIEntryShim(VM* vm, bool registerThread = true) 66 66 : APIEntryShimWithoutLock(vm, registerThread) 67 , m_lockHolder(vm ->exclusiveThread ? 0 : vm)67 , m_lockHolder(vm) 68 68 { 69 69 } … … 103 103 static bool shouldDropAllLocks(VM& vm) 104 104 { 105 if (vm.exclusiveThread)106 return false;107 108 105 // If the VM is in the middle of being destroyed then we don't want to resurrect it 109 106 // by allowing DropAllLocks to ref it. By this point the APILock has already been -
trunk/Source/JavaScriptCore/ChangeLog
r164620 r164627 1 2014-02-24 Mark Lam <mark.lam@apple.com> 2 3 Need to initialize VM stack data even when the VM is on an exclusive thread. 4 <https://webkit.org/b/129265> 5 6 Reviewed by Geoffrey Garen. 7 8 We check VM::exclusiveThread as an optimization to forego the need to do 9 JSLock locking. However, we recently started piggy backing on JSLock's 10 lock() and unlock() to initialize VM stack data (stackPointerAtVMEntry 11 and lastStackTop) to appropriate values for the current thread. This is 12 needed because we may be acquiring the lock to enter the VM on a different 13 thread. 14 15 As a result, we ended up not initializing the VM stack data when 16 VM::exclusiveThread causes us to bypass the locking activity. Even though 17 the VM::exclusiveThread will not have to deal with the VM being entered 18 on a different thread, it still needs to initialize the VM stack data. 19 The VM relies on that data being initialized properly once it has been 20 entered. 21 22 With this fix, we push the check for exclusiveThread down into the JSLock, 23 and handle the bypassing of unneeded locking activity there while still 24 executing the necessary the VM stack data initialization. 25 26 * API/APIShims.h: 27 (JSC::APIEntryShim::APIEntryShim): 28 (JSC::APICallbackShim::shouldDropAllLocks): 29 * heap/MachineStackMarker.cpp: 30 (JSC::MachineThreads::addCurrentThread): 31 * runtime/JSLock.cpp: 32 (JSC::JSLockHolder::JSLockHolder): 33 (JSC::JSLockHolder::init): 34 (JSC::JSLockHolder::~JSLockHolder): 35 (JSC::JSLock::JSLock): 36 (JSC::JSLock::setExclusiveThread): 37 (JSC::JSLock::lock): 38 (JSLock::unlock): 39 (JSLock::currentThreadIsHoldingLock): 40 (JSLock::dropAllLocks): 41 (JSLock::grabAllLocks): 42 * runtime/JSLock.h: 43 (JSC::JSLock::exclusiveThread): 44 * runtime/VM.cpp: 45 (JSC::VM::VM): 46 * runtime/VM.h: 47 (JSC::VM::exclusiveThread): 48 (JSC::VM::setExclusiveThread): 49 (JSC::VM::currentThreadIsHoldingAPILock): 50 1 51 2014-02-24 Filip Pizlo <fpizlo@apple.com> 2 52 -
trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp
r164500 r164627 183 183 void MachineThreads::addCurrentThread() 184 184 { 185 ASSERT(!m_heap->vm()-> exclusiveThread || m_heap->vm()->exclusiveThread == currentThread());185 ASSERT(!m_heap->vm()->hasExclusiveThread() || m_heap->vm()->exclusiveThread() == std::this_thread::get_id()); 186 186 187 187 if (!m_threadSpecific || threadSpecificGet(m_threadSpecific)) -
trunk/Source/JavaScriptCore/runtime/JSLock.cpp
r164484 r164627 51 51 52 52 JSLockHolder::JSLockHolder(ExecState* exec) 53 : m_vm( exec ? &exec->vm() : 0)53 : m_vm(&exec->vm()) 54 54 { 55 55 init(); … … 70 70 void JSLockHolder::init() 71 71 { 72 if (m_vm) 73 m_vm->apiLock().lock(); 72 m_vm->apiLock().lock(); 74 73 } 75 74 76 75 JSLockHolder::~JSLockHolder() 77 76 { 78 if (!m_vm)79 return;80 81 77 RefPtr<JSLock> apiLock(&m_vm->apiLock()); 82 78 m_vm.clear(); … … 85 81 86 82 JSLock::JSLock(VM* vm) 87 : m_lockCount(0) 83 : m_ownerThreadID(std::thread::id()) 84 , m_lockCount(0) 88 85 , m_lockDropDepth(0) 86 , m_hasExclusiveThread(false) 89 87 , m_vm(vm) 90 88 { … … 99 97 ASSERT_UNUSED(vm, m_vm == vm); 100 98 m_vm = 0; 99 } 100 101 void JSLock::setExclusiveThread(std::thread::id threadId) 102 { 103 RELEASE_ASSERT(!m_lockCount && m_ownerThreadID == std::thread::id()); 104 m_hasExclusiveThread = (threadId != std::thread::id()); 105 m_ownerThreadID = threadId; 101 106 } 102 107 … … 114 119 } 115 120 116 m_lock.lock(); 117 118 m_ownerThreadID = std::this_thread::get_id(); 121 if (!m_hasExclusiveThread) { 122 m_lock.lock(); 123 m_ownerThreadID = std::this_thread::get_id(); 124 } 119 125 ASSERT(!m_lockCount); 120 126 m_lockCount = lockCount; … … 122 128 if (!m_vm) 123 129 return; 124 125 WTFThreadData& threadData = wtfThreadData();126 130 127 131 RELEASE_ASSERT(!m_vm->stackPointerAtVMEntry()); … … 129 133 m_vm->setStackPointerAtVMEntry(p); 130 134 135 WTFThreadData& threadData = wtfThreadData(); 131 136 m_vm->setLastStackTop(threadData.savedLastStackTop()); 132 137 } … … 147 152 if (m_vm) 148 153 m_vm->setStackPointerAtVMEntry(nullptr); 149 m_ownerThreadID = std::thread::id(); 150 m_lock.unlock(); 154 155 if (!m_hasExclusiveThread) { 156 m_ownerThreadID = std::thread::id(); 157 m_lock.unlock(); 158 } 151 159 } 152 160 } … … 164 172 bool JSLock::currentThreadIsHoldingLock() 165 173 { 174 ASSERT(!m_hasExclusiveThread || (exclusiveThread() == std::this_thread::get_id())); 175 if (m_hasExclusiveThread) 176 return !!m_lockCount; 166 177 return m_ownerThreadID == std::this_thread::get_id(); 167 178 } … … 170 181 unsigned JSLock::dropAllLocks(DropAllLocks* dropper) 171 182 { 183 if (m_hasExclusiveThread) { 184 ASSERT(exclusiveThread() == std::this_thread::get_id()); 185 return 0; 186 } 187 172 188 // Check if this thread is currently holding the lock. 173 189 // FIXME: Maybe we want to require this, guard with an ASSERT? … … 194 210 void JSLock::grabAllLocks(DropAllLocks* dropper, unsigned droppedLockCount) 195 211 { 212 ASSERT(!m_hasExclusiveThread || !droppedLockCount); 213 196 214 // If no locks were dropped, nothing to do! 197 215 if (!droppedLockCount) -
trunk/Source/JavaScriptCore/runtime/JSLock.h
r164484 r164627 95 95 VM* vm() { return m_vm; } 96 96 97 bool hasExclusiveThread() const { return m_hasExclusiveThread; } 98 std::thread::id exclusiveThread() const 99 { 100 ASSERT(m_hasExclusiveThread); 101 return m_ownerThreadID; 102 } 103 JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id); 97 104 JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock(); 98 105 … … 130 137 intptr_t m_lockCount; 131 138 unsigned m_lockDropDepth; 139 bool m_hasExclusiveThread; 132 140 VM* m_vm; 133 141 }; -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r164347 r164627 209 209 , m_rtTraceList(new RTTraceList()) 210 210 #endif 211 , exclusiveThread(0)212 211 , m_newStringsSinceLastHashCons(0) 213 212 #if ENABLE(ASSEMBLER) -
trunk/Source/JavaScriptCore/runtime/VM.h
r164347 r164627 464 464 #endif 465 465 466 ThreadIdentifier exclusiveThread; 466 bool hasExclusiveThread() const { return m_apiLock->hasExclusiveThread(); } 467 std::thread::id exclusiveThread() const { return m_apiLock->exclusiveThread(); } 468 void setExclusiveThread(std::thread::id threadId) { m_apiLock->setExclusiveThread(threadId); } 467 469 468 470 JS_EXPORT_PRIVATE void resetDateCache(); … … 492 494 void resetNewStringsSinceLastHashCons() { m_newStringsSinceLastHashCons = 0; } 493 495 494 bool currentThreadIsHoldingAPILock() const 495 { 496 return m_apiLock->currentThreadIsHoldingLock() || exclusiveThread == currentThread(); 497 } 496 bool currentThreadIsHoldingAPILock() const { return m_apiLock->currentThreadIsHoldingLock(); } 498 497 499 498 JSLock& apiLock() { return *m_apiLock; } -
trunk/Source/WebCore/ChangeLog
r164624 r164627 1 2014-02-24 Mark Lam <mark.lam@apple.com> 2 3 Need to initialize VM stack data even when the VM is on an exclusive thread. 4 <https://webkit.org/b/129265> 5 6 Reviewed by Geoffrey Garen. 7 8 No new tests. 9 10 * bindings/js/JSDOMBinding.cpp: 11 (WebCore::reportException): 12 - Added an assertion to ensure that we are holding the JSLock. 13 * bindings/js/JSDOMWindowBase.cpp: 14 (WebCore::JSDOMWindowBase::commonVM): 15 - Updated to use the new VM::setExclusiveThread(). 16 1 17 2014-02-24 Anders Carlsson <andersca@apple.com> 2 18 -
trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp
r164554 r164627 154 154 void reportException(ExecState* exec, JSValue exception, CachedScript* cachedScript) 155 155 { 156 RELEASE_ASSERT(exec->vm().currentThreadIsHoldingAPILock()); 156 157 if (isTerminatedExecutionException(exception)) 157 158 return; -
trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp
r164347 r164627 225 225 vm->heap.machineThreads().addCurrentThread(); 226 226 #else 227 vm-> exclusiveThread = currentThread();227 vm->setExclusiveThread(std::this_thread::get_id()); 228 228 #endif // !PLATFORM(IOS) 229 229 initNormalWorldClientData(vm);
Note: See TracChangeset
for help on using the changeset viewer.