Baseline JIT should have closure call caching
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jan 2013 08:48:18 +0000 (08:48 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Jan 2013 08:48:18 +0000 (08:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=105900

Reviewed by Gavin Barraclough.

This is not a speed-up by itself, but is meant to allow the DFG inliner to
accurately discern between closure calls and non-closure calls, so that it can
do closure call inlining in the future.

* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::computeFromLLInt):
(JSC::CallLinkStatus::computeFor):
* bytecode/CallLinkStatus.h:
(JSC::CallLinkStatus::CallLinkStatus):
(JSC::CallLinkStatus::isClosureCall):
(CallLinkStatus):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleCall):
* jit/JIT.cpp:
(JSC::JIT::linkFor):
(JSC::JIT::linkSlowCall):
* jit/JIT.h:
(JSC::JIT::compileClosureCall):
* jit/JITCall.cpp:
(JSC::JIT::privateCompileClosureCall):
* jit/JITCall32_64.cpp:
(JSC::JIT::privateCompileClosureCall):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* jit/JITStubs.h:
* jit/ThunkGenerators.cpp:
(JSC::linkClosureCallGenerator):
* jit/ThunkGenerators.h:

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

12 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
Source/JavaScriptCore/bytecode/CallLinkStatus.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITCall.cpp
Source/JavaScriptCore/jit/JITCall32_64.cpp
Source/JavaScriptCore/jit/JITStubs.cpp
Source/JavaScriptCore/jit/JITStubs.h
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/jit/ThunkGenerators.h

index 8008bca..f3156ad 100644 (file)
@@ -1,3 +1,39 @@
+2013-01-01  Filip Pizlo  <fpizlo@apple.com>
+
+        Baseline JIT should have closure call caching
+        https://bugs.webkit.org/show_bug.cgi?id=105900
+
+        Reviewed by Gavin Barraclough.
+        
+        This is not a speed-up by itself, but is meant to allow the DFG inliner to
+        accurately discern between closure calls and non-closure calls, so that it can
+        do closure call inlining in the future.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::computeFromLLInt):
+        (JSC::CallLinkStatus::computeFor):
+        * bytecode/CallLinkStatus.h:
+        (JSC::CallLinkStatus::CallLinkStatus):
+        (JSC::CallLinkStatus::isClosureCall):
+        (CallLinkStatus):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleCall):
+        * jit/JIT.cpp:
+        (JSC::JIT::linkFor):
+        (JSC::JIT::linkSlowCall):
+        * jit/JIT.h:
+        (JSC::JIT::compileClosureCall):
+        * jit/JITCall.cpp:
+        (JSC::JIT::privateCompileClosureCall):
+        * jit/JITCall32_64.cpp:
+        (JSC::JIT::privateCompileClosureCall):
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+        * jit/JITStubs.h:
+        * jit/ThunkGenerators.cpp:
+        (JSC::linkClosureCallGenerator):
+        * jit/ThunkGenerators.h:
+
 2013-01-01  Dan Bernstein  <mitz@apple.com>
 
         <rdar://problem/12942239> Update copyright strings
index 7f9e9ee..da7af8a 100644 (file)
@@ -39,9 +39,9 @@ CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsign
     Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
     LLIntCallLinkInfo* callLinkInfo = instruction[4].u.callLinkInfo;
     
-    return CallLinkStatus(callLinkInfo->lastSeenCallee.get(), false);
+    return CallLinkStatus(callLinkInfo->lastSeenCallee.get(), false, false);
 #else
-    return CallLinkStatus(0, false);
+    return CallLinkStatus(0, false, false);
 #endif
 }
 
@@ -56,13 +56,14 @@ CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned byt
     if (profiledBlock->couldTakeSlowCase(bytecodeIndex))
         return CallLinkStatus(0, true);
     
-    JSFunction* target = profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get();
+    CallLinkInfo& callLinkInfo = profiledBlock->getCallLinkInfo(bytecodeIndex);
+    JSFunction* target = callLinkInfo.lastSeenCallee.get();
     if (!target)
         return computeFromLLInt(profiledBlock, bytecodeIndex);
     
-    return CallLinkStatus(target, false);
+    return CallLinkStatus(target, false, !!callLinkInfo.stub);
 #else
-    return CallLinkStatus(0, false);
+    return CallLinkStatus(0, false, false);
 #endif
 }
 
index 5f72019..8dd49eb 100644 (file)
@@ -36,12 +36,14 @@ public:
     CallLinkStatus()
         : m_callTarget(0)
         , m_couldTakeSlowPath(false)
