Ignore:
Timestamp:
Jan 29, 2014, 11:18:54 AM (12 years ago)
Author:
[email protected]
Message:

Merge the jsCStack branch
https://bugs.webkit.org/show_bug.cgi?id=127763

Reviewed by Mark Hahnenberg.

Source/JavaScriptCore:

Changes from http://svn.webkit.org/repository/webkit/branches/jsCStack
up to changeset 162958.

Source/WebCore:

Changes from http://svn.webkit.org/repository/webkit/branches/jsCStack
up to changeset 162958.

Source/WTF:

Changes from http://svn.webkit.org/repository/webkit/branches/jsCStack
up to changeset 162958.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r161220 r163027  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3131#include "ArrayConstructor.h"
    3232#include "CallFrameInlines.h"
    33 #include "CommonSlowPaths.h"
    3433#include "DFGCompilationMode.h"
    3534#include "DFGDriver.h"
     
    3736#include "DFGWorklist.h"
    3837#include "Error.h"
     38#include "ErrorHandlingScope.h"
    3939#include "GetterSetter.h"
    4040#include "HostCallReturnValue.h"
     
    7272
    7373
    74 void JIT_OPERATION operationStackCheck(ExecState* exec, CodeBlock* codeBlock)
     74void JIT_OPERATION operationThrowStackOverflowError(ExecState* exec, CodeBlock* codeBlock)
    7575{
    7676    // We pass in our own code block, because the callframe hasn't been populated.
     
    8181
    8282    NativeCallFrameTracer tracer(vm, callerFrame);
    83 
    84     JSStack& stack = vm->interpreter->stack();
    85 
    86     if (UNLIKELY(!stack.grow(&exec->registers()[virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset()])))
    87         vm->throwException(callerFrame, createStackOverflowError(callerFrame));
     83    ErrorHandlingScope errorScope(*vm);
     84    vm->throwException(callerFrame, createStackOverflowError(callerFrame));
    8885}
    8986
     
    9895    int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForCall);
    9996    if (missingArgCount < 0)
    100         vm->throwException(callerFrame, createStackOverflowError(callerFrame));
     97        throwStackOverflowError(callerFrame);
    10198
    10299    return missingArgCount;
     
    113110    int32_t missingArgCount = CommonSlowPaths::arityCheckFor(exec, &stack, CodeForConstruct);
    114111    if (missingArgCount < 0)
    115         vm->throwException(callerFrame, createStackOverflowError(callerFrame));
     112        throwStackOverflowError(callerFrame);
    116113
    117114    return missingArgCount;
     
    613610}
    614611
    615 EncodedJSValue JIT_OPERATION operationCallEval(ExecState* execCallee)
    616 {
    617     CallFrame* callerFrame = execCallee->callerFrame();
    618     ASSERT(execCallee->callerFrame()->codeBlock()->codeType() != FunctionCode
    619         || !execCallee->callerFrame()->codeBlock()->needsFullScopeChain()
    620         || execCallee->callerFrame()->uncheckedR(execCallee->callerFrame()->codeBlock()->activationRegister().offset()).jsValue());
    621 
    622     execCallee->setScope(callerFrame->scope());
    623     execCallee->setReturnPC(static_cast<Instruction*>(OUR_RETURN_ADDRESS));
     612EncodedJSValue JIT_OPERATION operationCallEval(ExecState* exec, ExecState* execCallee)
     613{
     614    ASSERT(exec->codeBlock()->codeType() != FunctionCode
     615        || !exec->codeBlock()->needsFullScopeChain()
     616        || exec->uncheckedR(exec->codeBlock()->activationRegister().offset()).jsValue());
     617
     618    execCallee->setScope(exec->scope());
    624619    execCallee->setCodeBlock(0);
    625620
     
    686681}
    687682
    688 inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
     683inline char* linkFor(
     684    ExecState* execCallee, CodeSpecializationKind kind, RegisterPreservationMode registers)
    689685{
    690686    ExecState* exec = execCallee->callerFrame();
     
    705701    CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC());
    706702    if (executable->isHostFunction())
    707         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
     703        codePtr = executable->entrypointFor(*vm, kind, MustCheckArity, registers);
    708704    else {
    709705        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
    710706        JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
    711707        if (error) {
    712             vm->throwException(exec, createStackOverflowError(exec));
     708            throwStackOverflowError(exec);
    713709            return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
    714710        }
    715711        codeBlock = functionExecutable->codeBlockFor(kind);
     712        ArityCheckMode arity;
    716713        if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()) || callLinkInfo.callType == CallLinkInfo::CallVarargs)
    717             codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
     714            arity = MustCheckArity;
    718715        else
    719             codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall();
     716            arity = ArityCheckNotRequired;
     717        codePtr = functionExecutable->entrypointFor(*vm, kind, arity, registers);
    720718    }
    721719    if (!callLinkInfo.seenOnce())
    722720        callLinkInfo.setSeen();
    723721    else
    724         linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
     722        linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind, registers);
    725723    return reinterpret_cast<char*>(codePtr.executableAddress());
    726724}
     
    728726char* JIT_OPERATION operationLinkCall(ExecState* execCallee)
    729727{
    730     return linkFor(execCallee, CodeForCall);
     728    return linkFor(execCallee, CodeForCall, RegisterPreservationNotRequired);
    731729}
    732730
    733731char* JIT_OPERATION operationLinkConstruct(ExecState* execCallee)
    734732{
    735     return linkFor(execCallee, CodeForConstruct);
    736 }
    737 
    738 inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell)
     733    return linkFor(execCallee, CodeForConstruct, RegisterPreservationNotRequired);
     734}
     735
     736char* JIT_OPERATION operationLinkCallThatPreservesRegs(ExecState* execCallee)
     737{
     738    return linkFor(execCallee, CodeForCall, MustPreserveRegisters);
     739}
     740
     741char* JIT_OPERATION operationLinkConstructThatPreservesRegs(ExecState* execCallee)
     742{
     743    return linkFor(execCallee, CodeForConstruct, MustPreserveRegisters);
     744}
     745
     746inline char* virtualForWithFunction(
     747    ExecState* execCallee, CodeSpecializationKind kind, RegisterPreservationMode registers,
     748    JSCell*& calleeAsFunctionCell)
    739749{
    740750    ExecState* exec = execCallee->callerFrame();
     
    758768        }
    759769    }
    760     return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress());
    761 }
    762 
    763 inline char* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
     770    return reinterpret_cast<char*>(executable->entrypointFor(
     771        *vm, kind, MustCheckArity, registers).executableAddress());
     772}
     773
     774inline char* virtualFor(
     775    ExecState* execCallee, CodeSpecializationKind kind, RegisterPreservationMode registers)
    764776{
    765777    JSCell* calleeAsFunctionCellIgnored;
    766     return virtualForWithFunction(execCallee, kind, calleeAsFunctionCellIgnored);
    767 }
    768 
    769 static bool attemptToOptimizeClosureCall(ExecState* execCallee, JSCell* calleeAsFunctionCell, CallLinkInfo& callLinkInfo)
     778    return virtualForWithFunction(execCallee, kind, registers, calleeAsFunctionCellIgnored);
     779}
     780
     781static bool attemptToOptimizeClosureCall(
     782    ExecState* execCallee, RegisterPreservationMode registers, JSCell* calleeAsFunctionCell,
     783    CallLinkInfo& callLinkInfo)
    770784{
    771785    if (!calleeAsFunctionCell)
     
    781795   
    782796    ASSERT(callee->executable()->hasJITCodeForCall());
    783     MacroAssemblerCodePtr codePtr = callee->executable()->generatedJITCodeForCall()->addressForCall();
     797    MacroAssemblerCodePtr codePtr =
     798        callee->executable()->generatedJITCodeForCall()->addressForCall(
     799            *execCallee->callerFrame()->codeBlock()->vm(), callee->executable(),
     800            ArityCheckNotRequired, registers);
    784801   
    785802    CodeBlock* codeBlock;
     
    794811    linkClosureCall(
    795812        execCallee, callLinkInfo, codeBlock,
    796         callee->structure(), callee->executable(), codePtr);
     813        callee->structure(), callee->executable(), codePtr, registers);
    797814   
    798815    return true;
     
    802819{
    803820    JSCell* calleeAsFunctionCell;
    804     char* result = virtualForWithFunction(execCallee, CodeForCall, calleeAsFunctionCell);
     821    char* result = virtualForWithFunction(execCallee, CodeForCall, RegisterPreservationNotRequired, calleeAsFunctionCell);
    805822    CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC());
    806823
    807     if (!attemptToOptimizeClosureCall(execCallee, calleeAsFunctionCell, callLinkInfo))
    808         linkSlowFor(execCallee, callLinkInfo, CodeForCall);
     824    if (!attemptToOptimizeClosureCall(execCallee, RegisterPreservationNotRequired, calleeAsFunctionCell, callLinkInfo))
     825        linkSlowFor(execCallee, callLinkInfo, CodeForCall, RegisterPreservationNotRequired);
    809826   
    810827    return result;
     
    813830char* JIT_OPERATION operationVirtualCall(ExecState* execCallee)
    814831{   
    815     return virtualFor(execCallee, CodeForCall);
     832    return virtualFor(execCallee, CodeForCall, RegisterPreservationNotRequired);
    816833}
    817834
    818835char* JIT_OPERATION operationVirtualConstruct(ExecState* execCallee)
    819836{
    820     return virtualFor(execCallee, CodeForConstruct);
    821 }
    822 
     837    return virtualFor(execCallee, CodeForConstruct, RegisterPreservationNotRequired);
     838}
     839
     840char* JIT_OPERATION operationLinkClosureCallThatPreservesRegs(ExecState* execCallee)
     841{
     842    JSCell* calleeAsFunctionCell;
     843    char* result = virtualForWithFunction(execCallee, CodeForCall, MustPreserveRegisters, calleeAsFunctionCell);
     844    CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC());
     845
     846    if (!attemptToOptimizeClosureCall(execCallee, MustPreserveRegisters, calleeAsFunctionCell, callLinkInfo))
     847        linkSlowFor(execCallee, callLinkInfo, CodeForCall, MustPreserveRegisters);
     848   
     849    return result;
     850}
     851
     852char* JIT_OPERATION operationVirtualCallThatPreservesRegs(ExecState* execCallee)
     853{   
     854    return virtualFor(execCallee, CodeForCall, MustPreserveRegisters);
     855}
     856
     857char* JIT_OPERATION operationVirtualConstructThatPreservesRegs(ExecState* execCallee)
     858{
     859    return virtualFor(execCallee, CodeForConstruct, MustPreserveRegisters);
     860}
    823861
    824862size_t JIT_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
     
    9751013
    9761014#if ENABLE(DFG_JIT)
    977 char* JIT_OPERATION operationOptimize(ExecState* exec, int32_t bytecodeIndex)
     1015SlowPathReturnType JIT_OPERATION operationOptimize(ExecState* exec, int32_t bytecodeIndex)
    9781016{
    9791017    VM& vm = exec->vm();
     
    10251063        if (Options::verboseOSR())
    10261064            dataLog("Choosing not to optimize ", *codeBlock, " yet, because the threshold hasn't been reached.\n");
    1027         return 0;
     1065        return encodeResult(0, 0);
    10281066    }
    10291067   
     
    10331071        if (Options::verboseOSR())
    10341072            dataLog("Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.\n");
    1035         return 0;
     1073        return encodeResult(0, 0);
    10361074    }
    10371075
    10381076    // We cannot be in the process of asynchronous compilation and also have an optimized
    10391077    // replacement.
     1078    DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull();
    10401079    ASSERT(
    1041         !vm.worklist
    1042         || !(vm.worklist->compilationState(DFG::CompilationKey(codeBlock, DFG::DFGMode)) != DFG::Worklist::NotKnown
     1080        !worklist
     1081        || !(worklist->compilationState(DFG::CompilationKey(codeBlock, DFG::DFGMode)) != DFG::Worklist::NotKnown
    10431082        && codeBlock->hasOptimizedReplacement()));
    10441083
    10451084    DFG::Worklist::State worklistState;
    1046     if (vm.worklist) {
     1085    if (worklist) {
    10471086        // The call to DFG::Worklist::completeAllReadyPlansForVM() will complete all ready
    10481087        // (i.e. compiled) code blocks. But if it completes ours, we also need to know
     
    10631102        // possible in order to minimize the chances of us executing baseline code after
    10641103        // optimized code is already available.
    1065         worklistState = vm.worklist->completeAllReadyPlansForVM(
     1104        worklistState = worklist->completeAllReadyPlansForVM(
    10661105            vm, DFG::CompilationKey(codeBlock, DFG::DFGMode));
    10671106    } else
     
    10731112        RELEASE_ASSERT(!codeBlock->hasOptimizedReplacement());
    10741113        codeBlock->setOptimizationThresholdBasedOnCompilationResult(CompilationDeferred);
    1075         return 0;
     1114        return encodeResult(0, 0);
    10761115    }
    10771116
     
    10861125            if (Options::verboseOSR())
    10871126                dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
    1088             return 0;
     1127            return encodeResult(0, 0);
    10891128        }
    10901129    } else if (codeBlock->hasOptimizedReplacement()) {
     
    11111150            }
    11121151            codeBlock->replacement()->jettison(CountReoptimization);
    1113             return 0;
     1152            return encodeResult(0, 0);
    11141153        }
    11151154    } else {
     
    11201159                    " because of insufficient profiling.\n");
    11211160            }
    1122             return 0;
     1161            return encodeResult(0, 0);
    11231162        }
    11241163
     
    11481187
    11491188        CompilationResult result = DFG::compile(
    1150             vm, codeBlock->newReplacement().get(), DFG::DFGMode, bytecodeIndex,
    1151             mustHandleValues, JITToDFGDeferredCompilationCallback::create(),
    1152             vm.ensureWorklist());
     1189            vm, codeBlock->newReplacement().get(), 0, DFG::DFGMode, bytecodeIndex,
     1190            mustHandleValues, JITToDFGDeferredCompilationCallback::create());
    11531191       
    11541192        if (result != CompilationSuccessful)
    1155             return 0;
     1193            return encodeResult(0, 0);
    11561194    }
    11571195   
     
    11671205
    11681206        codeBlock->optimizeSoon();
    1169         return static_cast<char*>(address);
     1207        ASSERT(exec->codeBlock() == optimizedCodeBlock);
     1208        return encodeResult(address, exec->topOfFrame());
    11701209    }
    11711210
     
    11961235        }
    11971236        optimizedCodeBlock->jettison(CountReoptimization);
    1198         return 0;
     1237        return encodeResult(0, 0);
    11991238    }
    12001239
     
    12031242    codeBlock->optimizeAfterWarmUp();
    12041243   
    1205     return 0;
     1244    return encodeResult(0, 0);
    12061245}
    12071246#endif
     
    15311570}
    15321571
    1533 CallFrame* JIT_OPERATION operationSizeAndAllocFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstFreeRegister)
     1572CallFrame* JIT_OPERATION operationSizeFrameForVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstFreeRegister)
    15341573{
    15351574    VM& vm = exec->vm();
     
    15371576    JSStack* stack = &exec->interpreter()->stack();
    15381577    JSValue arguments = JSValue::decode(encodedArguments);
    1539     CallFrame* newCallFrame = sizeAndAllocFrameForVarargs(exec, stack, arguments, firstFreeRegister);
     1578    CallFrame* newCallFrame = sizeFrameForVarargs(exec, stack, arguments, firstFreeRegister);
    15401579    return newCallFrame;
    15411580}
     
    17301769}
    17311770
    1732 void JIT_OPERATION lookupExceptionHandler(ExecState* exec)
    1733 {
    1734     VM* vm = &exec->vm();
    1735     NativeCallFrameTracer tracer(vm, exec);
    1736 
    1737     JSValue exceptionValue = exec->exception();
     1771void JIT_OPERATION lookupExceptionHandler(VM* vm, ExecState* exec)
     1772{
     1773    NativeCallFrameTracer tracer(vm, exec, NativeCallFrameTracer::VMEntrySentinelOK);
     1774
     1775    JSValue exceptionValue = vm->exception();
    17381776    ASSERT(exceptionValue);
    17391777   
     
    17681806HIDE_SYMBOL(getHostCallReturnValue) "\n"
    17691807SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
    1770     "mov 0(%rbp), %rbp\n" // CallerFrameAndPC::callerFrame
    17711808    "mov %rbp, %rdi\n"
    17721809    "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
     
    17791816HIDE_SYMBOL(getHostCallReturnValue) "\n"
    17801817SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
    1781     "mov 0(%ebp), %ebp\n" // CallerFrameAndPC::callerFrame
    1782     "mov %ebp, 4(%esp)\n"
     1818    "mov (%esp), %eax\n"
     1819    "push %ebp\n"
     1820    "leal -4(%esp), %esp\n"
     1821    "push %ebp\n"
     1822    "push %eax\n"
    17831823    "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
    17841824);
     
    17931833".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
    17941834SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
    1795     "ldr r7, [r7, #0]" "\n" // CallerFrameAndPC::callerFrame
    17961835    "mov r0, r7" "\n"
    17971836    "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
     
    18051844INLINE_ARM_FUNCTION(getHostCallReturnValue)
    18061845SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
    1807     "ldr r11, [r11, #0]" "\n" // CallerFrameAndPC::callerFrame
    18081846    "mov r0, r11" "\n"
    18091847    "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
     
    18171855HIDE_SYMBOL(getHostCallReturnValue) "\n"
    18181856SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
    1819     "ldur x29, [x29, #0]" "\n"
    18201857     "mov x0, x29" "\n"
    18211858     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
     
    18291866SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
    18301867    LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState)
    1831     "lw $fp, 0($fp)" "\n" // CallerFrameAndPC::callerFrame
    18321868    "move $a0, $fp" "\n"
    18331869    "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
     
    18401876HIDE_SYMBOL(getHostCallReturnValue) "\n"
    18411877SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
    1842     "mov.l @r14, r14" "\n" // CallerFrameAndPC::callerFrame
    18431878    "mov r14, r4" "\n"
    18441879    "mov.l 2f, " SH4_SCRATCH_REGISTER "\n"
     
    18531888    __declspec(naked) EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue()
    18541889    {
    1855         __asm mov ebp, [ebp + 0]; // CallerFrameAndPC::callerFrame
    18561890        __asm mov [esp + 4], ebp;
    18571891        __asm jmp getHostCallReturnValueWithExecState
Note: See TracChangeset for help on using the changeset viewer.