Fix updateHotnessCounter performance bug

1 remove some useless code
2 add param this Func for UpdateHotnessCounter
3 fix default hotnessCounter from 512 to int16_t max

issue: I5LGCS

Signed-off-by: sunzhe23 <sunzhe23@huawei.com>
This commit is contained in:
sunzhe23 2022-08-10 12:07:46 +08:00
parent a76f94f995
commit 38acdc0239
14 changed files with 220 additions and 246 deletions

View File

@ -134,13 +134,13 @@ GateRef CircuitBuilder::TaggedIsException(GateRef x)
GateRef CircuitBuilder::TaggedIsSpecial(GateRef x)
{
return BoolOr(
Equal(Int64And(x, Int64(JSTaggedValue::TAG_SPECIAL_MARK)), Int64(JSTaggedValue::TAG_SPECIAL)),
Equal(Int64And(x, Int64(JSTaggedValue::TAG_SPECIAL_MASK)), Int64(JSTaggedValue::TAG_SPECIAL)),
TaggedIsHole(x));
}
GateRef CircuitBuilder::TaggedIsHeapObject(GateRef x)
{
return Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MARK)), Int64(0));
return Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MASK)), Int64(0));
}
GateRef CircuitBuilder::TaggedIsAsyncGeneratorObject(GateRef x)

View File

@ -109,15 +109,16 @@ void name##StubBuilder::GenerateCircuitImpl(GateRef glue, GateRef sp, GateRef pc
#define DISPATCH_LAST_WITH_ACC() \
DispatchLast(glue, sp, pc, constpool, profileTypeInfo, *varAcc, hotnessCounter) \
#define UPDATE_HOTNESS(_sp) \
varHotnessCounter = Int32Add(offset, *varHotnessCounter); \
Branch(Int32LessThan(*varHotnessCounter, Int32(0)), &slowPath, &dispatch); \
Bind(&slowPath); \
{ \
varProfileTypeInfo = CallRuntime(glue, RTSTUB_ID(UpdateHotnessCounter), {}); \
varHotnessCounter = Int32(InterpreterAssembly::METHOD_HOTNESS_THRESHOLD); \
Jump(&dispatch); \
} \
#define UPDATE_HOTNESS(_sp) \
varHotnessCounter = Int32Add(offset, *varHotnessCounter); \
Branch(Int32LessThan(*varHotnessCounter, Int32(0)), &slowPath, &dispatch); \
Bind(&slowPath); \
{ \
GateRef func = GetFunctionFromFrame(GetFrame(_sp)); \
varProfileTypeInfo = CallRuntime(glue, RTSTUB_ID(UpdateHotnessCounter), { func }); \
varHotnessCounter = Int32(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD); \
Jump(&dispatch); \
} \
Bind(&dispatch);
#define CHECK_EXCEPTION(res, offset) \

View File