+        , m_isClosureCall(false)
     {
     }
     
-    CallLinkStatus(JSFunction* callTarget, bool couldTakeSlowPath)
+    CallLinkStatus(JSFunction* callTarget, bool couldTakeSlowPath, bool isClosureCall = false)
         : m_callTarget(callTarget)
         , m_couldTakeSlowPath(couldTakeSlowPath)
+        , m_isClosureCall(isClosureCall)
     {
     }
     
@@ -52,6 +54,7 @@ public:
     bool operator!() const { return !isSet(); }
     
     bool couldTakeSlowPath() const { return m_couldTakeSlowPath; }
+    bool isClosureCall() const { return m_isClosureCall; }
     
     JSFunction* callTarget() const { return m_callTarget; }
     
@@ -60,6 +63,7 @@ private:
     
     JSFunction* m_callTarget;
     bool m_couldTakeSlowPath;
+    bool m_isClosureCall;
 };
 
 } // namespace JSC
index fa19f50..1a76b90 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1316,6 +1316,7 @@ void ByteCodeParser::handleCall(Interpreter* interpreter, Instruction* currentIn
                 m_graph.valueOfInternalFunctionConstant(callTarget));
 #endif
     } else if (callLinkStatus.isSet() && !callLinkStatus.couldTakeSlowPath()
+               && !callLinkStatus.isClosureCall() // We will eventually optimize this, I promise.
                && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache)) {
         callType = LinkedFunction;
 #if DFG_ENABLE(DEBUG_VERBOSE)
index e7fbf72..dd38097 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -870,6 +870,13 @@ void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* cal
 
     // Patch the slow patch so we do not continue to try to link.
     if (kind == CodeForCall) {
+        ASSERT(callLinkInfo->callType == CallLinkInfo::Call
+               || callLinkInfo->callType == CallLinkInfo::CallVarargs);
+        if (callLinkInfo->callType == CallLinkInfo::Call) {
+            repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->getCTIStub(linkClosureCallGenerator).code());
+            return;
+        }
+
         repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->getCTIStub(virtualCallGenerator).code());
         return;
     }
@@ -878,6 +885,13 @@ void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* cal
     repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->getCTIStub(virtualConstructGenerator).code());
 }
 
+void JIT::linkSlowCall(CodeBlock* callerCodeBlock, CallLinkInfo* callLinkInfo)
+{
+    RepatchBuffer repatchBuffer(callerCodeBlock);
+
+    repatchBuffer.relink(callLinkInfo->callReturnLocation, callerCodeBlock->globalData()->getCTIStub(virtualCallGenerator).code());
+}
+
 } // namespace JSC
 
 #endif // ENABLE(JIT)
index 8acaaa4..f6edd3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -304,6 +304,13 @@ namespace JSC {
         {
             return JIT(globalData, codeBlock).privateCompile(functionEntryArityCheck, effort);
         }
+        
+        static void compileClosureCall(JSGlobalData* globalData, CallLinkInfo* callLinkInfo, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
+        {
+            JIT jit(globalData, callerCodeBlock);
+            jit.m_bytecodeOffset = callLinkInfo->codeOrigin.bytecodeIndex;
+            jit.privateCompileClosureCall(callLinkInfo, calleeCodeBlock, expectedStructure, expectedExecutable, codePtr);
+        }
 
         static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
         {
@@ -388,6 +395,7 @@ namespace JSC {
         }
 
         static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, JSGlobalData*, CodeSpecializationKind);
+        static void linkSlowCall(CodeBlock* callerCodeBlock, CallLinkInfo*);
 
     private:
         JIT(JSGlobalData*, CodeBlock* = 0);
@@ -397,6 +405,8 @@ namespace JSC {
         void privateCompileSlowCases();
         JITCode privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffort);
         
+        void privateCompileClosureCall(CallLinkInfo*, CodeBlock* calleeCodeBlock, Structure*, ExecutableBase*, MacroAssemblerCodePtr);
+        
         void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, ReturnAddressPtr, CallFrame*);
         void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset);
         void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, CallFrame*);
index e4848c0..8ce3b90 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
+#include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
+#include "ThunkGenerators.h"
 
 #ifndef NDEBUG
 #include <stdio.h>
@@ -221,6 +223,52 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction*, Vector<SlowCase
     sampleCodeBlock(m_codeBlock);
 }
 
