arkcompiler_ets_runtime/ecmascript/compiler/interpreter_stub.h
zhouguangyuan 44d28174b8 Split SetValueWithBarrier with ShareValue
1. Split SetValueWithBarrier to three functions, based on if known the value is shared or not.
2. Add a flag to mark the value is shared value or not. And select the corresponding function before call barrier.
3. Add static branch prediction for SetValueWithBarrier.
4. Lower the redundant argument as undef in llvm backend.

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IACEAI

Signed-off-by: ZhouGuangyuan <zhouguangyuan1@huawei.com>
Change-Id: I7a81ea98bceaaf73fa18748195f8da898c13a0fa
2024-07-26 12:47:46 +08:00

280 lines
14 KiB
C++

/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMASCRIPT_COMPILER_INTERPRETER_STUB_H
#define ECMASCRIPT_COMPILER_INTERPRETER_STUB_H
#include "ecmascript/base/config.h"
#include "ecmascript/compiler/bc_call_signature.h"
#include "ecmascript/compiler/profiler_operation.h"
#include "ecmascript/compiler/rt_call_signature.h"
#include "ecmascript/compiler/stub_builder.h"
#include "ecmascript/compiler/circuit_builder-inl.h"
namespace panda::ecmascript::kungfu {
class StringIdInfo {
public:
enum class Offset : uint8_t {
BYTE_0,
BYTE_1,
BYTE_2,
INVALID,
};
enum class Length : uint8_t {
BITS_16,
BITS_32,
INVALID,
};
enum class StringIdType : uint8_t {
STRING_ID,
STRING_ID_INFO,
};
StringIdInfo() : constpool(0), pc(0), offset(Offset::INVALID),
length(Length::INVALID), stringId(0), stringIdType(StringIdType::STRING_ID_INFO) {}
StringIdInfo(GateRef inputConstpool, GateRef inputPc, Offset inputOffset, Length inputLength)
: constpool(inputConstpool), pc(inputPc), offset(inputOffset),
length(inputLength), stringId(0), stringIdType(StringIdType::STRING_ID_INFO) {}
explicit StringIdInfo(GateRef inputConstpool, GateRef inputStringId)
: constpool(inputConstpool), pc(0), offset(Offset::INVALID),
length(Length::INVALID), stringId(inputStringId), stringIdType(StringIdType::STRING_ID) {}
GateRef GetConstantPool() const
{
return constpool;
}
GateRef GetPc() const
{
return pc;
}
Offset GetOffset() const
{
return offset;
}
Length GetLength() const
{
return length;
}
GateRef GetStringId() const
{
return stringId;
}
StringIdType GetStringIdType() const
{
return stringIdType;
}
bool IsValid() const
{
if (stringIdType == StringIdType::STRING_ID_INFO) {
return (constpool != 0) && (pc != 0) && (offset != Offset::INVALID) && (length != Length::INVALID);
}
return stringId != 0;
}
private:
GateRef constpool { 0 };
GateRef pc { 0 };
Offset offset { Offset::INVALID };
Length length { Length::INVALID };
GateRef stringId { 0 };
StringIdType stringIdType { StringIdType::STRING_ID_INFO };
};
class InterpreterStubBuilder : public StubBuilder {
public:
InterpreterStubBuilder(CallSignature *callSignature, Environment *env)
: StubBuilder(callSignature, env) {}
~InterpreterStubBuilder() override = default;
NO_MOVE_SEMANTIC(InterpreterStubBuilder);
NO_COPY_SEMANTIC(InterpreterStubBuilder);
virtual void GenerateCircuit() override = 0;
inline void SetVregValue(GateRef glue, GateRef sp, GateRef idx, GateRef val);
inline GateRef GetVregValue(GateRef sp, GateRef idx);
inline GateRef ReadInst4_0(GateRef pc);
inline GateRef ReadInst4_1(GateRef pc);
inline GateRef ReadInst4_2(GateRef pc);
inline GateRef ReadInst4_3(GateRef pc);
inline GateRef ReadInst8_0(GateRef pc);
inline GateRef ReadInst8_1(GateRef pc);
inline GateRef ReadInst8_2(GateRef pc);
inline GateRef ReadInst8_3(GateRef pc);
inline GateRef ReadInst8_4(GateRef pc);
inline GateRef ReadInst8_5(GateRef pc);
inline GateRef ReadInst8_6(GateRef pc);
inline GateRef ReadInst8_7(GateRef pc);
inline GateRef ReadInst8_8(GateRef pc);
inline GateRef ReadInst8_9(GateRef pc);
inline GateRef ReadInst16_0(GateRef pc);
inline GateRef ReadInst16_1(GateRef pc);
inline GateRef ReadInst16_2(GateRef pc);
inline GateRef ReadInst16_3(GateRef pc);
inline GateRef ReadInst16_4(GateRef pc);
inline GateRef ReadInst16_5(GateRef pc);
inline GateRef ReadInst16_6(GateRef pc);
inline GateRef ReadInst16_7(GateRef pc);
inline GateRef ReadInstSigned8_0(GateRef pc);
inline GateRef ReadInstSigned16_0(GateRef pc);
inline GateRef ReadInstSigned32_0(GateRef pc);
inline GateRef ReadInst32_0(GateRef pc);
inline GateRef ReadInst32_1(GateRef pc);
inline GateRef ReadInst32_2(GateRef pc);
inline GateRef ReadInst64_0(GateRef pc);
inline GateRef GetFrame(GateRef frame);
inline GateRef GetCurrentSpFrame(GateRef glue);
inline GateRef GetLastLeaveFrame(GateRef glue);
inline GateRef GetCurrentFrame(GateRef glue);
inline GateRef GetPcFromFrame(GateRef frame);
inline GateRef GetCallSizeFromFrame(GateRef frame);
inline GateRef GetFunctionFromFrame(GateRef frame);
inline GateRef GetNewTarget(GateRef sp);
inline GateRef GetThisFromFrame(GateRef frame);
inline GateRef GetAccFromFrame(GateRef frame);
inline GateRef GetEnvFromFrame(GateRef frame);
inline GateRef GetEnvFromFunction(GateRef frame);
inline GateRef GetConstpoolFromMethod(GateRef function);
inline GateRef GetModule(GateRef sp);
inline GateRef GetProfileTypeInfoFromFunction(GateRef function);
inline GateRef GetModuleFromFunction(GateRef function);
inline GateRef GetSendableEnvFromModule(GateRef function);
inline GateRef GetHomeObjectFromFunction(GateRef function);
inline GateRef GetResumeModeFromGeneratorObject(GateRef obj);
inline GateRef GetResumeModeFromAsyncGeneratorObject(GateRef obj);
inline GateRef GetHotnessCounterFromMethod(GateRef method);
inline void SetCurrentSpFrame(GateRef glue, GateRef sp);
inline void SetLastLeaveFrame(GateRef glue, GateRef sp);
inline void SetPcToFrame(GateRef glue, GateRef frame, GateRef value);
inline void SetCallSizeToFrame(GateRef glue, GateRef frame, GateRef value);
inline void SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value);
inline void SetAccToFrame(GateRef glue, GateRef frame, GateRef value);
inline void SetEnvToFrame(GateRef glue, GateRef frame, GateRef value);
inline void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
inline void SetFrameState(GateRef glue, GateRef sp, GateRef function, GateRef acc,
GateRef env, GateRef pc, GateRef prev, GateRef type);
inline void UpdateProfileTypeInfoCellToFunction(GateRef glue, GateRef function,
GateRef profileTypeInfo, GateRef slotId);
inline void CheckException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
GateRef res, GateRef offset);
inline void CheckPendingException(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
GateRef res, GateRef offset);
inline void CheckExceptionWithJump(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
GateRef res, Label *jump);
inline void CheckExceptionWithVar(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter,
GateRef res, GateRef offset);
inline GateRef CheckStackOverflow(GateRef glue, GateRef sp);
inline GateRef PushArg(GateRef glue, GateRef sp, GateRef value);
inline GateRef PushUndefined(GateRef glue, GateRef sp, GateRef num);
inline GateRef PushRange(GateRef glue, GateRef sp, GateRef array, GateRef startIndex, GateRef endIndex);
inline GateRef GetStartIdxAndNumArgs(GateRef sp, GateRef restIdx);
inline void Dispatch(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef format);
inline void DispatchWithId(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, GateRef index);
inline void DispatchLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
inline void DispatchDebugger(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
inline void DispatchDebuggerLast(GateRef glue, GateRef sp, GateRef pc, GateRef constpool,
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter);
template <bool needPrint>
void DebugPrintInstruction();
private:
template<typename... Args>
void DispatchBase(GateRef target, GateRef glue, Args... args);
};
class InterpreterToolsStubBuilder : private InterpreterStubBuilder {
public:
InterpreterToolsStubBuilder(CallSignature *callSignature, Environment *env)
: InterpreterStubBuilder(callSignature, env) {}
~InterpreterToolsStubBuilder() override = default;
NO_MOVE_SEMANTIC(InterpreterToolsStubBuilder);
NO_COPY_SEMANTIC(InterpreterToolsStubBuilder);
void GenerateCircuit() override {}
inline GateRef GetStringId(const StringIdInfo &info);
};
#define DECLARE_HANDLE_STUB_CLASS(name) \
class name##StubBuilder : public InterpreterStubBuilder { \
public: \
explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
: InterpreterStubBuilder(callSignature, env) \
{ \
env->GetCircuit()->SetFrameType(FrameType::ASM_INTERPRETER_FRAME); \
} \
~name##StubBuilder() = default; \
NO_MOVE_SEMANTIC(name##StubBuilder); \
NO_COPY_SEMANTIC(name##StubBuilder); \
void GenerateCircuit() override; \
\
protected: \
void GenerateCircuitImpl(GateRef glue, GateRef sp, GateRef pc, GateRef constpool, \
GateRef profileTypeInfo, GateRef acc, GateRef hotnessCounter, \
ProfileOperation callback); \
};
INTERPRETER_BC_STUB_LIST(DECLARE_HANDLE_STUB_CLASS)
ASM_INTERPRETER_BC_HELPER_STUB_LIST(DECLARE_HANDLE_STUB_CLASS)
#define DECLARE_HANDLE_PROFILE_STUB_CLASS(name, base, ...) \
class name##StubBuilder : public base##StubBuilder { \
public: \
explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
: base##StubBuilder(callSignature, env) \
{ \
} \
~name##StubBuilder() = default; \
NO_MOVE_SEMANTIC(name##StubBuilder); \
NO_COPY_SEMANTIC(name##StubBuilder); \
void GenerateCircuit() override; \
};
ASM_INTERPRETER_BC_PROFILER_STUB_LIST(DECLARE_HANDLE_PROFILE_STUB_CLASS)
#undef DECLARE_HANDLE_PROFILE_STUB_CLASS
#define DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS(name, base, ...) \
class name##StubBuilder : public base##StubBuilder { \
public: \
explicit name##StubBuilder(CallSignature *callSignature, Environment *env) \
: base##StubBuilder(callSignature, env) \
{ \
} \
~name##StubBuilder() = default; \
NO_MOVE_SEMANTIC(name##StubBuilder); \
NO_COPY_SEMANTIC(name##StubBuilder); \
void GenerateCircuit() override; \
};
ASM_INTERPRETER_BC_JIT_PROFILER_STUB_LIST(DECLARE_HANDLE_JIT_PROFILE_STUB_CLASS)
#undef DECLARE_HANDLE_PROFILE_STUB_CLASS
#undef DECLARE_HANDLE_STUB_CLASS
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_INTERPRETER_STUB_H