https://bugs.webkit.org/show_bug.cgi?id=64181
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Jul 2011 23:40:39 +0000 (23:40 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Jul 2011 23:40:39 +0000 (23:40 +0000)
REGRESSION (r90602): Gmail doesn't load

Rolling out r90601, r90602.

* dfg/DFGAliasTracker.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addVarArgChild):
(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::tryCacheGetByID):
(JSC::DFG::dfgLinkCall):
* dfg/DFGRepatch.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* runtime/JSObject.h:
(JSC::JSObject::isUsingInlineStorage):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@90673 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGAliasTracker.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGOperations.h
Source/JavaScriptCore/dfg/DFGRepatch.cpp
Source/JavaScriptCore/dfg/DFGRepatch.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/runtime/JSObject.h

index b2f0455..60b477b 100644 (file)
@@ -1,3 +1,30 @@
+2011-07-08  Gavin Barraclough  <barraclough@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=64181
+        REGRESSION (r90602): Gmail doesn't load
+
+        Rolling out r90601, r90602.
+
+        * dfg/DFGAliasTracker.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addVarArgChild):
+        (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::tryCacheGetByID):
+        (JSC::DFG::dfgLinkCall):
+        * dfg/DFGRepatch.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * runtime/JSObject.h:
+        (JSC::JSObject::isUsingInlineStorage):
+
 2011-07-08  Kalev Lember  <kalev@smartlink.ee>
 
         Reviewed by Adam Roben.
index 00390e0..d0eed99 100644 (file)
@@ -107,12 +107,6 @@ public:
         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)
index 537a09b..1d25f6c 100644 (file)
@@ -411,23 +411,6 @@ private:
         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)
     {
@@ -1118,18 +1101,27 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         }
             
         case op_call: {
-            NodeIndex call = addCall(interpreter, currentInstruction, 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);
             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);
         }
 
index c34cfe3..50d0274 100644 (file)
@@ -470,18 +470,6 @@ void JITCodeGenerator::cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, unsigne
 
 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();
@@ -513,7 +501,14 @@ void JITCodeGenerator::emitCall(Node& node)
         m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx));
     }
     
-    m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
+    switch (node.op) {
+    case Call:
+        m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
+        break;
+        
+    default:
+        ASSERT_NOT_REACHED();
+    }
     
     flushRegisters();
     
@@ -523,9 +518,16 @@ void JITCodeGenerator::emitCall(Node& node)
     JITCompiler::DataLabelPtr targetToCheck;
     JITCompiler::Jump slowPath;
     
-    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));
+    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();
+    }
 
     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
     
@@ -537,7 +539,7 @@ void JITCodeGenerator::emitCall(Node& node)
     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(slowCallFunction, m_jit.graph()[m_compileIndex].exceptionInfo);
+    JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(operationLinkCall, 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);
@@ -548,7 +550,7 @@ void JITCodeGenerator::emitCall(Node& node)
     
     jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
     
-    m_jit.addJSCall(fastCall, slowCall, targetToCheck, isCall, m_jit.graph()[m_compileIndex].exceptionInfo);
+    m_jit.addJSCall(fastCall, slowCall, targetToCheck, true, m_jit.graph()[m_compileIndex].exceptionInfo);
 }
 
 #ifndef NDEBUG
index 1ae35e0..b2d9da2 100644 (file)
@@ -142,7 +142,6 @@ typedef uint32_t ExceptionInfo;
     \
     /* Calls. */\
     macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
-    macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
     \
     /* Nodes for misc operations. */\
     macro(Breakpoint, NodeMustGenerate) \
index ac4d0a5..652e8ad 100644 (file)
@@ -1068,7 +1068,6 @@ void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator, No
         break;
         
     case Call:
-    case Construct:
         emitCall(node);
         break;
     }
index 0cf2d76..151270c 100644 (file)
@@ -431,124 +431,86 @@ EncodedJSValue getHostCallReturnValueWithExecState(ExecState* exec)
     return JSValue::encode(exec->globalData().hostCallReturnValue);
 }
 