+void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
+{
+    JumpList slowCases;
+    
+    slowCases.append(branchTestPtr(NonZero, regT0, tagMaskRegister));
+    slowCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(expectedStructure)));
+    slowCases.append(branchPtr(NotEqual, Address(regT0, JSFunction::offsetOfExecutable()), TrustedImmPtr(expectedExecutable)));
+    
+    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT1);
+    emitPutToCallFrameHeader(regT1, JSStack::ScopeChain);
+    
+    Call call = nearCall();
+    Jump done = jump();
+    
+    slowCases.link(this);
+    move(TrustedImmPtr(callLinkInfo->callReturnLocation.executableAddress()), regT2);
+    restoreReturnAddressBeforeReturn(regT2);
+    Jump slow = jump();
+    
+    LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+    
+    patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
+    patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
+    patchBuffer.link(slow, CodeLocationLabel(m_globalData->getCTIStub(virtualCallGenerator).code()));
+    
+    RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
+        FINALIZE_CODE(
+            patchBuffer,
+            ("Baseline closure call stub for %s, return point %p, target %p (%s)",
+                toCString(*m_codeBlock).data(),
+                callLinkInfo->hotPathOther.labelAtOffset(0).executableAddress(),
+                codePtr.executableAddress(),
+                toCString(*calleeCodeBlock).data())),
+        *m_globalData, m_codeBlock->ownerExecutable(), expectedStructure, expectedExecutable,
+        callLinkInfo->codeOrigin));
+    
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    
+    repatchBuffer.replaceWithJump(
+        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
+        CodeLocationLabel(stubRoutine->code().code()));
+    repatchBuffer.relink(callLinkInfo->callReturnLocation, m_globalData->getCTIStub(virtualCallGenerator).code());
+    
+    callLinkInfo->stub = stubRoutine.release();
+}
+
 } // namespace JSC
 
 #endif // USE(JSVALUE64)
index ef43dc4..82bda71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,6 +36,7 @@
 #include "JITStubCall.h"
 #include "JSArray.h"
 #include "JSFunction.h"
+#include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
 
@@ -302,6 +303,52 @@ void JIT::compileOpCallSlowCase(OpcodeID opcodeID, Instruction*, Vector<SlowCase
     sampleCodeBlock(m_codeBlock);
 }
 
+void JIT::privateCompileClosureCall(CallLinkInfo* callLinkInfo, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
+{
+    JumpList slowCases;
+
+    slowCases.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
+    slowCases.append(branchPtr(NotEqual, Address(regT0, JSCell::structureOffset()), TrustedImmPtr(expectedStructure)));
+    slowCases.append(branchPtr(NotEqual, Address(regT0, JSFunction::offsetOfExecutable()), TrustedImmPtr(expectedExecutable)));
+    
+    loadPtr(Address(regT0, JSFunction::offsetOfScopeChain()), regT1);
+    emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain);
+    
+    Call call = nearCall();
+    Jump done = jump();
+    
+    slowCases.link(this);
+    move(TrustedImmPtr(callLinkInfo->callReturnLocation.executableAddress()), regT2);
+    restoreReturnAddressBeforeReturn(regT2);
+    Jump slow = jump();
+    
+    LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock);
+    
+    patchBuffer.link(call, FunctionPtr(codePtr.executableAddress()));
+    patchBuffer.link(done, callLinkInfo->hotPathOther.labelAtOffset(0));
+    patchBuffer.link(slow, CodeLocationLabel(m_globalData->getCTIStub(virtualCallGenerator).code()));
+    
+    RefPtr<ClosureCallStubRoutine> stubRoutine = adoptRef(new ClosureCallStubRoutine(
+        FINALIZE_CODE(
+            patchBuffer,
+            ("Baseline closure call stub for %s, return point %p, target %p (%s)",
+                toCString(*m_codeBlock).data(),
+                callLinkInfo->hotPathOther.labelAtOffset(0).executableAddress(),
+                codePtr.executableAddress(),
+                toCString(*calleeCodeBlock).data())),
+        *m_globalData, m_codeBlock->ownerExecutable(), expectedStructure, expectedExecutable,
+        callLinkInfo->codeOrigin));
+    
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    
+    repatchBuffer.replaceWithJump(
+        RepatchBuffer::startOfBranchPtrWithPatchOnRegister(callLinkInfo->hotPathBegin),
+        CodeLocationLabel(stubRoutine->code().code()));
+    repatchBuffer.relink(callLinkInfo->callReturnLocation, m_globalData->getCTIStub(virtualCallGenerator).code());
+    
+    callLinkInfo->stub = stubRoutine.release();
+}
+
 } // namespace JSC
 
 #endif // USE(JSVALUE32_64)
