diff --git a/ecmascript/compiler/interpreter_stub.cpp b/ecmascript/compiler/interpreter_stub.cpp index 85dc0e5fe0..8c78eb3b31 100644 --- a/ecmascript/compiler/interpreter_stub.cpp +++ b/ecmascript/compiler/interpreter_stub.cpp @@ -4575,6 +4575,9 @@ DECLARE_ASM_HANDLER(HandleSuspendGeneratorPrefV8V8) } Bind(&tryContinue); +#if ECMASCRIPT_ENABLE_ASM_INTERPRETER_RSP_STACK + GateRef currentSp = *varSp; +#endif varSp = Load(VariableType::NATIVE_POINTER(), frame, IntPtr(AsmInterpretedFrame::GetBaseOffset(env->IsArch32Bit()))); GateRef prevState = GetFrame(*varSp); @@ -4590,7 +4593,9 @@ DECLARE_ASM_HANDLER(HandleSuspendGeneratorPrefV8V8) } Bind(&pcNotEqualNullptr); { +#if !ECMASCRIPT_ENABLE_ASM_INTERPRETER_RSP_STACK SetCurrentSpFrame(glue, *varSp); +#endif GateRef function = GetFunctionFromFrame(prevState); varConstpool = GetConstpoolFromFunction(function); varProfileTypeInfo = GetProfileTypeInfoFromFunction(function); @@ -4598,8 +4603,15 @@ DECLARE_ASM_HANDLER(HandleSuspendGeneratorPrefV8V8) IntPtr(JSFunctionBase::METHOD_OFFSET)); varHotnessCounter = GetHotnessCounterFromMethod(method); GateRef jumpSize = GetCallSizeFromFrame(prevState); +#if ECMASCRIPT_ENABLE_ASM_INTERPRETER_RSP_STACK + CallNGCRuntime(glue, RTSTUB_ID(ResumeRspAndDispatch), + { glue, currentSp, *varPc, *varConstpool, *varProfileTypeInfo, + *varAcc, *varHotnessCounter, jumpSize }); + Return(); +#else Dispatch(glue, *varSp, *varPc, *varConstpool, *varProfileTypeInfo, *varAcc, *varHotnessCounter, jumpSize); +#endif } } diff --git a/ecmascript/generator_helper.cpp b/ecmascript/generator_helper.cpp index 78c4391dec..f576ac07f8 100644 --- a/ecmascript/generator_helper.cpp +++ b/ecmascript/generator_helper.cpp @@ -75,17 +75,4 @@ JSHandle GeneratorHelper::Throw(JSThread *thread, const JSHandlefoo -void GeneratorHelper::ChangeGenContext(JSThread *thread, const JSHandle &genContext) -{ - JSThread *jsThread = thread; - EcmaInterpreter::ChangeGenContext(jsThread, genContext); -} - -// foo->main -void GeneratorHelper::ResumeContext(JSThread *thread) -{ - EcmaInterpreter::ResumeContext(thread); -} } // namespace panda::ecmascript diff --git a/ecmascript/generator_helper.h b/ecmascript/generator_helper.h index fbbb2ecc08..1ae667d8b8 100644 --- a/ecmascript/generator_helper.h +++ b/ecmascript/generator_helper.h @@ -31,8 +31,6 @@ public: static JSHandle Throw(JSThread *thread, const JSHandle &genContext, JSTaggedValue value); - static void ChangeGenContext(JSThread *thread, const JSHandle &genContext); - static void ResumeContext(JSThread *thread); }; } // namespace panda::ecmascript diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index 2a5e39977e..f5c242d7e7 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -644,74 +644,6 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH return res; } -void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandle context) -{ - [[maybe_unused]] EcmaHandleScope handleScope(thread); - if (thread->IsAsmInterpreter()) { - return InterpreterAssembly::ChangeGenContext(thread, context); - } - JSHandle func = JSHandle::Cast(JSHandle(thread, context->GetMethod())); - JSMethod *method = func->GetCallTarget(); - - JSTaggedType *currentSp = const_cast(thread->GetCurrentSPFrame()); - - // push break frame - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - JSTaggedType *breakSp = currentSp - INTERPRETER_FRAME_STATE_SIZE; - if (UNLIKELY(thread->DoStackOverflowCheck(breakSp))) { - return; - } - - InterpretedFrame *breakState = GET_FRAME(breakSp); - breakState->pc = nullptr; - breakState->sp = nullptr; - breakState->function = JSTaggedValue::Hole(); - breakState->base.prev = currentSp; - breakState->base.type = FrameType::INTERPRETER_FRAME; - - // create new frame and resume sp and pc - uint32_t nregs = context->GetNRegs(); - size_t newFrameSize = INTERPRETER_FRAME_STATE_SIZE + nregs; - - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic - JSTaggedType *newSp = breakSp - newFrameSize; - if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) { - return; - } - JSHandle regsArray(thread, context->GetRegsArray()); - for (size_t i = 0; i < nregs; i++) { - newSp[i] = regsArray->Get(i).GetRawData(); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } - JSTaggedValue constpool = func->GetConstantPool(); - uint32_t pcOffset = context->GetBCOffset(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - const uint8_t *pc = method->GetBytecodeArray() + pcOffset; - - InterpretedFrame *state = GET_FRAME(newSp); - state->pc = pc; - state->sp = newSp; - state->function = func.GetTaggedValue(); - state->constpool = constpool; - state->profileTypeInfo = func->GetProfileTypeInfo(); - state->acc = context->GetAcc(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - state->base.prev = breakSp; - state->base.type = FrameType::INTERPRETER_FRAME; - state->env = context->GetLexicalEnv(); - - thread->SetCurrentSPFrame(newSp); -} - -void EcmaInterpreter::ResumeContext(JSThread *thread) -{ - if (thread->IsAsmInterpreter()) { - return InterpreterAssembly::ResumeContext(thread); - } - JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); - InterpretedFrame *state = GET_FRAME(sp); - thread->SetCurrentSPFrame(state->base.prev); -} - void EcmaInterpreter::NotifyBytecodePcChanged(JSThread *thread) { FrameHandler frameHandler(thread); diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index 273d374a24..43fb966fbd 100644 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -49,8 +49,6 @@ public: JSThread *thread, JSHandle func, JSHandle thisObj, JSHandle newTarget, size_t numArgs); static inline JSTaggedValue GeneratorReEnterInterpreter(JSThread *thread, JSHandle context); - static inline void ChangeGenContext(JSThread *thread, JSHandle context); - static inline void ResumeContext(JSThread *thread); static inline void RunInternal(JSThread *thread, ConstantPool *constpool, const uint8_t *pc, JSTaggedType *sp); static inline uint8_t ReadU8(const uint8_t *pc, uint32_t offset); static inline void InitStackFrame(JSThread *thread); diff --git a/ecmascript/interpreter/interpreter_assembly.cpp b/ecmascript/interpreter/interpreter_assembly.cpp index f0723bf3e8..5cdc5820fd 100644 --- a/ecmascript/interpreter/interpreter_assembly.cpp +++ b/ecmascript/interpreter/interpreter_assembly.cpp @@ -703,61 +703,6 @@ JSTaggedValue InterpreterAssembly::GeneratorReEnterInterpreter(JSThread *thread, return res; } -void InterpreterAssembly::ChangeGenContext(JSThread *thread, JSHandle context) -{ - JSHandle func = JSHandle::Cast(JSHandle(thread, context->GetMethod())); - JSMethod *method = func->GetCallTarget(); - - JSTaggedType *currentSp = const_cast(thread->GetCurrentSPFrame()); - - // push break frame - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - JSTaggedType *breakSp = currentSp - AsmInterpretedFrame::NumOfMembers(); - if (thread->DoStackOverflowCheck(breakSp) || thread->HasPendingException()) { - return; - } - AsmInterpretedFrame *breakState = GET_ASM_FRAME(breakSp); - breakState->pc = nullptr; - breakState->function = JSTaggedValue::Hole(); - breakState->base.prev = currentSp; - breakState->base.type = FrameType::ASM_INTERPRETER_FRAME; - - // create new frame and resume sp and pc - uint32_t nregs = context->GetNRegs(); - size_t newFrameSize = AsmInterpretedFrame::NumOfMembers() + nregs; - - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic - JSTaggedType *newSp = breakSp - newFrameSize; - if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) { - return; - } - JSHandle regsArray(thread, context->GetRegsArray()); - for (size_t i = 0; i < nregs; i++) { - newSp[i] = regsArray->Get(i).GetRawData(); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - } - uint32_t pcOffset = context->GetBCOffset(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - const uint8_t *pc = method->GetBytecodeArray() + pcOffset; - - AsmInterpretedFrame *state = GET_ASM_FRAME(newSp); - state->pc = pc; - state->function = func.GetTaggedValue(); - state->acc = context->GetAcc(); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - state->base.prev = breakSp; - state->base.type = FrameType::ASM_INTERPRETER_FRAME; - state->env = context->GetLexicalEnv(); - - thread->SetCurrentSPFrame(newSp); -} - -void InterpreterAssembly::ResumeContext(JSThread *thread) -{ - JSTaggedType *sp = const_cast(thread->GetCurrentSPFrame()); - AsmInterpretedFrame *state = GET_ASM_FRAME(sp); - thread->SetCurrentSPFrame(state->base.prev); -} - void InterpreterAssembly::HandleMovV4V4( JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo, JSTaggedValue acc, int32_t hotnessCounter) diff --git a/ecmascript/interpreter/interpreter_assembly.h b/ecmascript/interpreter/interpreter_assembly.h index 365e14c117..5efe2d8614 100644 --- a/ecmascript/interpreter/interpreter_assembly.h +++ b/ecmascript/interpreter/interpreter_assembly.h @@ -41,8 +41,6 @@ public: static JSTaggedValue Execute(EcmaRuntimeCallInfo *info); static JSTaggedValue ExecuteNative(EcmaRuntimeCallInfo *info); static JSTaggedValue GeneratorReEnterInterpreter(JSThread *thread, JSHandle context); - static void ChangeGenContext(JSThread *thread, JSHandle context); - static void ResumeContext(JSThread *thread); static uint32_t FindCatchBlock(JSMethod *caller, uint32_t pc); static inline size_t GetJumpSizeAfterCall(const uint8_t *prevPc); diff --git a/ecmascript/js_async_function.cpp b/ecmascript/js_async_function.cpp index 4a79f8dc70..50c50598cb 100644 --- a/ecmascript/js_async_function.cpp +++ b/ecmascript/js_async_function.cpp @@ -92,13 +92,11 @@ JSHandle JSAsyncAwaitStatusFunction::AsyncFunctionAwaitFulfilled( JSHandle asyncCtxt(thread, func->GetAsyncContext()); // 2.Let prevContext be the running execution context. - GeneratorHelper::ChangeGenContext(thread, asyncCtxt); // 3.Suspend prevContext. // 4.Push asyncContext onto the execution context stack; asyncContext is now the running execution context. // 5.Resume the suspended evaluation of asyncContext using NormalCompletion(value) as the result of the // operation that suspended it. Let result be the value returned by the resumed computation. JSHandle result = GeneratorHelper::Next(thread, asyncCtxt, value.GetTaggedValue()); - GeneratorHelper::ResumeContext(thread); // 6.Assert: When we reach this step, asyncContext has already been removed from the execution context stack // and prevContext is the currently running execution context. @@ -113,14 +111,12 @@ JSHandle JSAsyncAwaitStatusFunction::AsyncFunctionAwaitRejected( JSHandle asyncCtxt(thread, func->GetAsyncContext()); // 2.Let prevContext be the running execution context. - GeneratorHelper::ChangeGenContext(thread, asyncCtxt); // 3.Suspend prevContext. // 4.Push asyncContext onto the execution context stack; asyncContext is now the running execution context. // 5.Resume the suspended evaluation of asyncContext using Completion{[[Type]]: throw, // [[Value]]: reason, [[Target]]: empty} as the result of the operation that suspended it. // Let result be the value returned by the resumed computation. JSHandle result = GeneratorHelper::Throw(thread, asyncCtxt, reason.GetTaggedValue()); - GeneratorHelper::ResumeContext(thread); // 6.Assert: When we reach this step, asyncContext has already been removed from the execution context stack // and prevContext is the currently running execution context. diff --git a/ecmascript/js_generator_object.cpp b/ecmascript/js_generator_object.cpp index c46409ef94..c1cb2cb862 100644 --- a/ecmascript/js_generator_object.cpp +++ b/ecmascript/js_generator_object.cpp @@ -71,15 +71,12 @@ JSHandle JSGeneratorObject::GeneratorResume(JSThread *thread, const JS generator->SetGeneratorState(JSGeneratorState::EXECUTING); // 8.Push genContext onto the execution context stack; genContext is now the running execution context. - GeneratorHelper::ChangeGenContext(thread, genContext); - // 9.Resume the suspended evaluation of genContext using NormalCompletion(value) as the result of the operation // that suspended it. Let result be the value returned by the resumed computation. // 10.Assert: When we return here, genContext has already been removed from the execution context stack and // methodContext is the currently running execution context. // 11.Return Completion(result). JSHandle result = GeneratorHelper::Next(thread, genContext, value); - GeneratorHelper::ResumeContext(thread); return result; } @@ -128,8 +125,6 @@ JSHandle JSGeneratorObject::GeneratorResumeAbrupt(JSThread *thread, generator->SetGeneratorState(JSGeneratorState::EXECUTING); // 9.Push genContext onto the execution context stack; genContext is now the running execution context. - GeneratorHelper::ChangeGenContext(thread, genContext); - // 10.Resume the suspended evaluation of genContext using abruptCompletion as the result of the operation that // suspended it. Let result be the completion record returned by the resumed computation. // 11.Assert: When we return here, genContext has already been removed from the execution context stack and @@ -141,7 +136,6 @@ JSHandle JSGeneratorObject::GeneratorResumeAbrupt(JSThread *thread, } else { result = GeneratorHelper::Throw(thread, genContext, abruptCompletion->GetValue()); } - GeneratorHelper::ResumeContext(thread); return result; } } // namespace panda::ecmascript