Changeset 239244 in webkit
- Timestamp:
- Dec 14, 2018 6:28:17 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r239231 r239244 1 2018-12-14 Mark Lam <mark.lam@apple.com> 2 3 CallFrame::convertToStackOverflowFrame() needs to keep the top CodeBlock alive. 4 https://bugs.webkit.org/show_bug.cgi?id=192717 5 <rdar://problem/46660677> 6 7 Reviewed by Saam Barati. 8 9 * stress/regress-192717.js: Added. 10 1 11 2018-12-14 Commit Queue <commit-queue@webkit.org> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r239237 r239244 1 2018-12-14 Mark Lam <mark.lam@apple.com> 2 3 CallFrame::convertToStackOverflowFrame() needs to keep the top CodeBlock alive. 4 https://bugs.webkit.org/show_bug.cgi?id=192717 5 <rdar://problem/46660677> 6 7 Reviewed by Saam Barati. 8 9 When throwing a StackOverflowError, we convert the topCallFrame into a 10 StackOverflowFrame. Previously, we would nullify the codeBlock field in the frame 11 because a StackOverflowFrame is only a sentinel and doesn't really correspond to 12 any CodeBlocks. However, this is a problem because the topCallFrame may be the 13 only remaining place that references the CodeBlock that the stack overflow is 14 triggered in. The way we handle exceptions in JIT code is to return (from the 15 runtime operation function throwing the exception) to the JIT code to check for 16 the exception and if needed, do some clean up before jumping to the exception 17 handling thunk. As a result, we need to keep that JIT code alive, which means we 18 need to keep its CodeBlock alive. We only need to keep this CodeBlock alive until 19 we've unwound (in terms of exception handling) out of it. 20 21 We fix this issue by storing the CodeBlock to keep alive in the StackOverflowFrame 22 for the GC to scan while the frame is still on the stack. 23 24 We removed the call to convertToStackOverflowFrame() in 25 lookupExceptionHandlerFromCallerFrame() because it is redundant. 26 lookupExceptionHandlerFromCallerFrame() will only every be called after 27 a StackOverFlowError has been thrown. Hence, the top frame is already 28 guaranteed to be a StackOverflowFrame, and there should always be a 29 StackOverFlowError exception pending. We added assertions for these 30 instead. 31 32 * interpreter/CallFrame.cpp: 33 (JSC::CallFrame::convertToStackOverflowFrame): 34 * interpreter/CallFrame.h: 35 * jit/JITOperations.cpp: 36 * llint/LLIntSlowPaths.cpp: 37 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 38 * runtime/CommonSlowPaths.cpp: 39 (JSC::SLOW_PATH_DECL): 40 * runtime/CommonSlowPaths.h: 41 (JSC::CommonSlowPaths::codeBlockFromCallFrameCallee): 42 (JSC::CommonSlowPaths::arityCheckFor): 43 * runtime/VM.h: 44 (JSC::VM::exceptionForInspection const): 45 1 46 2018-12-14 David Kilzer <ddkilzer@apple.com> 2 47 -
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r237547 r239244 338 338 } 339 339 340 void CallFrame::convertToStackOverflowFrame(VM& vm )340 void CallFrame::convertToStackOverflowFrame(VM& vm, CodeBlock* codeBlockToKeepAliveUntilFrameIsUnwound) 341 341 { 342 342 ASSERT(!isGlobalExec()); 343 ASSERT(codeBlockToKeepAliveUntilFrameIsUnwound->inherits<CodeBlock>(vm)); 343 344 344 345 EntryFrame* entryFrame = vm.topEntryFrame; … … 351 352 JSObject* stackOverflowCallee = originCallee->globalObject()->stackOverflowFrameCallee(); 352 353 353 setCodeBlock( nullptr);354 setCodeBlock(codeBlockToKeepAliveUntilFrameIsUnwound); 354 355 setCallee(stackOverflowCallee); 355 356 setArgumentCountIncludingThis(0); -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r237547 r239244 258 258 } 259 259 260 void convertToStackOverflowFrame(VM& );260 void convertToStackOverflowFrame(VM&, CodeBlock* codeBlockToKeepAliveUntilFrameIsUnwound); 261 261 inline bool isStackOverflowFrame() const; 262 262 inline bool isWasmFrame() const; -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r238425 r239244 103 103 VM* vm = codeBlock->vm(); 104 104 auto scope = DECLARE_THROW_SCOPE(*vm); 105 exec->convertToStackOverflowFrame(*vm );105 exec->convertToStackOverflowFrame(*vm, codeBlock); 106 106 NativeCallFrameTracer tracer(vm, exec); 107 107 throwStackOverflowError(exec, scope); … … 114 114 115 115 int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, *vm, CodeForCall); 116 if (missingArgCount < 0) { 117 exec->convertToStackOverflowFrame(*vm); 116 if (UNLIKELY(missingArgCount < 0)) { 117 CodeBlock* codeBlock = CommonSlowPaths::codeBlockFromCallFrameCallee(exec, CodeForCall); 118 exec->convertToStackOverflowFrame(*vm, codeBlock); 118 119 NativeCallFrameTracer tracer(vm, exec); 119 120 throwStackOverflowError(vm->topCallFrame, scope); … … 129 130 130 131 int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, *vm, CodeForConstruct); 131 if (missingArgCount < 0) { 132 exec->convertToStackOverflowFrame(*vm); 132 if (UNLIKELY(missingArgCount < 0)) { 133 CodeBlock* codeBlock = CommonSlowPaths::codeBlockFromCallFrameCallee(exec, CodeForCall); 134 exec->convertToStackOverflowFrame(*vm, codeBlock); 133 135 NativeCallFrameTracer tracer(vm, exec); 134 136 throwStackOverflowError(vm->topCallFrame, scope); … … 2433 2435 void JIT_OPERATION lookupExceptionHandlerFromCallerFrame(VM* vm, ExecState* exec) 2434 2436 { 2435 exec->convertToStackOverflowFrame(*vm); 2437 ASSERT(exec->isStackOverflowFrame()); 2438 ASSERT(jsCast<ErrorInstance*>(vm->exceptionForInspection()->value().asCell())->isStackOverflowError()); 2436 2439 lookupExceptionHandler(vm, exec); 2437 2440 } -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r238141 r239244 560 560 #endif 561 561 562 exec->convertToStackOverflowFrame(vm );562 exec->convertToStackOverflowFrame(vm, codeBlock); 563 563 ErrorHandlingScope errorScope(vm); 564 564 throwStackOverflowError(exec, throwScope); -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
r238790 r239244 178 178 BEGIN(); 179 179 int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, vm, CodeForCall); 180 if (slotsToAdd < 0) { 181 exec->convertToStackOverflowFrame(vm); 180 if (UNLIKELY(slotsToAdd < 0)) { 181 CodeBlock* codeBlock = CommonSlowPaths::codeBlockFromCallFrameCallee(exec, CodeForCall); 182 exec->convertToStackOverflowFrame(vm, codeBlock); 182 183 NativeCallFrameTracer tracer(&vm, exec); 183 184 ErrorHandlingScope errorScope(vm); … … 193 194 BEGIN(); 194 195 int slotsToAdd = CommonSlowPaths::arityCheckFor(exec, vm, CodeForConstruct); 195 if (slotsToAdd < 0) { 196 exec->convertToStackOverflowFrame(vm); 196 if (UNLIKELY(slotsToAdd < 0)) { 197 CodeBlock* codeBlock = CommonSlowPaths::codeBlockFromCallFrameCallee(exec, CodeForCall); 198 exec->convertToStackOverflowFrame(vm, codeBlock); 197 199 NativeCallFrameTracer tracer(&vm, exec); 198 200 ErrorHandlingScope errorScope(vm); -
trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h
r238543 r239244 73 73 } 74 74 75 ALWAYS_INLINE int arityCheckFor(ExecState* exec, VM& vm, CodeSpecializationKind kind)75 ALWAYS_INLINE CodeBlock* codeBlockFromCallFrameCallee(ExecState* exec, CodeSpecializationKind kind) 76 76 { 77 77 JSFunction* callee = jsCast<JSFunction*>(exec->jsCallee()); 78 78 ASSERT(!callee->isHostFunction()); 79 CodeBlock* newCodeBlock = callee->jsExecutable()->codeBlockFor(kind); 79 return callee->jsExecutable()->codeBlockFor(kind); 80 } 81 82 ALWAYS_INLINE int arityCheckFor(ExecState* exec, VM& vm, CodeSpecializationKind kind) 83 { 84 CodeBlock* newCodeBlock = codeBlockFromCallFrameCallee(exec, kind); 80 85 ASSERT(exec->argumentCountIncludingThis() < static_cast<unsigned>(newCodeBlock->numParameters())); 81 86 int padding = numberOfStackPaddingSlotsWithExtraSlots(newCodeBlock, exec->argumentCountIncludingThis()); -
trunk/Source/JavaScriptCore/runtime/VM.h
r239231 r239244 694 694 JSCell** addressOfLastException() { return reinterpret_cast<JSCell**>(&m_lastException); } 695 695 696 // This should only be used for test or assertion code that wants to inspect 697 // the pending exception without interfering with Throw/CatchScopes. 698 Exception* exceptionForInspection() const { return m_exception; } 699 696 700 void setFailNextNewCodeBlock() { m_failNextNewCodeBlock = true; } 697 701 bool getAndClearFailNextNewCodeBlock()
Note: See TracChangeset
for help on using the changeset viewer.