Changeset 34085 in webkit for trunk/JavaScriptCore
- Timestamp:
- May 23, 2008, 10:50:51 AM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r34080 r34085 1 2008-05-23 Geoffrey Garen <[email protected]> 2 3 Reviewed by Darin Adler, Kevin McCullough, and Oliver Hunt. 4 5 Fixed <rdar://problem/5959447> Crashes and incorrect reporting in the 6 JavaScript profiler 7 8 * VM/Machine.cpp: 9 (KJS::callEval): Made this profiler hooks slightly faster by passing in 10 the eval function. 11 12 (KJS::Machine::unwindCallFrame): Fixed incorrect reporting / a crash 13 when unwinding from inside eval and/or program code: detect the 14 difference, and do the right thing. Also, be sure to notify the profiler 15 *before* deref'ing the scope chain, since the profiler uses the scope chain. 16 17 (KJS::Machine::execute): Fixed incorrect reporting / crash when calling 18 a JS function re-entrently: Machine::execute(FunctionBodyNode*...) 19 should not invoke the didExecute hook, because op_ret already does that. 20 Also, use the new function's ExecState when calling out to the profiler. 21 (Not important now, but could have become a subtle bug later.) 22 23 (KJS::Machine::privateExecute): Fixed a hard to reproduce crash when 24 profiling JS functions: notify the profiler *before* deref'ing the scope 25 chain, since the profiler uses the scope chain. 26 27 * kjs/object.cpp: 28 (KJS::JSObject::call): Removed these hooks, because they are now unnecessary. 29 30 * profiler/Profile.cpp: Added a comment to explain a subtlety that only 31 Kevin and I understood previously. (Now, the whole world can understand!) 32 33 * profiler/Profiler.cpp: 34 (KJS::shouldExcludeFunction): Don't exclude .call and .apply. That was 35 a hack to fix bugs that no longer exist. 36 37 Finally, sped things up a little bit by changing the "Is the profiler 38 running?" check into an ASSERT, since we only call into the profiler 39 when it's running: 40 41 (KJS::Profiler::willExecute): 42 (KJS::Profiler::didExecute): 43 1 44 2008-05-23 Adam Roben <[email protected]> 2 45 -
trunk/JavaScriptCore/VM/Machine.cpp
r34075 r34085 438 438 } 439 439 440 static NEVER_INLINE JSValue* callEval(ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, Register* r, int argv, int argc, JSValue*& exceptionValue)440 static NEVER_INLINE JSValue* callEval(ExecState* exec, JSObject* thisObj, JSObject* evalFunction, ScopeChainNode* scopeChain, RegisterFile* registerFile, Register* r, int argv, int argc, JSValue*& exceptionValue) 441 441 { 442 442 Profiler** profiler = Profiler::enabledProfilerReference(); 443 JSObject* evalFunction = scopeChain->globalObject()->evalFunction();444 443 if (*profiler) 445 444 (*profiler)->willExecute(exec, evalFunction); … … 577 576 } 578 577 578 Register* callFrame = r - oldCodeBlock->numLocals - CallFrameHeaderSize; 579 580 if (Profiler* profiler = *Profiler::enabledProfilerReference()) { 581 if (!isGlobalCallFrame(registerBase, r) && callFrame[Callee].u.jsObject) // Check for global and eval code 582 profiler->didExecute(exec, callFrame[Callee].u.jsObject); 583 else 584 profiler->didExecute(exec, codeBlock->ownerNode->sourceURL(), codeBlock->ownerNode->lineNo()); 585 } 586 579 587 if (oldCodeBlock->needsFullScopeChain) 580 588 scopeChain->deref(); … … 583 591 return false; 584 592 585 Register* callFrame = r - oldCodeBlock->numLocals - CallFrameHeaderSize;586 587 593 codeBlock = callFrame[CallerCodeBlock].u.codeBlock; 588 594 if (!codeBlock) … … 602 608 vPC = callFrame[ReturnVPC].u.vPC; 603 609 604 if (Profiler* profiler = *Profiler::enabledProfilerReference())605 profiler->didExecute(exec, callFrame[Callee].u.jsObject);606 610 return true; 607 611 } … … 669 673 scopeChain = scopeChain->copy(); 670 674 675 ExecState newExec(exec, this, registerFile, scopeChain, -1); 676 671 677 Profiler** profiler = Profiler::enabledProfilerReference(); 672 678 if (*profiler) 673 679 (*profiler)->willExecute(exec, programNode->sourceURL(), programNode->lineNo()); 674 675 ExecState newExec(exec, this, registerFile, scopeChain, -1);676 680 677 681 m_reentryDepth++; … … 739 743 JSValue* result = privateExecute(Normal, &newExec, registerFile, r, scopeChain, newCodeBlock, exception); 740 744 m_reentryDepth--; 741 742 if (*profiler)743 (*profiler)->didExecute(exec, function);744 745 745 746 registerFile->shrink(oldSize); … … 1865 1866 registerFile->setSafeForReentry(true); 1866 1867 1867 JSValue* result = callEval(exec, thisObject, s copeChain, registerFile, r, argv, argc, exceptionValue);1868 JSValue* result = callEval(exec, thisObject, static_cast<JSObject*>(funcVal), scopeChain, registerFile, r, argv, argc, exceptionValue); 1868 1869 1869 1870 registerFile->setSafeForReentry(false); … … 1975 1976 activation->copyRegisters(); 1976 1977 } 1978 1979 if (*enabledProfilerReference) 1980 (*enabledProfilerReference)->didExecute(exec, callFrame[Callee].u.jsObject); 1977 1981 1978 1982 if (codeBlock->needsFullScopeChain) … … 1996 2000 int r0 = callFrame[ReturnValueRegister].u.i; 1997 2001 r[r0].u.jsValue = returnValue; 1998 1999 if (*enabledProfilerReference)2000 (*enabledProfilerReference)->didExecute(exec, callFrame[Callee].u.jsObject);2001 2002 2002 2003 NEXT_OPCODE; -
trunk/JavaScriptCore/kjs/object.cpp
r34074 r34085 92 92 } 93 93 #endif 94 CallData data; 95 JSValue *ret; 96 if (this->getCallData(data) == CallTypeJS) { 97 // A native function will enter the VM, which will allow the profiler 98 // to detect entry 99 ret = callAsFunction(exec,thisObj,args); 100 } else { 101 Profiler** profiler = Profiler::enabledProfilerReference(); 102 if (*profiler) 103 (*profiler)->willExecute(exec, this); 104 105 ret = callAsFunction(exec,thisObj,args); 106 107 if (*profiler) 108 (*profiler)->didExecute(exec, this); 109 } 94 JSValue* ret = callAsFunction(exec,thisObj,args); 95 110 96 #if KJS_MAX_STACK > 0 111 97 --depth; -
trunk/JavaScriptCore/profiler/Profile.cpp
r34060 r34085 57 57 { 58 58 ASSERT(m_currentNode); 59 60 59 m_currentNode = m_currentNode->willExecute(callIdentifier); 61 60 } … … 63 62 void Profile::didExecute(const CallIdentifier& callIdentifier) 64 63 { 64 ASSERT(m_currentNode); 65 66 // In case the profiler started recording calls in the middle of a stack frame, 67 // when returning up the stack it needs to insert the calls it missed on the 68 // way down. 65 69 if (m_currentNode == m_headNode) { 66 70 m_currentNode = ProfileNode::create(callIdentifier, m_headNode.get(), m_headNode.get()); -
trunk/JavaScriptCore/profiler/Profiler.cpp
r34065 r34085 99 99 } 100 100 101 static inline bool shouldExcludeFunction(ExecState* exec, JSObject* calledFunction)102 {103 if (!calledFunction->inherits(&InternalFunctionImp::info))104 return false;105 // Don't record a call for function.call and function.apply.106 if (static_cast<InternalFunctionImp*>(calledFunction)->functionName() == exec->propertyNames().call)107 return true;108 if (static_cast<InternalFunctionImp*>(calledFunction)->functionName() == exec->propertyNames().apply)109 return true;110 return false;111 }112 113 101 static inline void dispatchFunctionToProfiles(const Vector<RefPtr<Profile> >& profiles, Profile::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentPageGroupIdentifier) 114 102 { … … 120 108 void Profiler::willExecute(ExecState* exec, JSObject* calledFunction) 121 109 { 122 if (m_currentProfiles.isEmpty()) 123 return; 124 125 if (shouldExcludeFunction(exec, calledFunction)) 126 return; 110 ASSERT(!m_currentProfiles.isEmpty()); 127 111 128 112 dispatchFunctionToProfiles(m_currentProfiles, &Profile::willExecute, createCallIdentifier(calledFunction), exec->lexicalGlobalObject()->pageGroupIdentifier()); … … 131 115 void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber) 132 116 { 133 if (m_currentProfiles.isEmpty()) 134 return; 117 ASSERT(!m_currentProfiles.isEmpty()); 135 118 136 119 CallIdentifier callIdentifier = createCallIdentifier(sourceURL, startingLineNumber); … … 141 124 void Profiler::didExecute(ExecState* exec, JSObject* calledFunction) 142 125 { 143 if (m_currentProfiles.isEmpty()) 144 return; 145 146 if (shouldExcludeFunction(exec, calledFunction)) 147 return; 126 ASSERT(!m_currentProfiles.isEmpty()); 148 127 149 128 dispatchFunctionToProfiles(m_currentProfiles, &Profile::didExecute, createCallIdentifier(calledFunction), exec->lexicalGlobalObject()->pageGroupIdentifier()); … … 152 131 void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber) 153 132 { 154 if (m_currentProfiles.isEmpty()) 155 return; 133 ASSERT(!m_currentProfiles.isEmpty()); 156 134 157 135 dispatchFunctionToProfiles(m_currentProfiles, &Profile::didExecute, createCallIdentifier(sourceURL, startingLineNumber), exec->lexicalGlobalObject()->pageGroupIdentifier());
Note:
See TracChangeset
for help on using the changeset viewer.