Ignore:
Timestamp:
Dec 5, 2013, 12:33:35 PM (12 years ago)
Author:
[email protected]
Message:

Make the C Loop LLINT work with callToJavaScript.
https://bugs.webkit.org/show_bug.cgi?id=125294.

Reviewed by Michael Saboff.

  1. Changed the C Loop LLINT to dispatch to an Executable via its JITCode instance which is consistent with how the ASM LLINT works.
  2. Changed CLoop::execute() to take an Opcode instead of an OpcodeID. This makes it play nice with the use of JITCode for dispatching.
  3. Introduce a callToJavaScript and callToNativeFunction for the C Loop LLINT. These will call JSStack::pushFrame() and popFrame() to setup and teardown the CallFrame.
  4. Also introduced a C Loop returnFromJavaScript which is just a replacement for ctiOpThrowNotCaught which had the same function.
  5. Remove a lot of #if ENABLE(LLINT_C_LOOP) code now that the dispatch mechanism is consistent.

This patch has been tested with both configurations of COMPUTED_GOTOs
on and off.

  • interpreter/CachedCall.h:

(JSC::CachedCall::CachedCall):
(JSC::CachedCall::call):
(JSC::CachedCall::setArgument):

  • interpreter/CallFrameClosure.h:

(JSC::CallFrameClosure::setThis):
(JSC::CallFrameClosure::setArgument):
(JSC::CallFrameClosure::resetCallFrame):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):

  • interpreter/Interpreter.h:
  • interpreter/JSStack.h:
  • interpreter/JSStackInlines.h:

(JSC::JSStack::pushFrame):

  • interpreter/ProtoCallFrame.h:

(JSC::ProtoCallFrame::scope):
(JSC::ProtoCallFrame::callee):
(JSC::ProtoCallFrame::thisValue):
(JSC::ProtoCallFrame::argument):
(JSC::ProtoCallFrame::setArgument):

  • jit/JITCode.cpp:

(JSC::JITCode::execute):

  • jit/JITCode.h:
  • jit/JITExceptions.cpp:

(JSC::genericUnwind):

  • llint/LLIntCLoop.cpp:

(JSC::LLInt::CLoop::initialize):

  • llint/LLIntCLoop.h:
  • llint/LLIntEntrypoint.cpp:

(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):

  • Inverted the check for vm.canUseJIT(). This allows the JIT case to be #if'd out nicely when building the C Loop LLINT.
  • llint/LLIntOpcode.h:
  • llint/LLIntThunks.cpp:

(JSC::doCallToJavaScript):
(JSC::executeJS):
(JSC::callToJavaScript):
(JSC::executeNative):
(JSC::callToNativeFunction):

  • llint/LLIntThunks.h:
  • llint/LowLevelInterpreter.cpp:

(JSC::CLoop::execute):

  • runtime/Executable.h:

(JSC::ExecutableBase::offsetOfNumParametersFor):
(JSC::ExecutableBase::hostCodeEntryFor):
(JSC::ExecutableBase::jsCodeEntryFor):
(JSC::ExecutableBase::jsCodeWithArityCheckEntryFor):
(JSC::NativeExecutable::create):
(JSC::NativeExecutable::finishCreation):
(JSC::ProgramExecutable::generatedJITCode):

  • runtime/JSArray.cpp:

(JSC::AVLTreeAbstractorForArrayCompare::compare_key_key):

  • runtime/StringPrototype.cpp:

(JSC::replaceUsingRegExpSearch):

  • runtime/VM.cpp:

