Diff
Modified: trunk/LayoutTests/ChangeLog (90876 => 90877)
--- trunk/LayoutTests/ChangeLog 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/LayoutTests/ChangeLog 2011-07-13 01:46:09 UTC (rev 90877)
@@ -1,3 +1,20 @@
+2011-07-12 Filip Pizlo <[email protected]>
+
+ DFG JIT does not implement op_construct.
+ https://bugs.webkit.org/show_bug.cgi?id=64066
+
+ Reviewed by Gavin Barraclough.
+
+ Added a test for the DFG op_construct regression, where polymorphic constructor
+ calls will result in the code being compiled for call but then invoked as a
+ constructor. This test will fail if that part of the patch is omitted.
+
+ * fast/js/polymorphic-construct-expected.txt: Added.
+ * fast/js/polymorphic-construct.html: Added.
+ * fast/js/script-tests/polymorphic-construct.js: Added.
+ (Foo):
+ ():
+
2011-07-12 Chris Rogers <[email protected]>
Enable Web Audio for chromium DRT
Added: trunk/LayoutTests/fast/js/polymorphic-construct-expected.txt (0 => 90877)
--- trunk/LayoutTests/fast/js/polymorphic-construct-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/polymorphic-construct-expected.txt 2011-07-13 01:46:09 UTC (rev 90877)
@@ -0,0 +1,21 @@
+This tests that polymorphic construction works correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS construct(Foo).field is 'foo'
+PASS construct(Foo).field is 'foo'
+PASS construct(Foo).field is 'foo'
+PASS construct(Foo).field is 'foo'
+PASS construct(Bar).field is 'bar'
+PASS construct(Baz).field is 'baz'
+PASS construct(Foo).field is 'foo'
+PASS construct(Bar).field is 'bar'
+PASS construct(Baz).field is 'baz'
+PASS construct(Foo).field is 'foo'
+PASS construct(Bar).field is 'bar'
+PASS construct(Baz).field is 'baz'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/polymorphic-construct.html (0 => 90877)
--- trunk/LayoutTests/fast/js/polymorphic-construct.html (rev 0)
+++ trunk/LayoutTests/fast/js/polymorphic-construct.html 2011-07-13 01:46:09 UTC (rev 90877)
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/script-tests/polymorphic-construct.js (0 => 90877)
--- trunk/LayoutTests/fast/js/script-tests/polymorphic-construct.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/polymorphic-construct.js 2011-07-13 01:46:09 UTC (rev 90877)
@@ -0,0 +1,31 @@
+description(
+"This tests that polymorphic construction works correctly."
+);
+
+function Foo() {
+ this.field = "foo";
+}
+
+function Bar() {
+ this.field = "bar";
+}
+
+function Baz() {
+ this.field = "baz";
+}
+
+function construct(what) {
+ return new what();
+}
+
+for (var i = 0; i < 3; ++i) {
+ shouldBe("construct(Foo).field", "'foo'");
+}
+
+for (var i = 0; i < 3; ++i) {
+ shouldBe("construct(Foo).field", "'foo'");
+ shouldBe("construct(Bar).field", "'bar'");
+ shouldBe("construct(Baz).field", "'baz'");
+}
+
+var successfullyParsed = true;
Modified: trunk/Source/_javascript_Core/ChangeLog (90876 => 90877)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-13 01:46:09 UTC (rev 90877)
@@ -1,3 +1,38 @@
+2011-07-12 Filip Pizlo <[email protected]>
+
+ DFG JIT does not implement op_construct.
+ https://bugs.webkit.org/show_bug.cgi?id=64066
+
+ Reviewed by Gavin Barraclough.
+
+ This is a fixed implementation of op_construct. Constructor calls are implemented
+ by reusing almost all of the code for Call, with care taken to make sure that
+ where the are differences (like selecting different code blocks), those differences
+ are respected. The two fixes over the last patch are: (1) make sure the
+ CodeBlock::unlinkCalls respects differences between Call and Construct, and (2)
+ make sure that virtualFor() in DFGOperations respects the CodeSpecializationKind
+ (either CodeForCall or CodeForConstruct) when invoking the compiler.
+
+ * dfg/DFGAliasTracker.h:
+ (JSC::DFG::AliasTracker::recordConstruct):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addCall):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::emitCall):
+ * dfg/DFGNode.h:
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGRepatch.cpp:
+ (JSC::DFG::dfgLinkFor):
+ * dfg/DFGRepatch.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/CodeBlock.cpp:
+ (JSC::CodeBlock::unlinkCalls):
+
2011-07-12 Oliver Hunt <[email protected]>
Overzealous type validation in method_check
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (90876 => 90877)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-07-13 01:46:09 UTC (rev 90877)
@@ -1751,7 +1751,7 @@
continue;
if (getJITCode().jitType() == JITCode::DFGJIT) {
#if ENABLE(DFG_JIT)
- repatchBuffer.relink(CodeLocationCall(m_callLinkInfos[i].callReturnLocation), operationLinkCall);
+ repatchBuffer.relink(CodeLocationCall(m_callLinkInfos[i].callReturnLocation), m_callLinkInfos[i].isCall ? operationLinkCall : operationLinkConstruct);
#else
ASSERT_NOT_REACHED();
#endif
Modified: trunk/Source/_javascript_Core/dfg/DFGAliasTracker.h (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGAliasTracker.h 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGAliasTracker.h 2011-07-13 01:46:09 UTC (rev 90877)
@@ -107,6 +107,12 @@
m_candidateAliasGetByVal = NoNode;
}
+ void recordConstruct(NodeIndex construct)
+ {
+ ASSERT_UNUSED(construct, m_graph[construct].op == Construct);
+ m_candidateAliasGetByVal = NoNode;
+ }
+
private:
// This method returns true for arguments:
// - (X, X)
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2011-07-13 01:46:09 UTC (rev 90877)
@@ -411,6 +411,23 @@
m_graph.m_varArgChildren.append(child);
m_numPassedVarArgs++;
}
+
+ NodeIndex addCall(Interpreter* interpreter, Instruction* currentInstruction, NodeType op)
+ {
+ addVarArgChild(get(currentInstruction[1].u.operand));
+ int argCount = currentInstruction[2].u.operand;
+ int registerOffset = currentInstruction[3].u.operand;
+ int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize;
+ for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++)
+ addVarArgChild(get(argIdx));
+ NodeIndex call = addToGraph(Node::VarArg, op);
+ Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);
+ if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
+ set(putInstruction[1].u.operand, call);
+ if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots)
+ m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount;
+ return call;
+ }
void predictArray(NodeIndex nodeIndex)
{
@@ -1101,27 +1118,18 @@
}
case op_call: {
- addVarArgChild(get(currentInstruction[1].u.operand));
- int argCount = currentInstruction[2].u.operand;
- int registerOffset = currentInstruction[3].u.operand;
- int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize;
- for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++)
- addVarArgChild(get(argIdx));
- NodeIndex call = addToGraph(Node::VarArg, Call);
+ NodeIndex call = addCall(interpreter, currentInstruction, Call);
aliases.recordCall(call);
- Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);
- if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
- set(putInstruction[1].u.operand, call);
- if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots)
- m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount;
NEXT_OPCODE(op_call);
}
+ case op_construct: {
+ NodeIndex construct = addCall(interpreter, currentInstruction, Construct);
+ aliases.recordConstruct(construct);
+ NEXT_OPCODE(op_construct);
+ }
+
case op_call_put_result: {
-#if !ASSERT_DISABLED
- Instruction* callInstruction = currentInstruction - OPCODE_LENGTH(op_call);
- ASSERT(interpreter->getOpcodeID(callInstruction->u.opcode) == op_call);
-#endif
NEXT_OPCODE(op_call_put_result);
}
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-13 01:46:09 UTC (rev 90877)
@@ -470,6 +470,18 @@
void JITCodeGenerator::emitCall(Node& node)
{
+ P_DFGOperation_E slowCallFunction;
+ bool isCall;
+
+ if (node.op == Call) {
+ slowCallFunction = operationLinkCall;
+ isCall = true;
+ } else {
+ ASSERT(node.op == Construct);
+ slowCallFunction = operationLinkConstruct;
+ isCall = false;
+ }
+
NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
JSValueOperand callee(this, calleeNodeIndex);
GPRReg calleeGPR = callee.gpr();
@@ -501,14 +513,7 @@
m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx));
}
- switch (node.op) {
- case Call:
- m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
- break;
-
- default:
- ASSERT_NOT_REACHED();
- }
+ m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
flushRegisters();
@@ -518,16 +523,9 @@
JITCompiler::DataLabelPtr targetToCheck;
JITCompiler::Jump slowPath;
- switch (node.op) {
- case Call:
- slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
- m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
- m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain));
- break;
-
- default:
- ASSERT_NOT_REACHED();
- }
+ slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
+ m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
+ m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain));
m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
@@ -539,7 +537,7 @@
slowPath.link(&m_jit);
m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(operationLinkCall, m_jit.graph()[m_compileIndex].exceptionInfo);
+ JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, m_jit.graph()[m_compileIndex].exceptionInfo);
m_jit.move(Imm32(numArgs), GPRInfo::regT1);
m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), m_jit.graph()[m_compileIndex].exceptionInfo);
@@ -550,7 +548,7 @@
jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
- m_jit.addJSCall(fastCall, slowCall, targetToCheck, true, m_jit.graph()[m_compileIndex].exceptionInfo);
+ m_jit.addJSCall(fastCall, slowCall, targetToCheck, isCall, m_jit.graph()[m_compileIndex].exceptionInfo);
}
#ifndef NDEBUG
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2011-07-13 01:46:09 UTC (rev 90877)
@@ -142,6 +142,7 @@
\
/* Calls. */\
macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
+ macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
\
/* Nodes for misc operations. */\
macro(Breakpoint, NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-13 01:46:09 UTC (rev 90877)
@@ -1068,6 +1068,7 @@
break;
case Call:
+ case Construct:
emitCall(node);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2011-07-13 01:46:09 UTC (rev 90877)
@@ -431,97 +431,145 @@
return JSValue::encode(exec->globalData().hostCallReturnValue);
}
-static void* handleHostCall(ExecState* execCallee, JSValue callee)
+static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
JSGlobalData* globalData = &exec->globalData();
- CallData callData;
- CallType callType = getCallData(callee, callData);
+ if (kind == CodeForCall) {
+ CallData callData;
+ CallType callType = getCallData(callee, callData);
- ASSERT(callType != CallTypeJS);
+ ASSERT(callType != CallTypeJS);
- if (callType == CallTypeHost) {
- if (!globalData->interpreter->registerFile().grow(execCallee->registers())) {
- globalData->exception = createStackOverflowError(exec);
- return 0;
+ if (callType == CallTypeHost) {
+ if (!globalData->interpreter->registerFile().grow(execCallee->registers())) {
+ globalData->exception = createStackOverflowError(exec);
+ return 0;
+ }
+
+ execCallee->setScopeChain(exec->scopeChain());
+
+ globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
+
+ if (globalData->exception)
+ return 0;
+ return reinterpret_cast<void*>(getHostCallReturnValue);
}
+
+ ASSERT(callType == CallTypeNone);
+ } else {
+ ASSERT(kind == CodeForConstruct);
- execCallee->setScopeChain(exec->scopeChain());
+ ConstructData constructData;
+ ConstructType constructType = getConstructData(callee, constructData);
- globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
+ ASSERT(constructType = ConstructTypeJS);
- if (globalData->exception)
- return 0;
- return reinterpret_cast<void*>(getHostCallReturnValue);
+ if (constructType == ConstructTypeHost) {
+ if (!globalData->interpreter->registerFile().grow(execCallee->registers())) {
+ globalData->exception = createStackOverflowError(exec);
+ return 0;
+ }
+
+ execCallee->setScopeChain(exec->scopeChain());
+
+ globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
+
+ if (globalData->exception)
+ return 0;
+ return reinterpret_cast<void*>(getHostCallReturnValue);
+ }
+
+ ASSERT(constructType == ConstructTypeNone);
}
-
- ASSERT(callType == CallTypeNone);
exec->globalData().exception = createNotAFunctionError(exec, callee);
return 0;
}
-void* operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr);
-FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall);
-void* operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
+inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind)
{
ExecState* exec = execCallee->callerFrame();
JSGlobalData* globalData = &exec->globalData();
JSValue calleeAsValue = execCallee->calleeAsValue();
JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
if (!calleeAsFunctionCell)
- return handleHostCall(execCallee, calleeAsValue);
+ return handleHostCall(execCallee, calleeAsValue, kind);
JSFunction* callee = asFunction(calleeAsFunctionCell);
ExecutableBase* executable = callee->executable();
MacroAssemblerCodePtr codePtr;
CodeBlock* codeBlock = 0;
if (executable->isHostFunction())
- codePtr = executable->generatedJITCodeForCall().addressForCall();
+ codePtr = executable->generatedJITCodeFor(kind).addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->compileForCall(exec, callee->scope());
+ JSObject* error = functionExecutable->compileFor(exec, callee->scope(), kind);
if (error) {
globalData->exception = createStackOverflowError(exec);
return 0;
}
- codeBlock = &functionExecutable->generatedBytecodeForCall();
+ codeBlock = &functionExecutable->generatedBytecodeFor(kind);
if (execCallee->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
- codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
+ codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
else
- codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck();
+ codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
execCallee->setScopeChain(callee->scope());
}
CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress);
if (!callLinkInfo.seenOnce())
callLinkInfo.setSeen();
else
- dfgLinkCall(execCallee, callLinkInfo, codeBlock, callee, codePtr);
+ dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
return codePtr.executableAddress();
}
-void* operationVirtualCall(ExecState* execCallee)
+void* operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall);
+void* operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
{
+ return linkFor(execCallee, returnAddress, CodeForCall);
+}
+
+void* operationLinkConstructWithReturnAddress(ExecState*, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkConstruct);
+void* operationLinkConstructWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
+{
+ return linkFor(execCallee, returnAddress, CodeForConstruct);
+}
+
+inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
+{
ExecState* exec = execCallee->callerFrame();
JSGlobalData* globalData = &exec->globalData();
JSValue calleeAsValue = execCallee->calleeAsValue();
JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
if (UNLIKELY(!calleeAsFunctionCell))
- return handleHostCall(execCallee, calleeAsValue);
+ return handleHostCall(execCallee, calleeAsValue, kind);
JSFunction* function = asFunction(calleeAsFunctionCell);
ExecutableBase* executable = function->executable();
- if (UNLIKELY(!executable->hasJITCodeForCall())) {
+ if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- JSObject* error = functionExecutable->compileForCall(exec, function->scope());
+ JSObject* error = functionExecutable->compileFor(exec, function->scope(), kind);
if (error) {
exec->globalData().exception = error;
return 0;
}
}
execCallee->setScopeChain(function->scopeUnchecked());
- return executable->generatedJITCodeForCallWithArityCheck().executableAddress();
+ return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress();
}
+void* operationVirtualCall(ExecState* execCallee)
+{
+ return virtualFor(execCallee, CodeForCall);
+}
+
+void* operationVirtualConstruct(ExecState* execCallee)
+{
+ return virtualFor(execCallee, CodeForConstruct);
+}
+
EncodedJSValue operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, EncodedJSValue encodedPrototype)
{
JSValue value = JSValue::decode(encodedValue);
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.h 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h 2011-07-13 01:46:09 UTC (rev 90877)
@@ -48,6 +48,7 @@
typedef void (*V_DFGOperation_EJJP)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
typedef void (*V_DFGOperation_EJJI)(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*);
typedef double (*D_DFGOperation_DD)(double, double);
+typedef void *(*P_DFGOperation_E)(ExecState*);
// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
EncodedJSValue operationConvertThis(ExecState*, EncodedJSValue encodedOp1);
@@ -83,6 +84,8 @@
bool operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
void* operationVirtualCall(ExecState*);
void* operationLinkCall(ExecState*);
+void* operationVirtualConstruct(ExecState*);
+void* operationLinkConstruct(ExecState*);
// This method is used to lookup an exception hander, keyed by faultLocation, which is
// the return location from one of the calls out to one of the helper operations above.
Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp 2011-07-13 01:46:09 UTC (rev 90877)
@@ -434,7 +434,7 @@
dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriatePutByIdFunction(slot, putKind));
}
-void dfgLinkCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr)
+void dfgLinkFor(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr, CodeSpecializationKind kind)
{
CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
@@ -446,7 +446,12 @@
repatchBuffer.relink(callLinkInfo.hotPathOther, codePtr);
}
- repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall);
+ if (kind == CodeForCall) {
+ repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall);
+ return;
+ }
+ ASSERT(kind == CodeForConstruct);
+ repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualConstruct);
}
} } // namespace JSC::DFG
Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.h (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGRepatch.h 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.h 2011-07-13 01:46:09 UTC (rev 90877)
@@ -37,7 +37,7 @@
void dfgRepatchGetMethod(ExecState*, JSValue, const Identifier&, const PropertySlot&, MethodCallLinkInfo&);
void dfgBuildGetByIDList(ExecState*, JSValue, const Identifier&, const PropertySlot&, StructureStubInfo&);
void dfgRepatchPutByID(ExecState*, JSValue, const Identifier&, const PutPropertySlot&, StructureStubInfo&, PutKind);
-void dfgLinkCall(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr);
+void dfgLinkFor(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr, CodeSpecializationKind);
} } // namespace JSC::DFG
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (90876 => 90877)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-13 01:33:50 UTC (rev 90876)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-13 01:46:09 UTC (rev 90877)
@@ -1143,6 +1143,7 @@
break;
case Call:
+ case Construct:
emitCall(node);
break;
}