#include "JSLock.h"
#include "JSPropertyNameIterator.h"
#include "Parser.h"
+#include "Profiler.h"
#include "Register.h"
#include "array_object.h"
#include "debugger.h"
return true;
}
-static NEVER_INLINE JSValue* eval(ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, Register* r, int argv, int argc, JSValue*& exceptionValue)
+static NEVER_INLINE JSValue* callEval(ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, Register* r, int argv, int argc, JSValue*& exceptionValue)
{
+ Profiler** profiler = Profiler::enabledProfilerReference();
+ JSObject* evalFunction = scopeChain->globalObject()->evalFunction();
+ if (*profiler)
+ (*profiler)->willExecute(exec, evalFunction);
+
JSValue* x = argc >= 2 ? r[argv + 1].u.jsValue : jsUndefined();
if (!x->isString())
return 0;
}
- return machine().execute(evalNode.get(), exec, thisObj, registerFile, r - (*registerFile->basePointer()) + argv + argc, scopeChain, &exceptionValue);
+ JSValue* result = machine().execute(evalNode.get(), exec, thisObj, registerFile, r - (*registerFile->basePointer()) + argv + argc, scopeChain, &exceptionValue);
+
+ if ((*profiler))
+ (*profiler)->didExecute(exec, evalFunction);
+
+ return result;
}
Machine& machine()
r = (*registerBase) + callerRegisterOffset;
exec->m_callFrameOffset = callerRegisterOffset - codeBlock->numLocals - CallFrameHeaderSize;
vPC = callFrame[ReturnVPC].u.vPC;
+
+ if (Profiler* profiler = *Profiler::enabledProfilerReference())
+ profiler->didExecute(exec, callFrame[Callee].u.jsObject);
return true;
}
if (codeBlock->needsFullScopeChain)
scopeChain = scopeChain->copy();
-
+
+ Profiler** profiler = Profiler::enabledProfilerReference();
+ if (*profiler)
+ (*profiler)->willExecute(exec, programNode->sourceURL(), programNode->lineNo());
+
ExecState newExec(exec, this, registerFile, scopeChain, -1);
m_reentryDepth++;
m_reentryDepth--;
registerFileStack->popGlobalRegisterFile();
+
+ if (*profiler)
+ (*profiler)->didExecute(exec, programNode->sourceURL(), programNode->lineNo());
+
return result;
}
scopeChain = scopeChainForCall(functionBodyNode, newCodeBlock, scopeChain, registerBase, r);
ExecState newExec(exec, this, registerFile, scopeChain, callFrameOffset);
+
+ Profiler** profiler = Profiler::enabledProfilerReference();
+ if (*profiler)
+ (*profiler)->willExecute(exec, function);
m_reentryDepth++;
JSValue* result = privateExecute(Normal, &newExec, registerFile, r, scopeChain, newCodeBlock, exception);
m_reentryDepth--;
+ if (*profiler)
+ (*profiler)->didExecute(exec, function);
+
registerFile->shrink(oldSize);
return result;
-
}
JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, RegisterFile* registerFile, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception)
*exception = createStackOverflowError(exec);
return 0;
}
+
EvalCodeBlock* codeBlock = &evalNode->code(scopeChain);
JSVariableObject* variableObject;
if (codeBlock->needsFullScopeChain)
scopeChain = scopeChain->copy();
+ Profiler** profiler = Profiler::enabledProfilerReference();
+ if (*profiler)
+ (*profiler)->willExecute(exec, evalNode->sourceURL(), evalNode->lineNo());
+
ExecState newExec(exec, this, registerFile, scopeChain, -1);
m_reentryDepth++;
m_reentryDepth--;
registerFile->shrink(oldSize);
+
+ if (*profiler)
+ (*profiler)->didExecute(exec, evalNode->sourceURL(), evalNode->lineNo());
+
return result;
}
JSValue* exceptionValue = 0;
Instruction* handlerVPC = 0;
-
+
Register** registerBase = registerFile->basePointer();
Instruction* vPC = codeBlock->instructions.begin();
JSValue** k = codeBlock->jsValues.data();
+ Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
+#if HAVE(COMPUTED_GOTO)
+ // Yet another hack around GCC's various foibles, in this case fetching the
+ // profiler reference results in a regression. Removing this indirection
+ // results in a 0.8% regression.
+ goto *(&&profilerFetchHack);
+ profilerFetchHack:
+#endif
+
registerFile->setSafeForReentry(false);
#define VM_CHECK_EXCEPTION() \
do { \
JSObject* thisObject = r[codeBlock->thisRegister].u.jsObject;
registerFile->setSafeForReentry(true);
- JSValue* result = eval(exec, thisObject, scopeChain, registerFile, r, argv, argc, exceptionValue);
+
+ JSValue* result = callEval(exec, thisObject, scopeChain, registerFile, r, argv, argc, exceptionValue);
+
registerFile->setSafeForReentry(false);
r = (*registerBase) + registerOffset;
CallType callType = v->getCallData(callData);
if (callType == CallTypeJS) {
+ if (*enabledProfilerReference)
+ (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
int registerOffset = r - (*registerBase);
Register* callFrame = r + argv - CallFrameHeaderSize;
int callFrameOffset = registerOffset + argv - CallFrameHeaderSize;
}
if (callType == CallTypeNative) {
+ if (*enabledProfilerReference)
+ (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
int registerOffset = r - (*registerBase);
-
+
r[argv].u.jsValue = base == missingThisObjectMarker() ? exec->globalThisValue() : (r[base].u.jsValue)->toObject(exec); // "this" value
JSObject* thisObj = static_cast<JSObject*>(r[argv].u.jsValue);
r = (*registerBase) + registerOffset;
r[dst].u.jsValue = returnValue;
+ if (*enabledProfilerReference)
+ (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v));
VM_CHECK_EXCEPTION();
++vPC;
exec->m_callFrameOffset = callerRegisterOffset - codeBlock->numLocals - CallFrameHeaderSize;
int r0 = callFrame[ReturnValueRegister].u.i;
r[r0].u.jsValue = returnValue;
-
+
+ if (*enabledProfilerReference)
+ (*enabledProfilerReference)->didExecute(exec, callFrame[Callee].u.jsObject);
+
NEXT_OPCODE;
}
BEGIN_OPCODE(op_construct) {
JSObject* constructor = static_cast<JSObject*>(funcVal);
if (constructType == ConstructTypeJS) {
+ if (*enabledProfilerReference)
+ (*enabledProfilerReference)->willExecute(exec, constructor);
+
int registerOffset = r - (*registerBase);
Register* callFrame = r + argv - CallFrameHeaderSize;
int callFrameOffset = registerOffset + argv - CallFrameHeaderSize;
}
if (constructType == ConstructTypeNative) {
+ if (*enabledProfilerReference)
+ (*enabledProfilerReference)->willExecute(exec, constructor);
+
int registerOffset = r - (*registerBase);
List args(&r[argv + 1].u.jsValue, argc - 1);
VM_CHECK_EXCEPTION();
r[dst].u.jsValue = returnValue;
+ if (*enabledProfilerReference)
+ (*enabledProfilerReference)->didExecute(exec, constructor);
+
++vPC;
NEXT_OPCODE;
}