(JSC::VM::getHostFunction):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r160094 r160186  
    861861        return throwTerminatedExecutionException(callFrame);
    862862
    863     // Push the call frame for this invocation:
    864863    ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
    865 #if ENABLE(LLINT_C_LOOP)
    866     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
    867     if (UNLIKELY(!newCallFrame))
    868         return checkedReturn(throwStackOverflowError(callFrame));
    869 
    870     // Set the arguments for the callee:
    871     newCallFrame->setThisValue(thisObj);
    872 #else
     864
    873865    if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
    874866        return checkedReturn(throwStackOverflowError(callFrame));
     
    876868    ProtoCallFrame protoCallFrame;
    877869    protoCallFrame.init(codeBlock, scope, 0, thisObj, 1);
    878 #endif
    879870
    880871    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    887878        Watchdog::Scope watchdogScope(vm.watchdog);
    888879
    889 #if ENABLE(LLINT_C_LOOP)
    890         result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
    891 #elif ENABLE(JIT)
    892880        result = program->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    893 #endif // ENABLE(JIT)
    894881    }
    895882
    896883    if (LegacyProfiler* profiler = vm.enabledProfiler())
    897884        profiler->didExecute(callFrame, program->sourceURL(), program->lineNo());
    898 
    899 #if ENABLE(LLINT_C_LOOP)
    900     m_stack.popFrame(newCallFrame);
    901 #endif
    902885
    903886    return checkedReturn(result);
     
    943926        return throwTerminatedExecutionException(callFrame);
    944927
    945 #if ENABLE(LLINT_C_LOOP)
    946     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
    947     if (UNLIKELY(!newCallFrame))
    948         return checkedReturn(throwStackOverflowError(callFrame));
    949 
    950     // Set the arguments for the callee:
    951     newCallFrame->setThisValue(thisValue);
    952     for (size_t i = 0; i < args.size(); ++i)
    953         newCallFrame->setArgument(i, args.at(i));
    954 #else
    955928    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
    956929        return checkedReturn(throwStackOverflowError(callFrame));
     
    958931    ProtoCallFrame protoCallFrame;
    959932    protoCallFrame.init(newCodeBlock, scope, function, thisValue, argsCount, args.data());
    960 #endif
    961933
    962934    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    969941
    970942        // Execute the code:
    971         if (isJSCall) {
    972 #if ENABLE(LLINT_C_LOOP)
    973             result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
    974 #elif ENABLE(JIT)
     943        if (isJSCall)
    975944            result = callData.js.functionExecutable->generatedJITCodeForCall()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    976 #endif // ENABLE(JIT)
    977         } else {
    978 #if ENABLE(LLINT_C_LOOP)
    979             result = JSValue::decode(callData.native.function(newCallFrame));
    980 #else
     945        else
    981946            result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(callData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
    982 #endif
    983         }
    984947    }
    985948
     
    987950        profiler->didExecute(callFrame, function);
    988951
    989 #if ENABLE(LLINT_C_LOOP)
    990     m_stack.popFrame(newCallFrame);
    991 #endif
    992952    return checkedReturn(result);
    993953}
     
    1033993    if (UNLIKELY(vm.watchdog.didFire(callFrame)))
    1034994        return throwTerminatedExecutionException(callFrame);
    1035 #if ENABLE(LLINT_C_LOOP)
    1036     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, constructor);
    1037     if (UNLIKELY(!newCallFrame))
    1038         return checkedReturn(throwStackOverflowError(callFrame));
    1039 
    1040     // Set the arguments for the callee:
    1041     newCallFrame->setThisValue(jsUndefined());
    1042     for (size_t i = 0; i < args.size(); ++i)
    1043         newCallFrame->setArgument(i, args.at(i));
    1044 #else
     995
    1045996    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount)))
    1046997        return checkedReturn(throwStackOverflowError(callFrame));
     
    1048999    ProtoCallFrame protoCallFrame;
    10491000    protoCallFrame.init(newCodeBlock, scope, constructor, jsUndefined(), argsCount, args.data());
    1050 #endif
    10511001
    10521002    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    10591009
    10601010        // Execute the code.
    1061         if (isJSConstruct) {
    1062 #if ENABLE(LLINT_C_LOOP)
    1063             result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
    1064 #elif ENABLE(JIT)
     1011        if (isJSConstruct)
    10651012            result = constructData.js.functionExecutable->generatedJITCodeForConstruct()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    1066 #endif // ENABLE(JIT)
    1067         } else {
    1068 #if ENABLE(LLINT_C_LOOP)
    1069             result = JSValue::decode(constructData.native.function(newCallFrame));
    1070 #else
     1013        else {
    10711014            result = JSValue::decode(callToNativeFunction(reinterpret_cast<void*>(constructData.native.function), &vm.topCallFrame, &protoCallFrame, m_stack.getTopOfStack()));
    1072 #endif
     1015
    10731016            if (!callFrame->hadException())
    10741017                RELEASE_ASSERT(result.isObject());
     
    10781021    if (LegacyProfiler* profiler = vm.enabledProfiler())
    10791022        profiler->didExecute(callFrame, constructor);
    1080 
    1081 #if ENABLE(LLINT_C_LOOP)
    1082     m_stack.popFrame(newCallFrame);
    1083 #endif
    10841023
    10851024    if (callFrame->hadException())
     
    10891028}
    10901029
    1091 #if ENABLE(LLINT_C_LOOP)
    1092 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope)
    1093 #else
    10941030CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
    1095 #endif
    10961031{
    10971032    VM& vm = *scope->vm();
     
    11121047    size_t argsCount = argumentCountIncludingThis;
    11131048
    1114 #if ENABLE(LLINT_C_LOOP)
    1115     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, newCodeBlock, scope, argsCount, function);
    1116 
    1117     if (UNLIKELY(!newCallFrame)) {
    1118         throwStackOverflowError(callFrame);
    1119         return CallFrameClosure();
    1120     }
    1121 
    1122     // Return the successful closure:
    1123     CallFrameClosure result = { callFrame, newCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
    1124 #else
    11251049    if (UNLIKELY(!m_stack.entryCheck(newCodeBlock, argsCount))) {
    11261050        throwStackOverflowError(callFrame);
     
    11311055    // Return the successful closure:
    11321056    CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
    1133 #endif
    11341057    return result;
    11351058}
     
    11451068
    11461069    StackStats::CheckPoint stackCheckPoint;
    1147 #if ENABLE(LLINT_C_LOOP)
    1148     m_stack.validateFence(closure.newCallFrame, "BEFORE");
    1149 #endif
    11501070    closure.resetCallFrame();
    1151 #if ENABLE(LLINT_C_LOOP)
    1152     m_stack.validateFence(closure.newCallFrame, "STEP 1");
    1153 #endif
    11541071
    11551072    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    11591076        return throwTerminatedExecutionException(closure.oldCallFrame);
    11601077
    1161     // The code execution below may push more frames and point the topCallFrame
    1162     // to those newer frames, or it may pop to the top frame to the caller of
    1163     // the current repeat frame, or it may leave the top frame pointing to the
    1164     // current repeat frame.
    1165     //
    1166     // Hence, we need to preserve the topCallFrame here ourselves before
    1167     // repeating this call on a second callback function.
    1168 
    1169 #if ENABLE(LLINT_C_LOOP)
    1170     TopCallFrameSetter topCallFrame(vm, closure.newCallFrame);
    1171 #endif
    1172 
    11731078    // Execute the code:
    11741079    JSValue result;
     
    11771082        Watchdog::Scope watchdogScope(vm.watchdog);
    11781083
    1179 #if ENABLE(LLINT_C_LOOP)
    1180         result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
    1181 #elif ENABLE(JIT)
    1182         result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.newCallFrame, m_stack.getTopOfStack());
    1183 #endif // ENABLE(JIT)
     1084        result = closure.functionExecutable->generatedJITCodeForCall()->execute(&vm, closure.protoCallFrame, m_stack.getTopOfStack());
    11841085    }
    11851086
     
    11871088        profiler->didExecute(closure.oldCallFrame, closure.function);
    11881089
    1189 #if ENABLE(LLINT_C_LOOP)
    1190     m_stack.validateFence(closure.newCallFrame, "AFTER");
    1191 #endif
    11921090    return checkedReturn(result);
    11931091}
    1194 
    1195 #if ENABLE(LLINT_C_LOOP)
    1196 void Interpreter::endRepeatCall(CallFrameClosure& closure)
    1197 {
    1198     m_stack.popFrame(closure.newCallFrame);
    1199 }
    1200 #endif
    12011092
    12021093JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
     
    12601151        return throwTerminatedExecutionException(callFrame);
    12611152
    1262     // Push the frame:
    12631153    ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
    1264 #if ENABLE(LLINT_C_LOOP)
    1265     CallFrame* newCallFrame = m_stack.pushFrame(callFrame, codeBlock, scope, 1, 0);
    1266     if (UNLIKELY(!newCallFrame))
    1267         return checkedReturn(throwStackOverflowError(callFrame));
    1268 
    1269     // Set the arguments for the callee:
    1270     newCallFrame->setThisValue(thisValue);
    1271 #else
     1154
    12721155    if (UNLIKELY(!m_stack.entryCheck(codeBlock, 1)))
    12731156        return checkedReturn(throwStackOverflowError(callFrame));
     
    12751158    ProtoCallFrame protoCallFrame;
    12761159    protoCallFrame.init(codeBlock, scope, 0, thisValue, 1);
    1277 #endif
    12781160
    12791161    if (LegacyProfiler* profiler = vm.enabledProfiler())
     
    12861168        Watchdog::Scope watchdogScope(vm.watchdog);
    12871169
    1288 #if ENABLE(LLINT_C_LOOP)
    1289         result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
    1290 #elif ENABLE(JIT)
    12911170        result = eval->generatedJITCode()->execute(&vm, &protoCallFrame, m_stack.getTopOfStack());
    1292 #endif // ENABLE(JIT)
    12931171    }
    12941172
     
    12961174        profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
    12971175
    1298 #if ENABLE(LLINT_C_LOOP)
    1299     m_stack.popFrame(newCallFrame);
    1300 #endif
    13011176    return checkedReturn(result);
    13021177}
Note: See TracChangeset for help on using the changeset viewer.