-static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
+static void* handleHostCall(ExecState* execCallee, JSValue callee)
 {
     ExecState* exec = execCallee->callerFrame();
     JSGlobalData* globalData = &exec->globalData();
-    if (kind == CodeForCall) {
-        CallData callData;
-        CallType callType = getCallData(callee, callData);
+    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;
-            }
-        
-            execCallee->setScopeChain(exec->scopeChain());
-        
-            globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
-        
-            if (globalData->exception)
-                return 0;
-            return reinterpret_cast<void*>(getHostCallReturnValue);
+    if (callType == CallTypeHost) {
+        if (!globalData->interpreter->registerFile().grow(execCallee->registers())) {
+            globalData->exception = createStackOverflowError(exec);
+            return 0;
         }
-    
-        ASSERT(callType == CallTypeNone);
-    } else {
-        ASSERT(kind == CodeForConstruct);
         
-        ConstructData constructData;
-        ConstructType constructType = getConstructData(callee, constructData);
+        execCallee->setScopeChain(exec->scopeChain());
         
-        ASSERT(constructType = ConstructTypeJS);
-        
-        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);
-        }
+        globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
         
-        ASSERT(constructType == ConstructTypeNone);
+        if (globalData->exception)
+            return 0;
+        return reinterpret_cast<void*>(getHostCallReturnValue);
     }
+    
+    ASSERT(callType == CallTypeNone);
     exec->globalData().exception = createNotAFunctionError(exec, callee);
     return 0;
 }
 
-inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind)
+void* operationLinkCallWithReturnAddress(ExecState*, ReturnAddressPtr);
+FUNCTION_WRAPPER_WITH_ARG2_RETURN_ADDRESS(operationLinkCall);
+void* operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
 {
     ExecState* exec = execCallee->callerFrame();
     JSGlobalData* globalData = &exec->globalData();
     JSValue calleeAsValue = execCallee->calleeAsValue();
     JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
     if (!calleeAsFunctionCell)
-        return handleHostCall(execCallee, calleeAsValue, kind);
+        return handleHostCall(execCallee, calleeAsValue);
     JSFunction* callee = asFunction(calleeAsFunctionCell);
     ExecutableBase* executable = callee->executable();
     
     MacroAssemblerCodePtr codePtr;
     CodeBlock* codeBlock = 0;
     if (executable->isHostFunction())
-        codePtr = executable->generatedJITCodeFor(kind).addressForCall();
+        codePtr = executable->generatedJITCodeForCall().addressForCall();
     else {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
-        JSObject* error = functionExecutable->compileFor(exec, callee->scope(), kind);
+        JSObject* error = functionExecutable->compileForCall(exec, callee->scope());
         if (error) {
             globalData->exception = createStackOverflowError(exec);
             return 0;
         }
-        codeBlock = &functionExecutable->generatedBytecodeFor(kind);
+        codeBlock = &functionExecutable->generatedBytecodeForCall();
         if (execCallee->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
-            codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
+            codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
         else
-            codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
+            codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck();
         execCallee->setScopeChain(callee->scope());
     }
     CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress);
     if (!callLinkInfo.seenOnce())
         callLinkInfo.setSeen();
     else
-        dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
+        dfgLinkCall(execCallee, callLinkInfo, codeBlock, callee, codePtr);
     return codePtr.executableAddress();
 }
 
-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)
+void* operationVirtualCall(ExecState* execCallee)
 {
     ExecState* exec = execCallee->callerFrame();
     JSGlobalData* globalData = &exec->globalData();
     JSValue calleeAsValue = execCallee->calleeAsValue();
     JSCell* calleeAsFunctionCell = getJSFunction(*globalData, calleeAsValue);
     if (UNLIKELY(!calleeAsFunctionCell))
-        return handleHostCall(execCallee, calleeAsValue, kind);
+        return handleHostCall(execCallee, calleeAsValue);
     
     JSFunction* function = asFunction(calleeAsFunctionCell);
     ExecutableBase* executable = function->executable();
-    if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
+    if (UNLIKELY(!executable->hasJITCodeForCall())) {
         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
         JSObject* error = functionExecutable->compileForCall(exec, function->scope());
         if (error) {
@@ -557,17 +519,7 @@ inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
         }
     }
     execCallee->setScopeChain(function->scopeUnchecked());
-    return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress();
-}
-
-void* operationVirtualCall(ExecState* execCallee)
-{
-    return virtualFor(execCallee, CodeForCall);
-}
-
-void* operationVirtualConstruct(ExecState* execCallee)
-{
-    return virtualFor(execCallee, CodeForConstruct);
+    return executable->generatedJITCodeForCallWithArityCheck().executableAddress();
 }
 
 EncodedJSValue operationInstanceOf(ExecState* exec, EncodedJSValue encodedValue, EncodedJSValue encodedBase, EncodedJSValue encodedPrototype)