index feaa386..e48c5e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
  * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
  *
@@ -2109,6 +2109,68 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
     return result;
 }
 
+DEFINE_STUB_FUNCTION(void*, vm_lazyLinkClosureCall)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    
+    CodeBlock* callerCodeBlock = callFrame->callerFrame()->codeBlock();
+    JSGlobalData* globalData = callerCodeBlock->globalData();
+    CallLinkInfo* callLinkInfo = &callerCodeBlock->getCallLinkInfo(callFrame->returnPC());
+    JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
+    ExecutableBase* executable = callee->executable();
+    Structure* structure = callee->structure();
+    
+    ASSERT(callLinkInfo->callType == CallLinkInfo::Call);
+    ASSERT(callLinkInfo->isLinked());
+    ASSERT(callLinkInfo->callee);
+    ASSERT(callee != callLinkInfo->callee.get());
+    
+    bool shouldLink = false;
+    CodeBlock* calleeCodeBlock = 0;
+    MacroAssemblerCodePtr codePtr;
+    
+    if (executable == callLinkInfo->callee.get()->executable()
+        && structure == callLinkInfo->callee.get()->structure()) {
+        
+        shouldLink = true;
+        
+        ASSERT(executable->hasJITCodeForCall());
+        codePtr = executable->generatedJITCodeForCall().addressForCall();
+        if (!callee->executable()->isHostFunction()) {
+            calleeCodeBlock = &jsCast<FunctionExecutable*>(executable)->generatedBytecodeForCall();
+            if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(calleeCodeBlock->numParameters())) {
+                shouldLink = false;
+                codePtr = executable->generatedJITCodeWithArityCheckFor(CodeForCall);
+            }
+        }
+    } else if (callee->isHostFunction())
+        codePtr = executable->generatedJITCodeForCall().addressForCall();
+    else {
+        // Need to clear the code block before compilation, because compilation can GC.
+        callFrame->setCodeBlock(0);
+        
+        FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
+        JSScope* scopeChain = callee->scope();
+        JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall);
+        if (error) {
+            callFrame->globalData().exception = error;
+            return 0;
+        }
+        
+        codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(CodeForCall);
+    }
+    
+    if (shouldLink) {
+        ASSERT(codePtr);
+        JIT::compileClosureCall(globalData, callLinkInfo, callerCodeBlock, calleeCodeBlock, structure, executable, codePtr);
+    } else
+        JIT::linkSlowCall(callerCodeBlock, callLinkInfo);
+
+    return codePtr.executableAddress();
+}
+
 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
index 5b1c66a..43dc01c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -411,6 +411,7 @@ void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void* JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void* JIT_STUB cti_stack_check(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION) WTF_INTERNAL;
+void* JIT_STUB cti_vm_lazyLinkClosureCall(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL;
 void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM WTF_INTERNAL;
 } // extern "C"
index beea967..e4eb384 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -106,6 +106,11 @@ MacroAssemblerCodeRef linkConstructGenerator(JSGlobalData* globalData)
     return linkForGenerator(globalData, FunctionPtr(cti_vm_lazyLinkConstruct), FunctionPtr(cti_op_construct_NotJSConstruct), "construct");
 }
 
+MacroAssemblerCodeRef linkClosureCallGenerator(JSGlobalData* globalData)
+{
+    return linkForGenerator(globalData, FunctionPtr(cti_vm_lazyLinkClosureCall), FunctionPtr(cti_op_call_NotJSFunction), "closure call");
+}
+
 static MacroAssemblerCodeRef virtualForGenerator(JSGlobalData* globalData, FunctionPtr compile, FunctionPtr notJSFunction, const char* name, CodeSpecializationKind kind)
 {
     JSInterfaceJIT jit;
index 2e9a5b1..e9e4d81 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2012, 2013 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@ namespace JSC {
 
 MacroAssemblerCodeRef linkCallGenerator(JSGlobalData*);
 MacroAssemblerCodeRef linkConstructGenerator(JSGlobalData*);
+MacroAssemblerCodeRef linkClosureCallGenerator(JSGlobalData*);
 MacroAssemblerCodeRef virtualCallGenerator(JSGlobalData*);
 MacroAssemblerCodeRef virtualConstructGenerator(JSGlobalData*);
 MacroAssemblerCodeRef stringLengthTrampolineGenerator(JSGlobalData*);