Ignore:
Timestamp:
May 23, 2008, 10:50:51 AM (17 years ago)
Author:
[email protected]
Message:

2008-05-23 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler, Kevin McCullough, and Oliver Hunt.


Fixed <rdar://problem/5959447> Crashes and incorrect reporting in the
JavaScript profiler

  • VM/Machine.cpp: (KJS::callEval): Made this profiler hooks slightly faster by passing in the eval function.


(KJS::Machine::unwindCallFrame): Fixed incorrect reporting / a crash
when unwinding from inside eval and/or program code: detect the
difference, and do the right thing. Also, be sure to notify the profiler
*before* deref'ing the scope chain, since the profiler uses the scope chain.

(KJS::Machine::execute): Fixed incorrect reporting / crash when calling
a JS function re-entrently: Machine::execute(FunctionBodyNode*...)
should not invoke the didExecute hook, because op_ret already does that.
Also, use the new function's ExecState when calling out to the profiler.
(Not important now, but could have become a subtle bug later.)

(KJS::Machine::privateExecute): Fixed a hard to reproduce crash when
profiling JS functions: notify the profiler *before* deref'ing the scope
chain, since the profiler uses the scope chain.

  • kjs/object.cpp: (KJS::JSObject::call): Removed these hooks, because they are now unnecessary.
  • profiler/Profile.cpp: Added a comment to explain a subtlety that only Kevin and I understood previously. (Now, the whole world can understand!)
  • profiler/Profiler.cpp: (KJS::shouldExcludeFunction): Don't exclude .call and .apply. That was a hack to fix bugs that no longer exist.

Finally, sped things up a little bit by changing the "Is the profiler
running?" check into an ASSERT, since we only call into the profiler
when it's running:

(KJS::Profiler::willExecute):
(KJS::Profiler::didExecute):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/profiler/Profiler.cpp

    r34065 r34085  
    9999}
    100100
    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 
    113101static inline void dispatchFunctionToProfiles(const Vector<RefPtr<Profile> >& profiles, Profile::ProfileFunction function, const CallIdentifier& callIdentifier, unsigned currentPageGroupIdentifier)
    114102{
     
    120108void Profiler::willExecute(ExecState* exec, JSObject* calledFunction)
    121109{
    122     if (m_currentProfiles.isEmpty())
    123         return;
    124 
    125     if (shouldExcludeFunction(exec, calledFunction))
    126         return;
     110    ASSERT(!m_currentProfiles.isEmpty());
    127111
    128112    dispatchFunctionToProfiles(m_currentProfiles, &Profile::willExecute, createCallIdentifier(calledFunction), exec->lexicalGlobalObject()->pageGroupIdentifier());
     
    131115void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber)
    132116{
    133     if (m_currentProfiles.isEmpty())
    134         return;
     117    ASSERT(!m_currentProfiles.isEmpty());
    135118
    136119    CallIdentifier callIdentifier = createCallIdentifier(sourceURL, startingLineNumber);
     
    141124void Profiler::didExecute(ExecState* exec, JSObject* calledFunction)
    142125{
    143     if (m_currentProfiles.isEmpty())
    144         return;
    145 
    146     if (shouldExcludeFunction(exec, calledFunction))
    147         return;
     126    ASSERT(!m_currentProfiles.isEmpty());
    148127
    149128    dispatchFunctionToProfiles(m_currentProfiles, &Profile::didExecute, createCallIdentifier(calledFunction), exec->lexicalGlobalObject()->pageGroupIdentifier());
     
    152131void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startingLineNumber)
    153132{
    154     if (m_currentProfiles.isEmpty())
    155         return;
     133    ASSERT(!m_currentProfiles.isEmpty());
    156134
    157135    dispatchFunctionToProfiles(m_currentProfiles, &Profile::didExecute, createCallIdentifier(sourceURL, startingLineNumber), exec->lexicalGlobalObject()->pageGroupIdentifier());
Note: See TracChangeset for help on using the changeset viewer.