| Index: third_party/WebKit/JavaScriptCore/bytecompiler/CodeGenerator.cpp
|
| ===================================================================
|
| --- third_party/WebKit/JavaScriptCore/bytecompiler/CodeGenerator.cpp (revision 5296)
|
| +++ third_party/WebKit/JavaScriptCore/bytecompiler/CodeGenerator.cpp (working copy)
|
| @@ -1219,25 +1219,38 @@
|
| return r0;
|
| }
|
|
|
| -RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
|
| +RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
|
| {
|
| - return emitCall(op_call, dst, func, base, argumentsNode, divot, startOffset, endOffset);
|
| + return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
|
| }
|
|
|
| -RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
|
| +RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
|
| {
|
| - return emitCall(op_call_eval, dst, func, base, argumentsNode, divot, startOffset, endOffset);
|
| + return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
|
| }
|
|
|
| -RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
|
| +RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
|
| {
|
| ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
|
| ASSERT(func->refCount());
|
| - ASSERT(!base || base->refCount());
|
| -
|
| +
|
| + if (m_shouldEmitProfileHooks) {
|
| + // If codegen decided to recycle func as this call's destination register,
|
| + // we need to undo that optimization here so that func will still be around
|
| + // for the sake of op_profile_did_call.
|
| + if (dst == func) {
|
| + RefPtr<RegisterID> protect = thisRegister;
|
| + RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister);
|
| + RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func);
|
| +
|
| + thisRegister = movedThisRegister.release().releaseRef();
|
| + func = movedFunc.release().releaseRef();
|
| + }
|
| + }
|
| +
|
| // Generate code for arguments.
|
| Vector<RefPtr<RegisterID>, 16> argv;
|
| - argv.append(newTemporary()); // reserve space for "this"
|
| + argv.append(thisRegister);
|
| for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
|
| argv.append(newTemporary());
|
| emitNode(argv.last().get(), n);
|
| @@ -1255,17 +1268,22 @@
|
|
|
| emitExpressionInfo(divot, startOffset, endOffset);
|
| m_codeBlock->callLinkInfos.append(CallLinkInfo());
|
| +
|
| + // Emit call.
|
| emitOpcode(opcodeID);
|
| - instructions().append(dst->index());
|
| - instructions().append(func->index());
|
| - instructions().append(base ? base->index() : missingThisObjectMarker()); // We encode the "this" value in the instruction stream, to avoid an explicit instruction for copying or loading it.
|
| - instructions().append(argv[0]->index()); // argv
|
| - instructions().append(argv.size()); // argc
|
| + instructions().append(dst->index()); // dst
|
| + instructions().append(func->index()); // func
|
| + instructions().append(argv.size()); // argCount
|
| instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
|
|
|
| if (m_shouldEmitProfileHooks) {
|
| emitOpcode(op_profile_did_call);
|
| instructions().append(func->index());
|
| +
|
| + if (dst == func) {
|
| + thisRegister->deref();
|
| + func->deref();
|
| + }
|
| }
|
|
|
| return dst;
|
| @@ -1293,6 +1311,16 @@
|
| {
|
| ASSERT(func->refCount());
|
|
|
| + if (m_shouldEmitProfileHooks) {
|
| + // If codegen decided to recycle func as this call's destination register,
|
| + // we need to undo that optimization here so that func will still be around
|
| + // for the sake of op_profile_did_call.
|
| + if (dst == func) {
|
| + RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func);
|
| + func = movedFunc.release().releaseRef();
|
| + }
|
| + }
|
| +
|
| RefPtr<RegisterID> funcProto = newTemporary();
|
|
|
| // Generate code for arguments.
|
| @@ -1319,13 +1347,14 @@
|
|
|
| emitExpressionInfo(divot, startOffset, endOffset);
|
| m_codeBlock->callLinkInfos.append(CallLinkInfo());
|
| +
|
| emitOpcode(op_construct);
|
| - instructions().append(dst->index());
|
| - instructions().append(func->index());
|
| - instructions().append(funcProto->index());
|
| - instructions().append(argv[0]->index()); // argv
|
| - instructions().append(argv.size()); // argc
|
| + instructions().append(dst->index()); // dst
|
| + instructions().append(func->index()); // func
|
| + instructions().append(argv.size()); // argCount
|
| instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
|
| + instructions().append(funcProto->index()); // proto
|
| + instructions().append(argv[0]->index()); // thisRegister
|
|
|
| emitOpcode(op_construct_verify);
|
| instructions().append(dst->index());
|
| @@ -1334,6 +1363,9 @@
|
| if (m_shouldEmitProfileHooks) {
|
| emitOpcode(op_profile_did_call);
|
| instructions().append(func->index());
|
| +
|
| + if (dst == func)
|
| + func->deref();
|
| }
|
|
|
| return dst;
|
|
|