index 69698bb..a894d8e 100644 (file)
@@ -48,7 +48,6 @@ typedef void (*V_DFGOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue,
 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);
@@ -84,8 +83,6 @@ bool operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue en
 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.
index cdc52c3..ccaed44 100644 (file)
@@ -56,44 +56,6 @@ static void dfgRepatchByIdSelfAccess(CodeBlock* codeBlock, StructureStubInfo& st
         repatchBuffer.repatch(stubInfo.callReturnLocation.dataLabel32AtOffset(stubInfo.u.unset.deltaCallToLoadOrStore), sizeof(JSValue) * offset);
 }
 
-static void emitRestoreScratch(MacroAssembler& stubJit, bool needToRestoreScratch, GPRReg scratchGPR, MacroAssembler::Jump& success, MacroAssembler::Jump& fail, MacroAssembler::Jump failureCase1, MacroAssembler::Jump failureCase2)
-{
-    if (needToRestoreScratch) {
-        stubJit.pop(scratchGPR);
-        
-        success = stubJit.jump();
-        
-        // link failure cases here, so we can pop scratchGPR, and then jump back.
-        failureCase1.link(&stubJit);
-        failureCase2.link(&stubJit);
-        
-        stubJit.pop(scratchGPR);
-        
-        fail = stubJit.jump();
-        return;
-    }
-    
-    success = stubJit.jump();
-}
-
-static void linkRestoreScratch(LinkBuffer& patchBuffer, bool needToRestoreScratch, StructureStubInfo& stubInfo, MacroAssembler::Jump& success, MacroAssembler::Jump& fail, MacroAssembler::Jump failureCase1, MacroAssembler::Jump failureCase2)
-{
-    CodeLocationLabel slowCaseBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase);
-    
-    patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
-        
-    patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
-    
-    if (needToRestoreScratch) {
-        patchBuffer.link(fail, slowCaseBegin);
-        return;
-    }
-    
-    // link failure cases directly back to normal path
-    patchBuffer.link(failureCase1, slowCaseBegin);
-    patchBuffer.link(failureCase2, slowCaseBegin);
-}
-            
 static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo& stubInfo)
 {
     // FIXME: Write a test that proves we need to check for recursion here just
@@ -126,11 +88,34 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
 
         MacroAssembler::Jump success, fail;
         
-        emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCase1, failureCase2);
+        if (needToRestoreScratch) {
+            stubJit.pop(scratchGPR);
+            
+            success = stubJit.jump();
+            
+            // link failure cases here, so we can pop scratchGPR, and then jump back.
+            failureCase1.link(&stubJit);
+            failureCase2.link(&stubJit);
+            
+            stubJit.pop(scratchGPR);
+            
+            fail = stubJit.jump();
+        } else
+            success = stubJit.jump();
         
         LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock->executablePool());
         
-        linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCase1, failureCase2);
+        CodeLocationLabel slowCaseBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase);
+        
+        patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone));
+        
+        if (needToRestoreScratch)
+            patchBuffer.link(fail, slowCaseBegin);
+        else {
+            // link failure cases directly back to normal path
+            patchBuffer.link(failureCase1, slowCaseBegin);
+            patchBuffer.link(failureCase2, slowCaseBegin);
+        }
         
         CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
         stubInfo.stubRoutine = entryLabel;
@@ -165,73 +150,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
         return true;
     }
     
