Changeset 160656 in webkit
- Timestamp:
- Dec 16, 2013 12:46:39 PM (10 years ago)
- Location:
- branches/jsCStack/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/jsCStack/Source/JavaScriptCore/ChangeLog
r160610 r160656 1 2013-12-14 Mark Lam <mark.lam@apple.com> 2 3 Fix exception handling for the baseline JIT. 4 https://bugs.webkit.org/show_bug.cgi?id=125736. 5 6 Reviewed by Geoffrey Garen. 7 8 * interpreter/Interpreter.cpp: 9 (JSC::unwindCallFrame): 10 Removed some unneeded code. 11 1. Removed use of the oldCodeBlock variable which is only a copy of 12 the codeBlock variable. There is no longer any reason to use a copy. 13 Just use codeBlock directly instead. 14 2. There's no need to set VM::topCallFrame. The UnwindFunctor 15 automatically updates the incoming callFrame pointer reference to 16 the frame that should be catching / handling the exception, and that 17 is adequate for what we need. 18 19 * jit/JITOpcodes.cpp: 20 (JSC::JIT::emit_op_catch): 21 - Restored sp. 22 23 * jit/JITOpcodes32_64.cpp: 24 (JSC::JIT::privateCompileCTINativeCall): 25 (JSC::JIT::emit_op_catch): 26 * jit/ThunkGenerators.cpp: 27 (JSC::nativeForGenerator): 28 Fixed 2 issues: 29 1. After returning from a native / host function, the thunk did not pop 30 the native / host frame before executing exception handling code. 31 This resulted in the VM trying to "unwind" the native / host frame 32 which is not possible, and crashes ensue. 33 2. After returning from a native / host function and discovering the 34 need to handle an exception, the thunk was wrongly popping a 35 non-existant return address off the stack. This caused the 36 callerFrame pointer of the current frame to be popped off the stack, 37 and havoc ensues. 38 39 * llint/LowLevelInterpreter32_64.asm: 40 - Updated to match exception handling code in LowLevelInterpreter64.asm. 41 42 * runtime/VM.h: 43 - Removed dead code. 44 1 45 2013-12-14 Filip Pizlo <fpizlo@apple.com> 2 46 -
branches/jsCStack/Source/JavaScriptCore/interpreter/Interpreter.cpp
r160497 r160656 422 422 CallFrame* callFrame = visitor->callFrame(); 423 423 CodeBlock* codeBlock = visitor->codeBlock(); 424 CodeBlock* oldCodeBlock = codeBlock;425 424 JSScope* scope = callFrame->scope(); 426 425 … … 433 432 434 433 JSValue activation; 435 if ( oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsActivation()) {434 if (codeBlock->codeType() == FunctionCode && codeBlock->needsActivation()) { 436 435 #if ENABLE(DFG_JIT) 437 436 RELEASE_ASSERT(!visitor->isInlinedFrame()); 438 437 #endif 439 activation = callFrame->uncheckedR( oldCodeBlock->activationRegister().offset()).jsValue();438 activation = callFrame->uncheckedR(codeBlock->activationRegister().offset()).jsValue(); 440 439 if (activation) 441 440 jsCast<JSActivation*>(activation)->tearOff(*scope->vm()); 442 441 } 443 442 444 if ( oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->usesArguments()) {443 if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) { 445 444 if (Arguments* arguments = visitor->existingArguments()) { 446 445 if (activation) … … 456 455 457 456 CallFrame* callerFrame = callFrame->callerFrame(); 458 if (callerFrame->isVMEntrySentinel()) { 459 if (callerFrame->vmEntrySentinelCallerFrame()) 460 callFrame->vm().topCallFrame = callerFrame->vmEntrySentinelCallerFrame(); 461 else 462 callFrame->vm().topCallFrame = callFrame; // _handleUncaughtException will pop the frame off. 463 return false; 464 } 465 return true; 457 return !callerFrame->isVMEntrySentinel(); 466 458 } 467 459 -
branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes.cpp
r160499 r160656 39 39 #include "JSPropertyNameIterator.h" 40 40 #include "LinkBuffer.h" 41 #include "MaxFrameExtentForSlowPathCall.h" 41 42 #include "SlowPathCall.h" 42 43 #include "VirtualRegister.h" … … 636 637 move(TrustedImmPtr(m_vm), regT3); 637 638 load64(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister); 639 640 size_t frameExtent = JIT::frameRegisterCountFor(codeBlock()) * sizeof(Register) + maxFrameExtentForSlowPathCall; 641 ASSERT(frameExtent == WTF::roundUpToMultipleOf(stackAlignmentBytes(), frameExtent)); 642 addPtr(TrustedImm32(-frameExtent), callFrameRegister, stackPointerRegister); 643 638 644 load64(Address(regT3, VM::exceptionOffset()), regT0); 639 645 store64(TrustedImm64(JSValue::encode(JSValue())), Address(regT3, VM::exceptionOffset())); -
branches/jsCStack/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r160213 r160656 40 40 #include "JSVariableObject.h" 41 41 #include "LinkBuffer.h" 42 #include "MaxFrameExtentForSlowPathCall.h" 42 43 #include "SlowPathCall.h" 43 44 #include "VirtualRegister.h" … … 120 121 sawException.link(this); 121 122 122 // Grab the return address.123 preserveReturnAddressAfterCall(regT1);124 125 move(TrustedImmPtr(&vm->exceptionLocation), regT2);126 storePtr(regT1, regT2);127 123 storePtr(callFrameRegister, &m_vm->topCallFrame); 128 124 … … 928 924 // operationThrow returns the callFrame for the handler. 929 925 load32(Address(regT3, VM::callFrameForThrowOffset()), callFrameRegister); 926 927 size_t frameExtent = JIT::frameRegisterCountFor(codeBlock()) * sizeof(Register) + maxFrameExtentForSlowPathCall; 928 ASSERT(frameExtent == WTF::roundUpToMultipleOf(stackAlignmentBytes(), frameExtent)); 929 addPtr(TrustedImm32(-frameExtent), callFrameRegister, stackPointerRegister); 930 930 931 // Now store the exception returned by operationThrow. 931 932 load32(Address(regT3, VM::exceptionOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); -
branches/jsCStack/Source/JavaScriptCore/jit/ThunkGenerators.cpp
r160468 r160656 368 368 #endif 369 369 370 jit.emitFunctionEpilogue(); 371 370 372 // Check for an exception 371 373 #if USE(JSVALUE64) … … 380 382 381 383 // Return. 382 jit.emitFunctionEpilogue();383 384 jit.ret(); 384 385 385 386 // Handle an exception 386 387 exceptionHandler.link(&jit); 387 388 // Grab the return address.389 jit.preserveReturnAddressAfterCall(JSInterfaceJIT::regT1);390 391 jit.move(JSInterfaceJIT::TrustedImmPtr(&vm->exceptionLocation), JSInterfaceJIT::regT2);392 jit.storePtr(JSInterfaceJIT::regT1, JSInterfaceJIT::regT2);393 388 394 389 jit.storePtr(JSInterfaceJIT::callFrameRegister, &vm->topCallFrame); -
branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r160573 r160656 345 345 346 346 _handleUncaughtException: 347 loadp ScopeChain [cfr], t3347 loadp ScopeChain + PayloadOffset[cfr], t3 348 348 andp MarkedBlockMask, t3 349 349 loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3 … … 353 353 # We need to pop to the sentinel frame and do the necessary clean up for 354 354 # returning to the caller C frame. 355 loadp CallerFrame [cfr], cfr356 357 loadp Callee [cfr], t3 # VM.topCallFrame358 loadp ScopeChain [cfr], t6355 loadp CallerFrame + PayloadOffset[cfr], cfr 356 357 loadp Callee + PayloadOffset[cfr], t3 # VM.topCallFrame 358 loadp ScopeChain + PayloadOffset[cfr], t6 359 359 storep t6, [t3] 360 360 … … 2003 2003 # The throwing code must have known that we were throwing to the interpreter, 2004 2004 # and have set VM::targetInterpreterPCForThrow. 2005 loadp ScopeChain [cfr], t32005 loadp ScopeChain + PayloadOffset[cfr], t3 2006 2006 andp MarkedBlockMask, t3 2007 2007 loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3 2008 2008 loadp VM::callFrameForThrow[t3], cfr 2009 restoreStackPointerAfterCall() 2010 2009 2011 loadi VM::targetInterpreterPCForThrow[t3], PC 2010 2012 loadi VM::m_exception + PayloadOffset[t3], t0 -
branches/jsCStack/Source/JavaScriptCore/runtime/VM.h
r160591 r160656 382 382 const ClassInfo* const jsFinalObjectClassInfo; 383 383 384 ReturnAddressPtr exceptionLocation;385 384 JSValue hostCallReturnValue; 386 385 ExecState* newCallFrameReturnValue;
Note: See TracChangeset
for help on using the changeset viewer.