Changeset 153218 in webkit for trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
- Timestamp:
- Jul 24, 2013, 9:02:28 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r153216 r153218 64 64 #include "Register.h" 65 65 #include "SamplingTool.h" 66 #include "StackIterator.h" 66 67 #include "StrictEvalActivation.h" 67 68 #include "StrongInlines.h" … … 100 101 m_interpreter.stack().disableErrorStackReserve(); 101 102 } 102 103 static CallFrame* getCallerInfo(VM*, CallFrame*, unsigned& bytecodeOffset, CodeBlock*& callerOut);104 103 105 104 // Returns the depth of the scope chain within a given call frame. … … 322 321 dataLogF("[ReturnJITPC] | %10p | %p \n", it, pc.jitReturnAddress().value()); 323 322 #endif 324 unsigned bytecodeOffset = 0; 325 int line = 0; 326 CodeBlock* callerCodeBlock = 0; 327 getCallerInfo(&callFrame->vm(), callFrame, bytecodeOffset, callerCodeBlock); 328 line = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset); 329 dataLogF("[ReturnVPC] | %10p | %d (line %d)\n", it, bytecodeOffset, line); 330 ++it; 323 StackIterator iter = callFrame->begin(); 324 ++iter; 325 if (iter != callFrame->end()) { 326 unsigned line = 0; 327 unsigned unusedColumn = 0; 328 iter->computeLineAndColumn(line, unusedColumn); 329 dataLogF("[ReturnVPC] | %10p | %d (line %d)\n", it, iter->bytecodeOffset(), line); 330 ++it; 331 } 331 332 dataLogF("[CodeBlock] | %10p | %p \n", it, callFrame->codeBlock()); 332 333 ++it; … … 377 378 } 378 379 379 NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock) 380 { 380 NEVER_INLINE bool Interpreter::unwindCallFrame(StackIterator& iter, JSValue exceptionValue) 381 { 382 CallFrame* callFrame = iter->callFrame(); 383 CodeBlock* codeBlock = iter->codeBlock(); 381 384 CodeBlock* oldCodeBlock = codeBlock; 382 385 JSScope* scope = callFrame->scope(); … … 408 411 CallFrame* callerFrame = callFrame->callerFrame(); 409 412 callFrame->vm().topCallFrame = callerFrame; 410 if (callerFrame->hasHostCallFrameFlag()) 411 return false; 412 callFrame = getCallerInfo(&callFrame->vm(), callFrame, bytecodeOffset, codeBlock); 413 return true; 413 return !callerFrame->hasHostCallFrameFlag(); 414 414 } 415 415 … … 468 468 } 469 469 470 static unsigned getBytecodeOffsetForCallFrame(CallFrame* callFrame)471 {472 callFrame = callFrame->removeHostCallFrameFlag();473 CodeBlock* codeBlock = callFrame->codeBlock();474 if (!codeBlock)475 return 0;476 #if ENABLE(DFG_JIT)477 if (JITCode::isOptimizingJIT(codeBlock->jitType()))478 return codeBlock->codeOrigin(callFrame->locationAsCodeOriginIndex()).bytecodeIndex;479 #endif480 return callFrame->locationAsBytecodeOffset();481 }482 483 static CallFrame* getCallerInfo(VM* vm, CallFrame* callFrame, unsigned& bytecodeOffset, CodeBlock*& caller)484 {485 ASSERT_UNUSED(vm, vm);486 bytecodeOffset = 0;487 ASSERT(!callFrame->hasHostCallFrameFlag());488 CallFrame* trueCallerFrame = callFrame->trueCallerFrame();489 ASSERT(!trueCallerFrame->hasHostCallFrameFlag());490 491 if (trueCallerFrame == CallFrame::noCaller() || !trueCallerFrame || !trueCallerFrame->codeBlock()) {492 caller = 0;493 return trueCallerFrame;494 }495 496 CodeBlock* callerCodeBlock = trueCallerFrame->codeBlock();497 #if ENABLE(DFG_JIT)498 if (trueCallerFrame->hasLocationAsCodeOriginIndex())499 bytecodeOffset = trueCallerFrame->bytecodeOffsetFromCodeOriginIndex();500 else501 #endif // ENABLE(DFG_JIT)502 bytecodeOffset = trueCallerFrame->locationAsBytecodeOffset();503 504 caller = callerCodeBlock;505 return trueCallerFrame;506 }507 508 470 static ALWAYS_INLINE const String getSourceURLFromCallFrame(CallFrame* callFrame) 509 471 { … … 512 474 } 513 475 514 static StackFrameCodeType getStackFrameCodeType(CallFrame* callFrame) 515 { 516 ASSERT(!callFrame->hasHostCallFrameFlag()); 517 518 switch (callFrame->codeBlock()->codeType()) { 519 case EvalCode: 476 static StackFrameCodeType getStackFrameCodeType(StackIterator iter) 477 { 478 switch (iter->codeType()) { 479 case StackIterator::Frame::Eval: 520 480 return StackFrameEvalCode; 521 case FunctionCode:481 case StackIterator::Frame::Function: 522 482 return StackFrameFunctionCode; 523 case GlobalCode:483 case StackIterator::Frame::Global: 524 484 return StackFrameGlobalCode; 485 case StackIterator::Frame::Native: 486 ASSERT_NOT_REACHED(); 487 return StackFrameNativeCode; 525 488 } 526 489 RELEASE_ASSERT_NOT_REACHED(); … … 577 540 } 578 541 579 void Interpreter::getStackTrace(VM* vm, Vector<StackFrame>& results, size_t maxStackSize) 580 { 581 CallFrame* callFrame = vm->topCallFrame->removeHostCallFrameFlag(); 582 if (!callFrame || callFrame == CallFrame::noCaller()) 583 return; 584 unsigned bytecodeOffset = getBytecodeOffsetForCallFrame(callFrame); 585 callFrame = callFrame->trueCallFrame(); 542 void Interpreter::getStackTrace(Vector<StackFrame>& results, size_t maxStackSize) 543 { 544 VM& vm = m_vm; 545 CallFrame* callFrame = vm.topCallFrame->removeHostCallFrameFlag(); 586 546 if (!callFrame) 587 547 return; 588 CodeBlock* callerCodeBlock = callFrame->codeBlock(); 589 590 while (callFrame && callFrame != CallFrame::noCaller() && maxStackSize--) { 591 String sourceURL; 592 if (callerCodeBlock) { 593 sourceURL = getSourceURLFromCallFrame(callFrame); 548 StackIterator iter = callFrame->begin(); 549 for (; iter != callFrame->end() && maxStackSize--; ++iter) { 550 if (iter->isJSFrame()) { 551 CodeBlock* codeBlock = iter->codeBlock(); 594 552 StackFrame s = { 595 Strong<JSObject>( *vm, callFrame->callee()),596 getStackFrameCodeType( callFrame),597 Strong<ExecutableBase>( *vm, callerCodeBlock->ownerExecutable()),598 Strong<UnlinkedCodeBlock>( *vm, callerCodeBlock->unlinkedCodeBlock()),599 c allerCodeBlock->source(),600 c allerCodeBlock->ownerExecutable()->lineNo(),601 c allerCodeBlock->firstLineColumnOffset(),602 c allerCodeBlock->sourceOffset(),603 bytecodeOffset,604 sourceURL553 Strong<JSObject>(vm, iter->callee()), 554 getStackFrameCodeType(iter), 555 Strong<ExecutableBase>(vm, codeBlock->ownerExecutable()), 556 Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()), 557 codeBlock->source(), 558 codeBlock->ownerExecutable()->lineNo(), 559 codeBlock->firstLineColumnOffset(), 560 codeBlock->sourceOffset(), 561 iter->bytecodeOffset(), 562 iter->sourceURL() 605 563 }; 606 607 564 results.append(s); 608 565 } else { 609 StackFrame s = { Strong<JSObject>( *vm, callFrame->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};566 StackFrame s = { Strong<JSObject>(vm, iter->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()}; 610 567 results.append(s); 611 568 } 612 callFrame = getCallerInfo(vm, callFrame, bytecodeOffset, callerCodeBlock);613 569 } 614 570 } … … 625 581 626 582 Vector<StackFrame> stackTrace; 627 getStackTrace(&callFrame->vm(),stackTrace);583 vm->interpreter->getStackTrace(stackTrace); 628 584 vm->exceptionStack() = RefCountedArray<StackFrame>(stackTrace); 629 585 if (stackTrace.isEmpty() || !error.isObject()) … … 677 633 if (!callFrame->vm().exceptionStack().size()) { 678 634 Vector<StackFrame> stack; 679 Interpreter::getStackTrace(&callFrame->vm(),stack);635 callFrame->vm().interpreter->getStackTrace(stack); 680 636 callFrame->vm().exceptionStack() = RefCountedArray<StackFrame>(stack); 681 637 } … … 690 646 // Calculate an exception handler vPC, unwinding call frames as necessary. 691 647 HandlerInfo* handler = 0; 692 while (isTermination || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) { 693 if (!unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) { 694 if (LegacyProfiler* profiler = callFrame->vm().enabledProfiler()) 695 profiler->exceptionUnwind(callFrame); 696 return 0; 697 } 648 VM& vm = callFrame->vm(); 649 ASSERT(callFrame == vm.topCallFrame); 650 for (StackIterator iter = callFrame->begin(); iter != callFrame->end(); ++iter) { 651 callFrame = iter->callFrame(); 652 codeBlock = iter->codeBlock(); 653 bytecodeOffset = iter->bytecodeOffset(); 654 655 if (isTermination || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) { 656 if (!unwindCallFrame(iter, exceptionValue)) { 657 if (LegacyProfiler* profiler = vm.enabledProfiler()) 658 profiler->exceptionUnwind(callFrame); 659 return 0; 660 } 661 } else 662 break; 698 663 } 699 664 … … 1288 1253 return; 1289 1254 } 1290 } 1291 1292 JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const 1293 { 1294 CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function); 1295 if (!functionCallFrame) 1296 return jsNull(); 1297 1298 Arguments* arguments = Arguments::create(functionCallFrame->vm(), functionCallFrame); 1299 arguments->tearOff(functionCallFrame); 1300 return JSValue(arguments); 1301 } 1302 1303 JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction* function) const 1304 { 1305 CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function); 1306 1307 if (!functionCallFrame) 1308 return jsNull(); 1309 1310 unsigned bytecodeOffset; 1311 CodeBlock* unusedCallerCodeBlock = 0; 1312 CallFrame* callerFrame = getCallerInfo(&callFrame->vm(), functionCallFrame, bytecodeOffset, unusedCallerCodeBlock); 1313 if (!callerFrame) 1314 return jsNull(); 1315 JSValue caller = callerFrame->callee(); 1316 if (!caller) 1317 return jsNull(); 1318 1319 // Skip over function bindings. 1320 ASSERT(caller.isObject()); 1321 while (asObject(caller)->inherits(&JSBoundFunction::s_info)) { 1322 callerFrame = getCallerInfo(&callFrame->vm(), callerFrame, bytecodeOffset, unusedCallerCodeBlock); 1323 if (!callerFrame) 1324 return jsNull(); 1325 caller = callerFrame->callee(); 1326 if (!caller) 1327 return jsNull(); 1328 } 1329 1330 return caller; 1331 } 1332 1333 CallFrame* Interpreter::findFunctionCallFrameFromVMCode(CallFrame* callFrame, JSFunction* function) 1334 { 1335 for (CallFrame* candidate = callFrame->trueCallFrame(); candidate; candidate = candidate->trueCallerFrame()) { 1336 if (candidate->callee() == function) 1337 return candidate; 1338 } 1339 return 0; 1340 } 1255 } 1341 1256 1342 1257 void Interpreter::enableSampler()
Note:
See TracChangeset
for help on using the changeset viewer.