Remove JAVASCRIPT_PROFILER define
[WebKit-https.git] / JavaScriptCore / VM / Machine.cpp
index 068d364..177a748 100644 (file)
@@ -38,6 +38,7 @@
 #include "JSLock.h"
 #include "JSPropertyNameIterator.h"
 #include "Parser.h"
+#include "Profiler.h"
 #include "Register.h"
 #include "array_object.h"
 #include "debugger.h"
@@ -97,6 +98,9 @@ static int depth(ScopeChain& sc)
     
 static inline bool jsLess(ExecState* exec, JSValue* v1, JSValue* v2)
 {
+    if (JSImmediate::areBothImmediateNumbers(v1, v2))
+        return JSImmediate::getTruncatedInt32(v1) < JSImmediate::getTruncatedInt32(v2);
+
     double n1;
     double n2;
     JSValue* p1;
@@ -433,8 +437,13 @@ static NEVER_INLINE bool isNotObject(ExecState* exec, const Instruction*, CodeBl
     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())
@@ -457,7 +466,12 @@ static NEVER_INLINE JSValue* eval(ExecState* exec, JSObject* thisObj, ScopeChain
         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()
@@ -586,6 +600,9 @@ NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionVa
     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;
 }
 
@@ -646,7 +663,11 @@ JSValue* Machine::execute(ProgramNode* programNode, ExecState* exec, ScopeChainN
     
     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++;
@@ -654,6 +675,10 @@ JSValue* Machine::execute(ProgramNode* programNode, ExecState* exec, ScopeChainN
     m_reentryDepth--;
 
     registerFileStack->popGlobalRegisterFile();
+
+    if (*profiler)
+        (*profiler)->didExecute(exec, programNode->sourceURL(), programNode->lineNo());
+
     return result;
 }
 
@@ -701,14 +726,20 @@ JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, ExecState* exec, F
     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)
@@ -717,6 +748,7 @@ JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj
         *exception = createStackOverflowError(exec);
         return 0;
     }
+
     EvalCodeBlock* codeBlock = &evalNode->code(scopeChain);
     
     JSVariableObject* variableObject;
@@ -757,6 +789,10 @@ JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj
     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++;
@@ -764,6 +800,10 @@ JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj
     m_reentryDepth--;
 
     registerFile->shrink(oldSize);
+
+    if (*profiler)
+        (*profiler)->didExecute(exec, evalNode->sourceURL(), evalNode->lineNo());
+
     return result;
 }
 
@@ -834,11 +874,20 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
 
     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 { \
@@ -1795,29 +1844,31 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         NEXT_OPCODE;
     }
     BEGIN_OPCODE(op_call_eval) {
-        int r0 = (++vPC)->u.operand;
-        int r1 = (++vPC)->u.operand;
-        int r2 = (++vPC)->u.operand;
+        int dst = (++vPC)->u.operand;
+        int func = (++vPC)->u.operand;
+        int base = (++vPC)->u.operand;
         int argv = (++vPC)->u.operand;
         int argc = (++vPC)->u.operand;
 
-        JSValue* v = r[r1].u.jsValue;
-        JSValue* base = r[r2].u.jsValue;
+        JSValue* funcVal = r[func].u.jsValue;
+        JSValue* baseVal = r[base].u.jsValue;
         
-        if (base == scopeChain->globalObject() && v == scopeChain->globalObject()->evalFunction()) {
+        if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
             int registerOffset = r - (*registerBase);
 
             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;
 
             if (exceptionValue)
                 goto vm_throw;
 
-            r[r0].u.jsValue = result;
+            r[dst].u.jsValue = result;
             
             ++vPC;
             NEXT_OPCODE;
@@ -1827,7 +1878,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         // this instruction as a normal function call, supplying the proper 'this'
         // value.
         vPC -= 5;
-        r[r2].u.jsValue = base->toObject(exec)->toThisObject(exec);
+        r[base].u.jsValue = baseVal->toObject(exec)->toThisObject(exec);
 
 #if HAVE(COMPUTED_GOTO)
         // Hack around gcc performance quirk by performing an indirect goto
@@ -1838,24 +1889,26 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         // fall through to op_call
     }
     BEGIN_OPCODE(op_call) {
-        int r0 = (++vPC)->u.operand;
-        int r1 = (++vPC)->u.operand;
-        int r2 = (++vPC)->u.operand;
+        int dst = (++vPC)->u.operand;
+        int func = (++vPC)->u.operand;
+        int base = (++vPC)->u.operand;
         int argv = (++vPC)->u.operand;
         int argc = (++vPC)->u.operand;
         
-        JSValue* v = r[r1].u.jsValue;
+        JSValue* v = r[func].u.jsValue;
         
         CallData callData;
         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;
 
-            r[argv].u.jsValue = r2 == missingThisObjectMarker() ? exec->globalThisValue() : r[r2].u.jsValue; // "this" value
-            initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, r0, argv, argc, 0, v);
+            r[argv].u.jsValue = base == missingThisObjectMarker() ? exec->globalThisValue() : r[base].u.jsValue; // "this" value
+            initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, argv, argc, 0, v);
 
             ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
             FunctionBodyNode* functionBodyNode = callData.js.functionBody;
