Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(507)

Unified Diff: third_party/WebKit/JavaScriptCore/VM/Machine.cpp

Issue 10670: Do another merge using nifty new merge script (CL for that coming soon). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/JavaScriptCore/VM/Machine.cpp
===================================================================
--- third_party/WebKit/JavaScriptCore/VM/Machine.cpp (revision 5302)
+++ third_party/WebKit/JavaScriptCore/VM/Machine.cpp (working copy)
@@ -580,24 +580,25 @@
return true;
}
-NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, int argv, int argc, JSValue*& exceptionValue)
+NEVER_INLINE JSValue* Machine::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset, JSValue*& exceptionValue)
{
if (argc < 2)
return jsUndefined();
- JSValue* program = callFrame[argv + 1].jsValue(callFrame);
+ JSValue* program = argv[1].jsValue(callFrame);
if (!program->isString())
return program;
UString programSource = asString(program)->value();
+ ScopeChainNode* scopeChain = callFrame->scopeChain();
CodeBlock* codeBlock = callFrame->codeBlock();
RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache.get(callFrame, programSource, scopeChain, exceptionValue);
JSValue* result = jsUndefined();
if (evalNode)
- result = callFrame->globalData().machine->execute(evalNode.get(), callFrame, thisObj, callFrame->registers() - registerFile->start() + argv + 1 + RegisterFile::CallFrameHeaderSize, scopeChain, &exceptionValue);
+ result = callFrame->globalData().machine->execute(evalNode.get(), callFrame, callFrame->thisValue()->toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
return result;
}
@@ -655,17 +656,13 @@
#ifndef NDEBUG
-void Machine::dumpCallFrame(const RegisterFile* registerFile, CallFrame* callFrame)
+void Machine::dumpCallFrame(CallFrame* callFrame)
{
- JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
-
- CodeBlock* codeBlock = callFrame->codeBlock();
- codeBlock->dump(globalObject->globalExec());
-
- dumpRegisters(registerFile, callFrame);
+ callFrame->codeBlock()->dump(callFrame);
+ dumpRegisters(callFrame);
}
-void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFrame)
+void Machine::dumpRegisters(CallFrame* callFrame)
{
printf("Register frame: \n\n");
printf("----------------------------------------------------\n");
@@ -673,6 +670,7 @@
printf("----------------------------------------------------\n");
CodeBlock* codeBlock = callFrame->codeBlock();
+ RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->machine->registerFile();
const Register* it;
const Register* end;
@@ -1023,7 +1021,7 @@
return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->byteCode(scopeChain).numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
}
-JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception)
+JSValue* Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue** exception)
{
ASSERT(!scopeChain->globalData->exception);
@@ -1069,13 +1067,13 @@
}
Register* oldEnd = m_registerFile.end();
- Register* newEnd = m_registerFile.start() + registerOffset + codeBlock->numCalleeRegisters;
+ Register* newEnd = m_registerFile.start() + globalRegisterOffset + codeBlock->numCalleeRegisters;
if (!m_registerFile.grow(newEnd)) {
*exception = createStackOverflowError(callFrame);
return jsNull();
}
- CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + registerOffset);
+ CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset);
// a 0 codeBlock indicates a built-in caller
newCallFrame[codeBlock->thisRegister] = thisObj;
@@ -3264,7 +3262,7 @@
NEXT_OPCODE;
}
BEGIN_OPCODE(op_call_eval) {
- /* call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n)
+ /* call_eval dst(r) func(r) argCount(n) registerOffset(n)
Call a function named "eval" with no explicit "this" value
(which may therefore be the eval operator). If register
@@ -3277,30 +3275,28 @@
int dst = vPC[1].u.operand;
int func = vPC[2].u.operand;
- int thisVal = vPC[3].u.operand;
- int firstArg = vPC[4].u.operand;
- int argCount = vPC[5].u.operand;
+ int argCount = vPC[3].u.operand;
+ int registerOffset = vPC[4].u.operand;
JSValue* funcVal = callFrame[func].jsValue(callFrame);
- JSValue* baseVal = callFrame[thisVal].jsValue(callFrame);
- ScopeChainNode* scopeChain = callFrame->scopeChain();
- if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
- JSObject* thisObject = asObject(callFrame[callFrame->codeBlock()->thisRegister].jsValue(callFrame));
- JSValue* result = callEval(callFrame, thisObject, scopeChain, registerFile, firstArg, argCount, exceptionValue);
+ Register* newCallFrame = callFrame->registers() + registerOffset;
+ Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
+ JSValue* thisValue = argv[0].jsValue(callFrame);
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+
+ if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
+ JSValue* result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
if (exceptionValue)
goto vm_throw;
-
callFrame[dst] = result;
- vPC += 7;
+ vPC += 5;
NEXT_OPCODE;
}
- // We didn't find the blessed version of eval, so reset vPC and process
- // this instruction as a normal function call, supplying the proper 'this'
- // value.
- callFrame[thisVal] = baseVal->toThisObject(callFrame);
+ // We didn't find the blessed version of eval, so process this
+ // instruction as a normal function call.
#if HAVE(COMPUTED_GOTO)
// Hack around gcc performance quirk by performing an indirect goto
@@ -3311,48 +3307,20 @@
// fall through to op_call
}
BEGIN_OPCODE(op_call) {
- /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) registerOffset(n)
+ /* call dst(r) func(r) argCount(n) registerOffset(n)
- Perform a function call. Specifically, call register func
- with a "this" value of register thisVal, and put the result
- in register dst.
-
- The arguments start at register firstArg and go up to
- argCount, but the "this" value is considered an implicit
- first argument, so the argCount should be one greater than
- the number of explicit arguments passed, and the register
- after firstArg should contain the actual first
- argument. This opcode will copy from the thisVal register
- to the firstArg register, unless the register index of
- thisVal is the special missing this object marker, which is
- 2^31-1; in that case, the global object will be used as the
- "this" value.
-
- If func is a native code function, then this opcode calls
- it and returns the value immediately.
-
- But if it is a JS function, then the current scope chain
- and code block is set to the function's, and we slide the
- register window so that the arguments would form the first
- few local registers of the called function's register
- window. In addition, a call frame header is written
- immediately before the arguments; see the call frame
- documentation for an explanation of how many registers a
- call frame takes and what they contain. That many registers
- before the firstArg register will be overwritten by the
- call. In addition, any registers higher than firstArg +
- argCount may be overwritten. Once this setup is complete,
- execution continues from the called function's first
- argument, and does not return until a "ret" opcode is
- encountered.
+ Perform a function call.
+
+ registerOffset is the distance the callFrame pointer should move
+ before the VM initializes the new call frame's header.
+
+ dst is where op_ret should store its result.
*/
int dst = vPC[1].u.operand;
int func = vPC[2].u.operand;
- int thisVal = vPC[3].u.operand;
- int firstArg = vPC[4].u.operand;
- int argCount = vPC[5].u.operand;
- int registerOffset = vPC[6].u.operand;
+ int argCount = vPC[3].u.operand;
+ int registerOffset = vPC[4].u.operand;
JSValue* v = callFrame[func].jsValue(callFrame);
@@ -3364,8 +3332,6 @@
FunctionBodyNode* functionBodyNode = callData.js.functionBody;
CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
- callFrame[firstArg] = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
-
CallFrame* previousCallFrame = callFrame;
callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
@@ -3375,7 +3341,7 @@
goto vm_throw;
}
- callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
+ callFrame->init(newCodeBlock, vPC + 5, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
vPC = newCodeBlock->instructions.begin();
#if ENABLE(OPCODE_STATS)
@@ -3386,13 +3352,18 @@
}
if (callType == CallTypeHost) {
- JSValue* thisValue = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
- ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
-
ScopeChainNode* scopeChain = callFrame->scopeChain();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
- newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
+ newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, 0);
+ Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
+ ArgList args(thisRegister + 1, argCount - 1);
+
+ // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
+ JSValue* thisValue = thisRegister->jsValue(callFrame);
+ if (thisValue == jsNull())
+ thisValue = callFrame->globalThisValue();
+
JSValue* returnValue;
{
SamplingTool::HostCallRecord callRecord(m_sampler);
@@ -3402,7 +3373,7 @@
callFrame[dst] = returnValue;
- vPC += 7;
+ vPC += 5;
NEXT_OPCODE;
}
@@ -3572,28 +3543,28 @@
NEXT_OPCODE;
}
BEGIN_OPCODE(op_construct) {
- /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) registerOffset(n)
+ /* construct dst(r) func(r) argCount(n) registerOffset(n) proto(r) thisRegister(r)
- Invoke register "constr" as a constructor. For JS
+ Invoke register "func" as a constructor. For JS
functions, the calling convention is exactly as for the
"call" opcode, except that the "this" value is a newly
- created Object. For native constructors, a null "this"
- value is passed. In either case, the firstArg and argCount
+ created Object. For native constructors, no "this"
+ value is passed. In either case, the argCount and registerOffset
registers are interpreted as for the "call" opcode.
- Register constrProto must contain the prototype property of
- register constsr. This is to enable polymorphic inline
+ Register proto must contain the prototype property of
+ register func. This is to enable polymorphic inline
caching of this lookup.
*/
int dst = vPC[1].u.operand;
- int constr = vPC[2].u.operand;
- int constrProto = vPC[3].u.operand;
- int firstArg = vPC[4].u.operand;
- int argCount = vPC[5].u.operand;
- int registerOffset = vPC[6].u.operand;
+ int func = vPC[2].u.operand;
+ int argCount = vPC[3].u.operand;
+ int registerOffset = vPC[4].u.operand;
+ int proto = vPC[5].u.operand;
+ int thisRegister = vPC[6].u.operand;
- JSValue* v = callFrame[constr].jsValue(callFrame);
+ JSValue* v = callFrame[func].jsValue(callFrame);
ConstructData constructData;
ConstructType constructType = v->getConstructData(constructData);
@@ -3604,14 +3575,14 @@
CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
StructureID* structure;
- JSValue* prototype = callFrame[constrProto].jsValue(callFrame);
+ JSValue* prototype = callFrame[proto].jsValue(callFrame);
if (prototype->isObject())
structure = asObject(prototype)->inheritorID();
else
structure = callDataScopeChain->globalObject()->emptyObjectStructure();
JSObject* newObject = new (globalData) JSObject(structure);
- callFrame[firstArg] = newObject; // "this" value
+ callFrame[thisRegister] = newObject; // "this" value
CallFrame* previousCallFrame = callFrame;
@@ -3633,7 +3604,7 @@
}
if (constructType == ConstructTypeHost) {
- ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
+ ArgList args(callFrame->registers() + thisRegister + 1, argCount - 1);
ScopeChainNode* scopeChain = callFrame->scopeChain();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
@@ -4325,13 +4296,19 @@
// to get the address of the ctiVMThrowTrampoline function. It's also
// good to keep the code size down by leaving as much of the exception
// handling code out of line as possible.
-static NEVER_INLINE void setUpThrowTrampolineReturnAddress(JSGlobalData* globalData, void*& returnAddress)
+static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
{
ASSERT(globalData->exception);
- globalData->throwReturnAddress = returnAddress;
- ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
+ globalData->exceptionLocation = exceptionLocation;
+ ctiSetReturnAddress(&returnAddressSlot, reinterpret_cast<void*>(ctiVMThrowTrampoline));
}
+static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
+{
+ globalData->exception = createStackOverflowError(callFrame);
+ returnToThrowTrampoline(globalData, exceptionLocation, returnAddressSlot);
+}
+
#define VM_THROW_EXCEPTION() \
do { \
VM_THROW_EXCEPTION_AT_END(); \
@@ -4344,7 +4321,7 @@
return pair.i; \
} while (0)
#define VM_THROW_EXCEPTION_AT_END() \
- setUpThrowTrampolineReturnAddress(ARG_globalData, CTI_RETURN_ADDRESS)
+ returnToThrowTrampoline(ARG_globalData, CTI_RETURN_ADDRESS, CTI_RETURN_ADDRESS)
#define VM_CHECK_EXCEPTION() \
do { \
@@ -4452,13 +4429,6 @@
}
}
-NEVER_INLINE void Machine::throwStackOverflowPreviousFrame(CallFrame* callFrame, JSGlobalData* globalData, void*& returnAddress)
-{
- globalData->exception = createStackOverflowError(callFrame->callerFrame());
- globalData->throwReturnAddress = callFrame->returnPC();
- ctiSetReturnAddress(&returnAddress, reinterpret_cast<void*>(ctiVMThrowTrampoline));
-}
-
void Machine::cti_register_file_check(CTI_ARGS)
{
CTI_STACK_HACK();
@@ -4466,8 +4436,11 @@
if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock()->numCalleeRegisters)))
return;
- ARG_setCallFrame(ARG_callFrame->callerFrame());
- throwStackOverflowPreviousFrame(ARG_callFrame, ARG_globalData, CTI_RETURN_ADDRESS);
+ // Rewind to the previous call frame because op_call already optimistically
+ // moved the call frame forward.
+ CallFrame* oldCallFrame = ARG_callFrame->callerFrame();
+ ARG_setCallFrame(oldCallFrame);
+ throwStackOverflowError(oldCallFrame, ARG_globalData, oldCallFrame->returnPC(), CTI_RETURN_ADDRESS);
}
int Machine::cti_op_loop_if_less(CTI_ARGS)
@@ -4744,8 +4717,12 @@
Register* r = callFrame->registers() + omittedArgCount;
Register* newEnd = r + newCodeBlock->numCalleeRegisters;
if (!ARG_registerFile->grow(newEnd)) {
- ARG_globalData->exception = createStackOverflowError(oldCallFrame);
- VM_THROW_EXCEPTION_2();
+ // Rewind to the previous call frame because op_call already optimistically
+ // moved the call frame forward.
+ ARG_setCallFrame(oldCallFrame);
+ throwStackOverflowError(oldCallFrame, ARG_globalData, CTI_RETURN_ADDRESS, CTI_RETURN_ADDRESS);
+ VoidPtrPairValue pair = {{ 0, 0 }};
+ return pair.i;
}
Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
@@ -4810,7 +4787,7 @@
{
SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
- // All host methods should be calling toThisObject, but this is not presently the case.
+ // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
JSValue* thisValue = argv[0].jsValue(callFrame);
if (thisValue == jsNull())
thisValue = callFrame->globalThisValue();
@@ -4934,8 +4911,8 @@
#endif
StructureID* structure;
- if (ARG_src5->isObject())
- structure = asObject(ARG_src5)->inheritorID();
+ if (ARG_src4->isObject())
+ structure = asObject(ARG_src4)->inheritorID();
else
structure = asFunction(ARG_src1)->m_scopeChain.node()->globalObject()->emptyObjectStructure();
return new (ARG_globalData) JSObject(structure);
@@ -4949,13 +4926,13 @@
JSValue* constrVal = ARG_src1;
int argCount = ARG_int3;
- int firstArg = ARG_int6;
+ int thisRegister = ARG_int5;
ConstructData constructData;
ConstructType constructType = constrVal->getConstructData(constructData);
if (constructType == ConstructTypeHost) {
- ArgList argList(callFrame->registers() + firstArg + 1, argCount - 1);
+ ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1);
JSValue* returnValue;
{
@@ -4969,7 +4946,7 @@
ASSERT(constructType == ConstructTypeNone);
- ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, ARG_instr4, callFrame->codeBlock());
+ ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, ARG_instr6, callFrame->codeBlock());
VM_THROW_EXCEPTION();
}
@@ -5568,20 +5545,21 @@
CallFrame* callFrame = ARG_callFrame;
RegisterFile* registerFile = ARG_registerFile;
- CodeBlock* codeBlock = callFrame->codeBlock();
- ScopeChainNode* scopeChain = callFrame->scopeChain();
Machine* machine = ARG_globalData->machine;
JSValue* funcVal = ARG_src1;
int registerOffset = ARG_int2;
int argCount = ARG_int3;
- JSValue* baseVal = ARG_src5;
- if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
- JSObject* thisObject = callFrame[codeBlock->thisRegister].jsValue(callFrame)->toThisObject(callFrame);
+ Register* newCallFrame = callFrame->registers() + registerOffset;
+ Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
+ JSValue* thisValue = argv[0].jsValue(callFrame);
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+
+ if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
JSValue* exceptionValue = noValue();
- JSValue* result = machine->callEval(callFrame, thisObject, scopeChain, registerFile, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argCount, exceptionValue);
+ JSValue* result = machine->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
if (UNLIKELY(exceptionValue != noValue())) {
ARG_globalData->exception = exceptionValue;
VM_THROW_EXCEPTION_AT_END();
@@ -5944,15 +5922,16 @@
CallFrame* callFrame = ARG_callFrame;
CodeBlock* codeBlock = callFrame->codeBlock();
+ JSGlobalData* globalData = ARG_globalData;
- ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(ARG_globalData->throwReturnAddress));
- unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(ARG_globalData->throwReturnAddress);
+ ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(globalData->exceptionLocation));
+ unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(globalData->exceptionLocation);
- JSValue* exceptionValue = ARG_globalData->exception;
+ JSValue* exceptionValue = globalData->exception;
ASSERT(exceptionValue);
- ARG_globalData->exception = noValue();
+ globalData->exception = noValue();
- Instruction* handlerVPC = ARG_globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, false);
+ Instruction* handlerVPC = globalData->machine->throwException(callFrame, exceptionValue, codeBlock->instructions.begin() + vPCIndex, false);
if (!handlerVPC) {
*ARG_exception = exceptionValue;
« no previous file with comments | « third_party/WebKit/JavaScriptCore/VM/Machine.h ('k') | third_party/WebKit/JavaScriptCore/bytecompiler/CodeGenerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698