mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Impl rsp frame of generator
1. Resume rsp of SuspendGenerator 2. Remove duplicated stack frame switching of ChangeGenContext and ResumeContext Issue:https://gitee.com/openharmony/ark_js_runtime/issues/I57IXJ?from=project-issue Signed-off-by: zhangyukun <zhangyukun8@huawei.com> Change-Id: I3a86c645864ec73f5dd351882125b4ee721b5468
This commit is contained in:
parent
e565046c8c
commit
903a0cd046
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,17 +75,4 @@ JSHandle<JSObject> GeneratorHelper::Throw(JSThread *thread, const JSHandle<Gener
|
||||
RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSObject, thread);
|
||||
return JSIterator::CreateIterResultObject(thread, throwValue, true);
|
||||
}
|
||||
|
||||
// main->foo
|
||||
void GeneratorHelper::ChangeGenContext(JSThread *thread, const JSHandle<GeneratorContext> &genContext)
|
||||
{
|
||||
JSThread *jsThread = thread;
|
||||
EcmaInterpreter::ChangeGenContext(jsThread, genContext);
|
||||
}
|
||||
|
||||
// foo->main
|
||||
void GeneratorHelper::ResumeContext(JSThread *thread)
|
||||
{
|
||||
EcmaInterpreter::ResumeContext(thread);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -31,8 +31,6 @@ public:
|
||||
|
||||
static JSHandle<JSObject> Throw(JSThread *thread, const JSHandle<GeneratorContext> &genContext,
|
||||
JSTaggedValue value);
|
||||
static void ChangeGenContext(JSThread *thread, const JSHandle<GeneratorContext> &genContext);
|
||||
static void ResumeContext(JSThread *thread);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
|
@ -644,74 +644,6 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH
|
||||
return res;
|
||||
}
|
||||
|
||||
void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> context)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
if (thread->IsAsmInterpreter()) {
|
||||
return InterpreterAssembly::ChangeGenContext(thread, context);
|
||||
}
|
||||
JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
|
||||
JSMethod *method = func->GetCallTarget();
|
||||
|
||||
JSTaggedType *currentSp = const_cast<JSTaggedType *>(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<TaggedArray> 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<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
thread->SetCurrentSPFrame(state->base.prev);
|
||||
}
|
||||
|
||||
void EcmaInterpreter::NotifyBytecodePcChanged(JSThread *thread)
|
||||
{
|
||||
FrameHandler frameHandler(thread);
|
||||
|
@ -49,8 +49,6 @@ public:
|
||||
JSThread *thread, JSHandle<JSTaggedValue> func, JSHandle<JSTaggedValue> thisObj,
|
||||
JSHandle<JSTaggedValue> newTarget, size_t numArgs);
|
||||
static inline JSTaggedValue GeneratorReEnterInterpreter(JSThread *thread, JSHandle<GeneratorContext> context);
|
||||
static inline void ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> 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);
|
||||
|
@ -703,61 +703,6 @@ JSTaggedValue InterpreterAssembly::GeneratorReEnterInterpreter(JSThread *thread,
|
||||
return res;
|
||||
}
|
||||
|
||||
void InterpreterAssembly::ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> context)
|
||||
{
|
||||
JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
|
||||
JSMethod *method = func->GetCallTarget();
|
||||
|
||||
JSTaggedType *currentSp = const_cast<JSTaggedType *>(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<TaggedArray> 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<JSTaggedType *>(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)
|
||||
|
@ -41,8 +41,6 @@ public:
|
||||
static JSTaggedValue Execute(EcmaRuntimeCallInfo *info);
|
||||
static JSTaggedValue ExecuteNative(EcmaRuntimeCallInfo *info);
|
||||
static JSTaggedValue GeneratorReEnterInterpreter(JSThread *thread, JSHandle<GeneratorContext> context);
|
||||
static void ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> context);
|
||||
static void ResumeContext(JSThread *thread);
|
||||
static uint32_t FindCatchBlock(JSMethod *caller, uint32_t pc);
|
||||
static inline size_t GetJumpSizeAfterCall(const uint8_t *prevPc);
|
||||
|
||||
|
@ -92,13 +92,11 @@ JSHandle<JSTaggedValue> JSAsyncAwaitStatusFunction::AsyncFunctionAwaitFulfilled(
|
||||
JSHandle<GeneratorContext> 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<JSObject> 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<JSTaggedValue> JSAsyncAwaitStatusFunction::AsyncFunctionAwaitRejected(
|
||||
JSHandle<GeneratorContext> 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<JSObject> 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.
|
||||
|
||||
|
@ -71,15 +71,12 @@ JSHandle<JSObject> 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<JSObject> result = GeneratorHelper::Next(thread, genContext, value);
|
||||
GeneratorHelper::ResumeContext(thread);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -128,8 +125,6 @@ JSHandle<JSObject> 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<JSObject> JSGeneratorObject::GeneratorResumeAbrupt(JSThread *thread,
|
||||
} else {
|
||||
result = GeneratorHelper::Throw(thread, genContext, abruptCompletion->GetValue());
|
||||
}
|
||||
GeneratorHelper::ResumeContext(thread);
|
||||
return result;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
Loading…
Reference in New Issue
Block a user