-    if (structure->isDictionary())
-        return false;
-    
-    // Optimize accesses on the direct prototype
-    if (slot.slotBase() == structure->prototypeForLookup(exec)) {
-        if (slot.cachedPropertyType() != PropertySlot::Value)
-            return false;
-        
-        ASSERT(slot.slotBase().isObject());
-        
-        JSObject* slotBaseObject = asObject(slot.slotBase());
-        size_t offset = slot.cachedOffset();
-        
-        if (slotBaseObject->structure()->isDictionary()) {
-            slotBaseObject->flattenDictionaryObject(*globalData);
-            offset = slotBaseObject->structure()->get(*globalData, propertyName);
-        }
-        
-        ASSERT(!structure->isDictionary());
-        ASSERT(!slotBaseObject->structure()->isDictionary());
-        
-        ASSERT(asObject(structure->prototypeForLookup(exec)) == slotBaseObject);
-        
-        GPRReg baseGPR = static_cast<GPRReg>(stubInfo.baseGPR);
-        GPRReg resultGPR = static_cast<GPRReg>(stubInfo.valueGPR);
-        GPRReg scratchGPR = static_cast<GPRReg>(stubInfo.u.unset.scratchGPR);
-        bool needToRestoreScratch = false;
-        
-        MacroAssembler stubJit;
-        
-        if (scratchGPR == InvalidGPRReg) {
-            scratchGPR = JITCodeGenerator::selectScratchGPR(baseGPR, resultGPR);
-            stubJit.push(scratchGPR);
-            needToRestoreScratch = true;
-        }
-        
-        MacroAssembler::Jump failureCase1 = stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(structure));
-        
-        stubJit.move(MacroAssembler::TrustedImmPtr(slotBaseObject), scratchGPR);
-        MacroAssembler::Jump failureCase2 = stubJit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(scratchGPR, JSCell::structureOffset()), MacroAssembler::TrustedImmPtr(slotBaseObject->structure()));
-        
-        if (slotBaseObject->structure()->isUsingInlineStorage())
-            stubJit.loadPtr(MacroAssembler::Address(scratchGPR, JSObject::offsetOfInlineStorage() + offset * sizeof(JSValue)), resultGPR);
-        else
-            stubJit.loadPtr(slotBaseObject->addressOfPropertyAtOffset(offset), resultGPR);
-        
-        MacroAssembler::Jump success, fail;
-        
-        emitRestoreScratch(stubJit, needToRestoreScratch, scratchGPR, success, fail, failureCase1, failureCase2);
-        
-        LinkBuffer patchBuffer(*globalData, &stubJit, codeBlock->executablePool());
-        
-        linkRestoreScratch(patchBuffer, needToRestoreScratch, stubInfo, success, fail, failureCase1, failureCase2);
-        
-        CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
-        stubInfo.stubRoutine = entryLabel;
-        
-        CodeLocationLabel hotPathBegin = stubInfo.hotPathBegin;
-        RepatchBuffer repatchBuffer(codeBlock);
-        repatchBuffer.relink(stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck), entryLabel);
-        repatchBuffer.relink(stubInfo.callReturnLocation, operationGetById);
-        
-        stubInfo.initGetByIdProto(*globalData, codeBlock->ownerExecutable(), structure, slotBaseObject->structure());
-        return true;
-    }
-    
-    // FIXME: should support chain accesses!
+    // FIXME: should support prototype & chain accesses!
     return false;
 }
 
@@ -513,7 +432,7 @@ void dfgRepatchPutByID(ExecState* exec, JSValue baseValue, const Identifier& pro
         dfgRepatchCall(exec->codeBlock(), stubInfo.callReturnLocation, appropriatePutByIdFunction(slot, putKind));
 }
 
-void dfgLinkFor(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr, CodeSpecializationKind kind)
+void dfgLinkCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCodeBlock, JSFunction* callee, MacroAssemblerCodePtr codePtr)
 {
     CodeBlock* callerCodeBlock = exec->callerFrame()->codeBlock();
     
@@ -525,12 +444,7 @@ void dfgLinkFor(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock* calleeCo
         repatchBuffer.relink(callLinkInfo.hotPathOther, codePtr);
     }
     
-    if (kind == CodeForCall) {
-        repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall);
-        return;
-    }
-    ASSERT(kind == CodeForConstruct);
-    repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualConstruct);
+    repatchBuffer.relink(CodeLocationCall(callLinkInfo.callReturnLocation), operationVirtualCall);
 }
 
 } } // namespace JSC::DFG
index 019dd93..6eafefc 100644 (file)
@@ -37,7 +37,7 @@ void dfgRepatchGetByID(ExecState*, JSValue, const Identifier&, const PropertySlo
 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 dfgLinkFor(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr, CodeSpecializationKind);
+void dfgLinkCall(ExecState*, CallLinkInfo&, CodeBlock*, JSFunction* callee, MacroAssemblerCodePtr);
 
 } } // namespace JSC::DFG
 
index df3b700..0aec3e2 100644 (file)
@@ -1145,7 +1145,6 @@ void SpeculativeJIT::compile(Node& node)
         break;
         
     case Call:
-    case Construct:
         emitCall(node);
         break;
     }
index 1d637b4..9a43959 100644 (file)
@@ -219,11 +219,6 @@ namespace JSC {
 
         void allocatePropertyStorage(size_t oldSize, size_t newSize);
         bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage) == static_cast<const void*>(this + 1); }
-        
-        void* addressOfPropertyAtOffset(size_t offset)
-        {
-            return static_cast<void*>(&m_propertyStorage[offset]);
-        }
 
         static const unsigned baseExternalStorageCapacity = 16;