@@ -1875,9 +1928,11 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         }
 
         if (callType == CallTypeNative) {
+            if (*enabledProfilerReference)
+                (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
             int registerOffset = r - (*registerBase);
-            
-            r[argv].u.jsValue = r2 == missingThisObjectMarker() ? exec->globalThisValue() : (r[r2].u.jsValue)->toObject(exec); // "this" value
+
+            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);
 
             List args(&r[argv + 1].u.jsValue, argc - 1);
@@ -1887,8 +1942,10 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
             registerFile->setSafeForReentry(false);
 
             r = (*registerBase) + registerOffset;
-            r[r0].u.jsValue = returnValue;
+            r[dst].u.jsValue = returnValue;
 
+            if (*enabledProfilerReference)
+                (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v));
             VM_CHECK_EXCEPTION();
 
             ++vPC;
@@ -1934,24 +1991,30 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         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) {
-        int r0 = (++vPC)->u.operand;
-        int r1 = (++vPC)->u.operand;
+        int dst = (++vPC)->u.operand;
+        int func = (++vPC)->u.operand;
         int argv = (++vPC)->u.operand;
         int argc = (++vPC)->u.operand;
 
-        JSValue* v = r[r1].u.jsValue;
+        JSValue* funcVal = r[func].u.jsValue;
 
         ConstructData constructData;
-        ConstructType constructType = v->getConstructData(constructData);
+        ConstructType constructType = funcVal->getConstructData(constructData);
 
         // Removing this line of code causes a measurable regression on squirrelfish.
-        JSObject* constructor = static_cast<JSObject*>(v);
+        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;
@@ -1965,8 +2028,8 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
             JSObject* newObject = new JSObject(prototype);
             r[argv].u.jsValue = newObject; // "this" value
 
-            initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, r0, argv, argc, 1, constructor);
-            
+            initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, argv, argc, 1, constructor);
+
             ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
             FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
 
@@ -1985,24 +2048,30 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         }
 
         if (constructType == ConstructTypeNative) {
+            if (*enabledProfilerReference)
+                (*enabledProfilerReference)->willExecute(exec, constructor);
+
             int registerOffset = r - (*registerBase);
 
             List args(&r[argv + 1].u.jsValue, argc - 1);
             registerFile->setSafeForReentry(true);
             JSValue* returnValue = constructor->construct(exec, args);
             registerFile->setSafeForReentry(false);
-        
+
             r = (*registerBase) + registerOffset;
             VM_CHECK_EXCEPTION();
-            r[r0].u.jsValue = returnValue;
-            
+            r[dst].u.jsValue = returnValue;
+
+            if (*enabledProfilerReference)
+                (*enabledProfilerReference)->didExecute(exec, constructor);
+
             ++vPC;
             NEXT_OPCODE;
         }
 
         ASSERT(constructType == ConstructTypeNone);
 
-        exceptionValue = createNotAConstructorError(exec, v, 0);
+        exceptionValue = createNotAConstructorError(exec, funcVal, 0);
         goto vm_throw;
     }
     BEGIN_OPCODE(op_push_scope) {