Changeset 228488 in webkit
- Timestamp:
- Feb 14, 2018 3:25:52 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r228474 r228488 1 2018-02-14 Saam Barati <sbarati@apple.com> 2 3 Setting a VMTrap shouldn't look at topCallFrame since that may imply we're in C code and holding the malloc lock 4 https://bugs.webkit.org/show_bug.cgi?id=182801 5 6 Reviewed by Keith Miller. 7 8 * stress/watchdog-dont-malloc-when-in-c-code.js: Added. 9 1 10 2018-02-14 Ryan Haddad <ryanhaddad@apple.com> 2 11 -
trunk/Source/JavaScriptCore/ChangeLog
r228481 r228488 1 2018-02-14 Saam Barati <sbarati@apple.com> 2 3 Setting a VMTrap shouldn't look at topCallFrame since that may imply we're in C code and holding the malloc lock 4 https://bugs.webkit.org/show_bug.cgi?id=182801 5 6 Reviewed by Keith Miller. 7 8 VMTraps would sometimes install traps when it paused the JS thread when it 9 was in C code. This is wrong, as installing traps mallocs, and the JS thread 10 may have been holding the malloc lock while in C code. This could lead to a 11 deadlock when C code was holding the malloc lock. 12 13 This patch makes it so that we only install traps when we've proven the PC 14 is in JIT or LLInt code. If we're in JIT/LLInt code, we are guaranteed that 15 we're not holding the malloc lock. 16 17 * jsc.cpp: 18 (GlobalObject::finishCreation): 19 (functionMallocInALoop): 20 * runtime/VMTraps.cpp: 21 (JSC::VMTraps::tryInstallTrapBreakpoints): 22 1 23 2018-02-14 Michael Saboff <msaboff@apple.com> 2 24 -
trunk/Source/JavaScriptCore/jsc.cpp
r227898 r228488 343 343 static EncodedJSValue JSC_HOST_CALL functionFlashHeapAccess(ExecState*); 344 344 static EncodedJSValue JSC_HOST_CALL functionDisableRichSourceInfo(ExecState*); 345 static EncodedJSValue JSC_HOST_CALL functionMallocInALoop(ExecState*); 345 346 346 347 struct Script { … … 600 601 601 602 addFunction(vm, "disableRichSourceInfo", functionDisableRichSourceInfo, 0); 603 addFunction(vm, "mallocInALoop", functionMallocInALoop, 0); 602 604 } 603 605 … … 1749 1751 } 1750 1752 1753 EncodedJSValue JSC_HOST_CALL functionMallocInALoop(ExecState*) 1754 { 1755 Vector<void*> ptrs; 1756 for (unsigned i = 0; i < 5000; ++i) 1757 ptrs.append(fastMalloc(1024 * 2)); 1758 for (void* ptr : ptrs) 1759 fastFree(ptr); 1760 return JSValue::encode(jsUndefined()); 1761 } 1762 1751 1763 template<typename ValueType> 1752 1764 typename std::enable_if<!std::is_fundamental<ValueType>::value>::type addOption(VM&, JSObject*, Identifier, ValueType) { } -
trunk/Source/JavaScriptCore/runtime/VMTraps.cpp
r226783 r228488 73 73 } 74 74 75 inline CallFrame* sanitizedTopCallFrame(CallFrame* topCallFrame)76 {77 #if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS)78 // prepareForExternalCall() in DFGSpeculativeJIT.h may set topCallFrame to a bad word79 // before calling native functions, but tryInstallTrapBreakpoints() below expects80 // topCallFrame to be null if not set.81 #if USE(JSVALUE64)82 const uintptr_t badBeefWord = 0xbadbeef0badbeef;83 #else84 const uintptr_t badBeefWord = 0xbadbeef;85 #endif86 if (topCallFrame == reinterpret_cast<CallFrame*>(badBeefWord))87 topCallFrame = nullptr;88 #endif89 return topCallFrame;90 }91 92 75 static bool isSaneFrame(CallFrame* frame, CallFrame* calleeFrame, EntryFrame* entryFrame, StackBounds stackBounds) 93 76 { … … 105 88 VM& vm = this->vm(); 106 89 void* trapPC = context.trapPC; 90 // We must ensure we're in JIT/LLint code. If we are, we know a few things: 91 // - The JS thread isn't holding the malloc lock. Therefore, it's safe to malloc below. 92 // - The JS thread isn't holding the CodeBlockSet lock. 93 // If we're not in JIT/LLInt code, we can't run the C++ code below because it 94 // mallocs, and we must prove the JS thread isn't holding the malloc lock 95 // to be able to do that without risking a deadlock. 96 if (!isJITPC(trapPC) && !LLInt::isLLIntPC(trapPC)) 97 return; 107 98 108 99 CallFrame* callFrame = reinterpret_cast<CallFrame*>(context.framePointer); 109 100 110 auto& lock = vm.heap.codeBlockSet().getLock(); 111 // If the target thread is in C++ code it might be holding the codeBlockSet lock. 112 // if it's in JIT code then it cannot be holding that lock but the GC might be. 113 auto codeBlockSetLocker = isJITPC(trapPC) ? holdLock(lock) : tryHoldLock(lock); 114 if (!codeBlockSetLocker) 115 return; // Let the SignalSender try again later. 116 117 if (!isJITPC(trapPC) && !LLInt::isLLIntPC(trapPC)) { 118 // We resort to topCallFrame to see if we can get anything 119 // useful. We usually get here when we're executing C code. 120 callFrame = sanitizedTopCallFrame(vm.topCallFrame); 121 } 101 auto codeBlockSetLocker = holdLock(vm.heap.codeBlockSet().getLock()); 122 102 123 103 CodeBlock* foundCodeBlock = nullptr;
Note: See TracChangeset
for help on using the changeset viewer.