@ -562,43 +562,41 @@ inline GateRef StubBuilder::TaggedIsException(GateRef x)
inline GateRef StubBuilder::TaggedIsSpecial(GateRef x)
{
return BoolOr(Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_SPECIAL_MARK)),
return BoolOr(Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_SPECIAL_MASK)),
Int64(JSTaggedValue::TAG_SPECIAL)), TaggedIsHole(x));
}
inline GateRef StubBuilder::TaggedIsHeapObject(GateRef x)
{
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MARK)), Int64(0));
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MASK)), Int64(0));
}
inline GateRef StubBuilder::TaggedIsGeneratorObject(GateRef x)
{
GateRef isHeapObj = SExtInt1ToInt32(TaggedIsHeapObject(x));
GateRef isHeapObj = TaggedIsHeapObject(x);
GateRef objType = GetObjectType(LoadHClass(x));
GateRef isGeneratorObj =
SExtInt1ToInt32(Int32Equal(objType, Int32(static_cast<int32_t>(JSType::JS_GENERATOR_OBJECT))));
return TruncInt32ToInt1(Int32And(isHeapObj, isGeneratorObj));
Int32Equal(objType, Int32(static_cast<int32_t>(JSType::JS_GENERATOR_OBJECT)));
return BoolAnd(isHeapObj, isGeneratorObj);
}
inline GateRef StubBuilder::TaggedIsAsyncGeneratorObject(GateRef x)
{
GateRef isHeapObj = SExtInt1ToInt32(TaggedIsHeapObject(x));
GateRef isHeapObj = TaggedIsHeapObject(x);
GateRef objType = GetObjectType(LoadHClass(x));
GateRef isGeneratorObj =
SExtInt1ToInt32(Int32Equal(objType, Int32(static_cast<int32_t>(JSType::JS_ASYNC_GENERATOR_OBJECT))));
return TruncInt32ToInt1(Int32And(isHeapObj, isGeneratorObj));
Int32Equal(objType, Int32(static_cast<int32_t>(JSType::JS_ASYNC_GENERATOR_OBJECT)));
return BoolAnd(isHeapObj, isGeneratorObj);
}
inline GateRef StubBuilder::TaggedIsPropertyBox(GateRef x)
{
return TruncInt32ToInt1(
Int32And(SExtInt1ToInt32(TaggedIsHeapObject(x)),
SExtInt1ToInt32(HclassIsPropertyBox(LoadHClass(x)))));
return BoolAnd(TaggedIsHeapObject(x), HclassIsPropertyBox(LoadHClass(x)));
}
inline GateRef StubBuilder::TaggedIsWeak(GateRef x)
{
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_WEAK_MARK)), Int64(JSTaggedValue::TAG_WEAK));
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_WEAK_MASK)), Int64(JSTaggedValue::TAG_WEAK));
}
inline GateRef StubBuilder::TaggedIsPrototypeHandler(GateRef x)
@ -643,7 +641,7 @@ inline GateRef StubBuilder::TaggedIsNull(GateRef x)
inline GateRef StubBuilder::TaggedIsUndefinedOrNull(GateRef x)
{
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MARK)),
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MASK)),
Int64(JSTaggedValue::TAG_SPECIAL));
}
@ -659,8 +657,8 @@ inline GateRef StubBuilder::TaggedIsFalse(GateRef x)
inline GateRef StubBuilder::TaggedIsBoolean(GateRef x)
{
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MARK)),
Int64(JSTaggedValue::TAG_BOOLEAN_MARK));
return Int64Equal(Int64And(x, Int64(JSTaggedValue::TAG_HEAPOBJECT_MASK)),
Int64(JSTaggedValue::TAG_BOOLEAN_MASK));
}
inline GateRef StubBuilder::TaggedGetInt(GateRef x)
@ -1408,6 +1406,15 @@ inline void StubBuilder::SetPropertyInlinedProps(GateRef glue, GateRef obj, Gate
Store(type, glue, obj, ChangeInt32ToIntPtr(propOffset), value);
}
inline GateRef StubBuilder::GetPropertyInlinedProps(GateRef obj, GateRef hClass,
GateRef index, VariableType type)
{
GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hClass);
GateRef propOffset = Int32Mul(
Int32Add(inlinedPropsStart, index), Int32(JSTaggedValue::TaggedTypeSize()));
return Load(type, obj, ZExtInt32ToInt64(propOffset));
}
inline void StubBuilder::IncNumberOfProps(GateRef glue, GateRef hClass)
{
GateRef propNums = GetNumberOfPropsFromHClass(hClass);

View File

@ -451,12 +451,7 @@ GateRef StubBuilder::JSObjectGetProperty(VariableType returnType, GateRef obj, G
{
Bind(&inlinedProp);
{
// GetPropertyInlinedProps
GateRef inlinedPropsStart = GetInlinedPropsStartFromHClass(hClass);
GateRef propOffset = Int32Mul(
Int32Add(inlinedPropsStart, attrOffset),
Int32(JSTaggedValue::TaggedTypeSize()));
result = Load(returnType, obj, ZExtInt32ToInt64(propOffset));
result = GetPropertyInlinedProps(obj, hClass, attrOffset, returnType);
Jump(&exit);
}
Bind(&notInlinedProp);

View File

@ -289,6 +289,8 @@ public:
GateRef IsProtoTypeHClass(GateRef hClass);
void SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
GateRef value, GateRef attrOffset, VariableType type = VariableType::JS_ANY());
GateRef GetPropertyInlinedProps(GateRef obj, GateRef hClass,
GateRef index, VariableType type = VariableType::JS_ANY());
void IncNumberOfProps(GateRef glue, GateRef hClass);
GateRef GetNumberOfPropsFromHClass(GateRef hClass);

View File

@ -681,7 +681,7 @@ void AsmInterpreterCall::ResumeRspAndDispatch(ExtendedAssembler *assembler)
__ Bind(&notUndefined);
{
Label notEcmaObject;
__ Mov(temp, Immediate(JSTaggedValue::TAG_HEAPOBJECT_MARK));
__ Mov(temp, Immediate(JSTaggedValue::TAG_HEAPOBJECT_MASK));
__ And(temp, temp, ret);
__ Cmp(temp, Immediate(0));
__ B(Condition::NE, &notEcmaObject);

View File

@ -959,7 +959,7 @@ void AsmInterpreterCall::ResumeRspAndDispatch(ExtendedAssembler *assembler)
__ Bind(&notUndefined);
{
Label notEcmaObject;
__ Movabs(JSTaggedValue::TAG_HEAPOBJECT_MARK, temp);
__ Movabs(JSTaggedValue::TAG_HEAPOBJECT_MASK, temp);
__ And(ret, temp);
__ Cmpq(0, temp);
__ Jne(&notEcmaObject);

View File

@ -673,14 +673,7 @@ bool FastRuntimeStub::FastSetPropertyByIndex(JSThread *thread, JSTaggedValue rec
JSTaggedValue value)
{
INTERPRETER_TRACE(thread, FastSetPropertyByIndex);
#ifdef ECMASCRIPT_ENABLE_STUB_AOT1
auto stubAddr = thread->GetFastStubEntry(CommonStubCSigns::SetPropertyByIndex);
typedef JSTaggedValue (*PFSetPropertyByIndex)(uintptr_t, JSTaggedValue, uint32_t, JSTaggedValue);
auto setPropertyByIndex = reinterpret_cast<PFSetPropertyByIndex>(stubAddr);
JSTaggedValue result = setPropertyByIndex(thread->GetGlueAddr(), receiver, index, value);
#else
JSTaggedValue result = FastRuntimeStub::SetPropertyByIndex(thread, receiver, index, value);
#endif
if (!result.IsHole()) {
return result != JSTaggedValue::Exception();
}
@ -712,14 +705,7 @@ JSTaggedValue FastRuntimeStub::FastGetPropertyByName(JSThread *thread, JSTaggedV
// Maybe moved by GC
receiver = receiverHandler.GetTaggedValue();
}
#ifdef ECMASCRIPT_ENABLE_STUB_AOT1
auto stubAddr = thread->GetFastStubEntry(CommonStubCSigns::GetPropertyByName);
typedef JSTaggedValue (*PFGetPropertyByName)(uintptr_t, JSTaggedValue, JSTaggedValue);
auto getPropertyByNamePtr = reinterpret_cast<PFGetPropertyByName>(stubAddr);
JSTaggedValue result = getPropertyByNamePtr(thread->GetGlueAddr(), receiver, key);
#else
JSTaggedValue result = FastRuntimeStub::GetPropertyByName(thread, receiver, key);
#endif
if (result.IsHole()) {
return JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(thread, receiver),
JSHandle<JSTaggedValue>(thread, key))
@ -732,14 +718,7 @@ JSTaggedValue FastRuntimeStub::FastGetPropertyByName(JSThread *thread, JSTaggedV
JSTaggedValue FastRuntimeStub::FastGetPropertyByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key)
{
INTERPRETER_TRACE(thread, FastGetPropertyByValue);
#ifdef ECMASCRIPT_ENABLE_STUB_AOT1
auto stubAddr = thread->GetFastStubEntry(CommonStubCSigns::GetPropertyByValue);
typedef JSTaggedValue (*PFGetPropertyByValue)(uintptr_t, JSTaggedValue, JSTaggedValue);
auto getPropertyByValuePtr = reinterpret_cast<PFGetPropertyByValue>(stubAddr);
JSTaggedValue result = getPropertyByValuePtr(thread->GetGlueAddr(), receiver, key);
#else
JSTaggedValue result = FastRuntimeStub::GetPropertyByValue(thread, receiver, key);
#endif
if (result.IsHole()) {
return JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(thread, receiver),
JSHandle<JSTaggedValue>(thread, key))
@ -753,14 +732,7 @@ template<bool UseHole> // UseHole is only for Array::Sort() which requires Hole
JSTaggedValue FastRuntimeStub::FastGetPropertyByIndex(JSThread *thread, JSTaggedValue receiver, uint32_t index)
{
INTERPRETER_TRACE(thread, FastGetPropertyByIndex);
#ifdef ECMASCRIPT_ENABLE_STUB_AOT1
auto stubAddr = thread->GetFastStubEntry(CommonStubCSigns::GetPropertyByIndex);
typedef JSTaggedValue (*PFGetPropertyByIndex)(uintptr_t, JSTaggedValue, uint32_t);
auto getPropertyByIndex = reinterpret_cast<PFGetPropertyByIndex>(stubAddr);
JSTaggedValue result = getPropertyByIndex(thread->GetGlueAddr(), receiver, index);
#else
JSTaggedValue result = FastRuntimeStub::GetPropertyByIndex(thread, receiver, index);
#endif
if (result.IsHole() && !UseHole) {
return JSTaggedValue::GetProperty(thread, JSHandle<JSTaggedValue>(thread, receiver), index)
.GetValue()

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@
namespace panda::ecmascript {
using DispatchEntryPoint =
void (*)(JSThread *, const uint8_t *, JSTaggedType *, JSTaggedValue, JSTaggedValue, JSTaggedValue, int32_t);
void (*)(JSThread *, const uint8_t *, JSTaggedType *, JSTaggedValue, JSTaggedValue, JSTaggedValue, int16_t);
class ConstantPool;
class ECMAObject;
class GeneratorContext;
@ -35,7 +35,6 @@ struct CallParams;
class InterpreterAssembly {
public:
static const uint32_t METHOD_HOTNESS_THRESHOLD = 512;
enum ActualNumArgsOfCall : uint8_t { CALLARG0 = 0, CALLARG1, CALLARGS2, CALLARGS3 };
static void InitStackFrame(JSThread *thread);
static JSTaggedValue Execute(EcmaRuntimeCallInfo *info);
@ -53,12 +52,12 @@ public:
static void HandleOverflow(JSThread *thread, const uint8_t *pc, JSTaggedType *sp,
JSTaggedValue constpool, JSTaggedValue profileTypeInfo,
JSTaggedValue acc, int32_t hotnessCounter);
JSTaggedValue acc, int16_t hotnessCounter);
#define DEF_HANDLER(name) \
static void name(JSThread *thread, const uint8_t *pc, JSTaggedType *sp, \
JSTaggedValue constpool, JSTaggedValue profileTypeInfo, \
JSTaggedValue acc, int32_t hotnessCounter);
JSTaggedValue acc, int16_t hotnessCounter);
ASM_INTERPRETER_BC_STUB_ID_LIST(DEF_HANDLER)
#undef DEF_HANDLER
};

View File

@ -490,7 +490,7 @@ inline bool JSTaggedValue::IsJSProxy() const
inline bool JSTaggedValue::IsBoolean() const
{
return ((value_ & TAG_HEAPOBJECT_MARK) == TAG_BOOLEAN_MARK);
return ((value_ & TAG_HEAPOBJECT_MASK) == TAG_BOOLEAN_MASK);
}
inline bool JSTaggedValue::IsJSObject() const

View File

@ -99,16 +99,16 @@ public:
static constexpr JSTaggedType TAG_SPECIAL = 0x02ULL;
static constexpr JSTaggedType TAG_BOOLEAN = 0x04ULL;
static constexpr JSTaggedType TAG_EXCEPTION = 0x08ULL;
// tag mark
static constexpr JSTaggedType TAG_SPECIAL_MARK = TAG_MARK | TAG_SPECIAL;
static constexpr JSTaggedType TAG_BOOLEAN_MARK = TAG_SPECIAL | TAG_BOOLEAN;
static constexpr JSTaggedType TAG_HEAPOBJECT_MARK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN;
static constexpr JSTaggedType TAG_WEAK_MARK = TAG_HEAPOBJECT_MARK | TAG_WEAK;
// tag mask
static constexpr JSTaggedType TAG_SPECIAL_MASK = TAG_MARK | TAG_SPECIAL;
static constexpr JSTaggedType TAG_BOOLEAN_MASK = TAG_SPECIAL | TAG_BOOLEAN;
static constexpr JSTaggedType TAG_HEAPOBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN;
static constexpr JSTaggedType TAG_WEAK_MASK = TAG_HEAPOBJECT_MASK | TAG_WEAK;
// special value
static constexpr JSTaggedType VALUE_HOLE = 0x05ULL;
static constexpr JSTaggedType VALUE_NULL = TAG_OBJECT | TAG_SPECIAL | TAG_NULL;
static constexpr JSTaggedType VALUE_FALSE = TAG_BOOLEAN_MARK | static_cast<JSTaggedType>(false);
static constexpr JSTaggedType VALUE_TRUE = TAG_BOOLEAN_MARK | static_cast<JSTaggedType>(true);
static constexpr JSTaggedType VALUE_FALSE = TAG_BOOLEAN_MASK | static_cast<JSTaggedType>(false);
static constexpr JSTaggedType VALUE_TRUE = TAG_BOOLEAN_MASK | static_cast<JSTaggedType>(true);
static constexpr JSTaggedType VALUE_UNDEFINED = TAG_SPECIAL;
static constexpr JSTaggedType VALUE_EXCEPTION = TAG_SPECIAL | TAG_EXCEPTION;
static constexpr JSTaggedType VALUE_ZERO = TAG_INT | 0x00ULL;
@ -148,7 +148,7 @@ public:
}
constexpr explicit JSTaggedValue(bool v)
: value_(static_cast<JSTaggedType>(v) | TAG_BOOLEAN_MARK) {}
: value_(static_cast<JSTaggedType>(v) | TAG_BOOLEAN_MASK) {}
explicit JSTaggedValue(double v)
{
@ -194,7 +194,7 @@ public:
inline bool IsWeak() const
{
return ((value_ & TAG_WEAK_MARK) == TAG_WEAK);
return ((value_ & TAG_WEAK_MASK) == TAG_WEAK);
}
inline bool IsDouble() const
@ -209,7 +209,7 @@ public:
inline bool IsSpecial() const
{
return ((value_ & TAG_SPECIAL_MARK) == TAG_SPECIAL) || IsHole();
return ((value_ & TAG_SPECIAL_MASK) == TAG_SPECIAL) || IsHole();
}
inline bool IsObject() const
@ -224,7 +224,7 @@ public:
inline bool IsHeapObject() const
{
return ((value_ & TAG_HEAPOBJECT_MARK) == 0U);
return ((value_ & TAG_HEAPOBJECT_MASK) == 0U);
}
inline double GetDouble() const
@ -285,7 +285,7 @@ public:
inline bool IsUndefinedOrNull() const
{
return ((value_ & TAG_HEAPOBJECT_MARK) == TAG_SPECIAL);
return ((value_ & TAG_HEAPOBJECT_MASK) == TAG_SPECIAL);
}
inline bool IsHole() const

View File

@ -826,16 +826,14 @@ DEF_RUNTIME_STUBS(SetClassConstructorLength)
DEF_RUNTIME_STUBS(UpdateHotnessCounter)
{
RUNTIME_STUBS_HEADER(UpdateHotnessCounter);
auto sp = const_cast<JSTaggedType *>(thread->GetCurrentInterpretedFrame());
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
JSHandle<JSFunction> thisFunc = GetHArg<JSFunction>(argv, argc, 0); // 0: means the zeroth parameter
thread->CheckSafepoint();
auto thisFunc = JSFunction::Cast(state->function.GetTaggedObject());
if (thisFunc->GetProfileTypeInfo() == JSTaggedValue::Undefined()) {
auto method = thisFunc->GetCallTarget();
auto res = RuntimeNotifyInlineCache(thread, JSHandle<JSFunction>(thread, thisFunc), method);
auto res = RuntimeNotifyInlineCache(thread, thisFunc, method);
return res.GetRawData();
}
return thisFunc->GetProfileTypeInfo().GetRawData();
return JSTaggedValue::Undefined().GetRawData();
}
DEF_RUNTIME_STUBS(LoadICByName)

View File

@ -290,10 +290,10 @@ public:
}
template<typename T>
inline static T GetPtrArg(uintptr_t argv, [[maybe_unused]] uint32_t argc, uint32_t index)
inline static T *GetPtrArg(uintptr_t argv, [[maybe_unused]] uint32_t argc, uint32_t index)
{
ASSERT(index < argc);
return reinterpret_cast<T>(*(reinterpret_cast<JSTaggedType *>(argv) + (index)));
return reinterpret_cast<T*>(*(reinterpret_cast<JSTaggedType *>(argv) + (index)));
}
static void DebugPrint(int fmtMessageId, ...);
@ -322,7 +322,7 @@ private:
static inline JSTaggedValue RuntimeCreateAsyncGeneratorObj(JSThread *thread,
const JSHandle<JSTaggedValue> &genFunc);
static inline JSTaggedValue RuntimeAsyncGeneratorResolve(JSThread *thread, JSHandle<JSTaggedValue> asyncFuncObj,
JSHandle<JSTaggedValue> value, JSTaggedValue flag);
static inline JSTaggedValue RuntimeGetTemplateObject(JSThread *thread, const JSHandle<JSTaggedValue> &literal);