Optimize performance

DefineField function C++ TO IR

Issue: IA99AA

Trst: Build & Boot devices

Signed-off-by: 马昌友 <2390893665@qq.com>
This commit is contained in:
马昌友 2024-07-01 20:37:38 +08:00
parent b4991165fc
commit e004f84b8d
8 changed files with 189 additions and 16 deletions

View File

@ -262,7 +262,7 @@ CallSignature BaselineStubCSigns::callSigns_[BaselineStubCSigns::NUM_OF_STUBS];
} \
Bind(&slowPath); \
{ \
result = CallRuntime(glue, RTSTUB_ID(DefineField), {receiver, propKey, acc}); \
result = DefineField(glue, receiver, propKey, acc); \
Jump(&exit); \
} \
Bind(&exit)
@ -5959,8 +5959,7 @@ void BaselineCallRuntimeDefineFieldByValuePrefImm8V8V8StubBuilder::GenerateCircu
GateRef v1 = Int32Argument(PARAM_INDEX(BaselineCallRuntimeDefineFieldByValuePrefImm8V8V8, V1));
GateRef obj = GetVregValue(sp, ZExtInt8ToPtr(v1));
GateRef propKey = GetVregValue(sp, ZExtInt8ToPtr(v0));
GateRef res = CallRuntime(glue, RTSTUB_ID(DefineField), {obj, propKey, acc}); // acc as value
GateRef res = DefineField(glue, obj, propKey, acc);
CHECK_EXCEPTION_WITH_ACC(res);
}
@ -5974,7 +5973,7 @@ void BaselineCallRuntimeDefineFieldByIndexPrefImm8Imm32V8StubBuilder::GenerateCi
GateRef propKey = IntToTaggedInt(index);
GateRef obj = GetVregValue(sp, ZExtInt8ToPtr(v0));
GateRef res = CallRuntime(glue, RTSTUB_ID(DefineField), {obj, propKey, acc}); // acc as value
GateRef res = DefineField(glue, obj, propKey, acc);
CHECK_EXCEPTION_WITH_ACC(res);
}

View File

@ -419,7 +419,7 @@ void name##StubBuilder::GenerateCircuitImpl(GateRef glue, GateRef sp, GateRef pc
} \
Bind(&slowPath); \
{ \
result = CallRuntime(glue, RTSTUB_ID(DefineField), {receiver, propKey, acc}); \
result = DefineField(glue, receiver, propKey, acc); \
Jump(&exit); \
} \
Bind(&exit)
@ -5497,7 +5497,7 @@ DECLARE_ASM_HANDLER(HandleCallRuntimeDefineFieldByValuePrefImm8V8V8)
GateRef v1 = ReadInst8_3(pc);
GateRef obj = GetVregValue(sp, ZExtInt8ToPtr(v1));
GateRef propKey = GetVregValue(sp, ZExtInt8ToPtr(v0));
GateRef res = CallRuntime(glue, RTSTUB_ID(DefineField), {obj, propKey, acc}); // acc as value
GateRef res = DefineField(glue, obj, propKey, acc);
CHECK_EXCEPTION_WITH_ACC(res, INT_PTR(CALLRUNTIME_DEFINEFIELDBYVALUE_PREF_IMM8_V8_V8));
}
@ -5507,7 +5507,7 @@ DECLARE_ASM_HANDLER(HandleCallRuntimeDefineFieldByIndexPrefImm8Imm32V8)
GateRef v0 = ReadInst8_6(pc);
GateRef obj = GetVregValue(sp, ZExtInt8ToPtr(v0));
GateRef propKey = IntToTaggedInt(index);
GateRef res = CallRuntime(glue, RTSTUB_ID(DefineField), {obj, propKey, acc}); // acc as value
GateRef res = DefineField(glue, obj, propKey, acc);
CHECK_EXCEPTION_WITH_ACC(res, INT_PTR(CALLRUNTIME_DEFINEFIELDBYINDEX_PREF_IMM8_IMM32_V8));
}

View File

@ -1137,6 +1137,16 @@ inline GateRef StubBuilder::IsJSHClass(GateRef obj)
return res;
}
inline void StubBuilder::CanNotConvertNotValidObject([[maybe_unused]] GateRef obj)
{
ASM_ASSERT(GET_MESSAGE_STRING_ID(CanNotConvertNotValidObject), IsEcmaObject(obj));
}
inline void StubBuilder::IsNotPropertyKey([[maybe_unused]] GateRef flag)
{
ASM_ASSERT(GET_MESSAGE_STRING_ID(IsNotPropertyKey), flag);
}
// object operation
inline GateRef StubBuilder::LoadHClass(GateRef object)
{

View File

@ -550,6 +550,150 @@ GateRef StubBuilder::GetKeyHashCode(GateRef glue, GateRef key, GateRef hir)
return ret;
}
GateRef StubBuilder::CreateDataProperty(GateRef glue, GateRef obj, GateRef propKey, GateRef value)
{
auto env = GetEnvironment();
Label subentry(env);
env->SubCfgEntry(&subentry);
Label exit(env);
Label next(env);
Label objIsShared(env);
Label objIsNotShared(env);
Label isHole(env);
Label notHole(env);
Label hasPendingException(env);
DEFVARIABLE(result, VariableType::BOOL(), True());
auto flag = SetPropertyByValue(glue, obj, propKey, value, false, ProfileOperation(), true);
GateRef exceptionOffset = IntPtr(JSThread::GlueData::GetExceptionOffset(env->IsArch32Bit()));
GateRef exception = Load(VariableType::JS_ANY(), glue, exceptionOffset);
BRANCH(TaggedIsNotHole(exception), &hasPendingException, &next);
Bind(&hasPendingException);
{
result = False();
Jump(&exit);
}
Bind(&next);
{
BRANCH(TaggedIsHole(flag), &isHole, &notHole);
Bind(&isHole);
{
GateRef temp = CallRuntime(glue, RTSTUB_ID(DefineOwnProperty), {obj, propKey, value});
result = TaggedIsTrue(temp);
Jump(&exit);
}
Bind(&notHole);
{
result = BoolNot(TaggedIsException(flag));
Jump(&exit);
}
}
Bind(&exit);
auto ret = *result;
env->SubCfgExit();
return ret;
}
GateRef StubBuilder::CreateDataPropertyOrThrow(GateRef glue, GateRef obj, GateRef key, GateRef value)
{
auto env = GetEnvironment();
Label subentry(env);
env->SubCfgEntry(&subentry);
Label exit(env);
Label isPropertyKey(env);
Label isNotStringOrSymbol(env);
Label isNotNumber(env);
Label newThrow(env);
Label isNotThrow(env);
DEFVARIABLE(result, VariableType::BOOL(), True());
DEFVARIABLE(isPropertyKeyFlag, VariableType::BOOL(), True());
CanNotConvertNotValidObject(obj);
BRANCH(TaggedIsStringOrSymbol(key), &isPropertyKey, &isNotStringOrSymbol);
Bind(&isNotStringOrSymbol);
{
BRANCH(TaggedIsNumber(key), &isPropertyKey, &isNotNumber);
Bind(&isNotNumber);
{
isPropertyKeyFlag = False();
Jump(&isPropertyKey);
}
}
Bind(&isPropertyKey);
{
IsNotPropertyKey(*isPropertyKeyFlag);
result = CreateDataProperty(glue, obj, key, value);
BRANCH(*result, &exit, &isNotThrow);
Bind(&isNotThrow);
{
GateRef exceptionOffset = IntPtr(JSThread::GlueData::GetExceptionOffset(env->IsArch32Bit()));
GateRef exception = Load(VariableType::JS_ANY(), glue, exceptionOffset);
BRANCH(TaggedIsNotHole(exception), &exit, &newThrow);
Bind(&newThrow);
{
GateRef msgIntId = Int32(GET_MESSAGE_STRING_ID(CreateDataPropertyFailed));
CallRuntime(glue, RTSTUB_ID(ThrowTypeError), { IntToTaggedInt(msgIntId)});
Jump(&exit);
}
}
}
Bind(&exit);
auto ret = *result;
env->SubCfgExit();
return ret;
}
GateRef StubBuilder::DefineField(GateRef glue, GateRef obj, GateRef propKey, GateRef value)
{
auto env = GetEnvironment();
Label entry(env);
env->SubCfgEntry(&entry);
Label exit(env);
Label next(env);
Label newThrow(env);
Label isObj(env);
Label notObj(env);
Label hasPendingException(env);
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
DEFVARIABLE(key, VariableType::JS_ANY(), Undefined());
BRANCH(IsEcmaObject(obj), &isObj, &notObj);
Bind(&isObj);
{
key = CallRuntime(glue, RTSTUB_ID(ToPropertyKey), {propKey});
BRANCH(HasPendingException(glue), &hasPendingException, &next);
}
Bind(&next);
{
CreateDataPropertyOrThrow(glue, obj, *key, value);
BRANCH(HasPendingException(glue), &hasPendingException, &exit);
}
Bind(&notObj);
{
BRANCH(HasPendingException(glue), &hasPendingException, &newThrow);
}
Bind(&hasPendingException);
{
result = Exception();
Jump(&exit);
}
Bind(&newThrow);
{
GateRef msgIntId = Int32(GET_MESSAGE_STRING_ID(DefineFieldField));
CallRuntime(glue, RTSTUB_ID(ThrowTypeError), { IntToTaggedInt(msgIntId)});
result = Exception();
Jump(&exit);
}
Bind(&exit);
auto ret = *result;
env->SubCfgExit();
return ret;
}
GateRef StubBuilder::FindElementFromNumberDictionary(GateRef glue, GateRef elements, GateRef index)
{
auto env = GetEnvironment();
@ -3849,7 +3993,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
Bind(&notDictionaryElement);
{
Label isReceiver(env);
if (useOwn) {
if (useOwn || defineSemantics) {
BRANCH(Equal(*holder, receiver), &isReceiver, &ifEnd);
} else {
BRANCH(Equal(*holder, receiver), &isReceiver, &afterLoop);
@ -3858,7 +4002,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
{
GateRef length = GetLengthOfTaggedArray(elements);
Label inRange(env);
if (useOwn) {
if (useOwn || defineSemantics) {
BRANCH(Int64LessThan(index, length), &inRange, &ifEnd);
} else {
BRANCH(Int64LessThan(index, length), &inRange, &loopExit);
@ -3867,7 +4011,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
{
GateRef value1 = GetTaggedValueWithElementsKind(*holder, index);
Label notHole(env);
if (useOwn) {
if (useOwn || defineSemantics) {
BRANCH(Int64NotEqual(value1, Hole()), &notHole, &ifEnd);
} else {
BRANCH(Int64NotEqual(value1, Hole()), &notHole, &loopExit);
@ -3931,7 +4075,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
Bind(&notAccessor);
{
Label holdEqualsRecv(env);
if (useOwn) {
if (useOwn || defineSemantics) {
BRANCH(Equal(*holder, receiver), &holdEqualsRecv, &ifEnd);
} else {
BRANCH(Equal(*holder, receiver), &holdEqualsRecv, &afterLoop);
@ -3955,7 +4099,7 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
Jump(&exit);
}
}
if (useOwn) {
if (useOwn || defineSemantics) {
Bind(&ifEnd);
} else {
Bind(&loopExit);
@ -4022,7 +4166,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
Label loopExit(env);
Label afterLoop(env);
Label findProperty(env);
if (!useOwn) {
if (!useOwn && !defineSemantics) {
// a do while loop
Jump(&loopHead);
LoopBegin(&loopHead);
@ -4076,7 +4220,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
Bind(&notSIndexObj);
{
if (canUseIsInternal) {
if (useOwn) {
if (useOwn || defineSemantics) {
BRANCH(isInternal, &findProperty, &ifEnd);
} else {
BRANCH(isInternal, &findProperty, &loopExit);
@ -4246,7 +4390,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
Bind(&writable1);
{
Label holdEqualsRecv1(env);
if (useOwn) {
if (useOwn || defineSemantics) {
BRANCH(Equal(*holder, receiver), &holdEqualsRecv1, &ifEnd);
} else {
BRANCH(Equal(*holder, receiver), &holdEqualsRecv1, &afterLoop);

View File

@ -359,6 +359,8 @@ public:
GateRef GetExtractLengthOfTaggedArray(GateRef array);
// object operation
GateRef IsJSHClass(GateRef obj);
void CanNotConvertNotValidObject(GateRef obj);
void IsNotPropertyKey(GateRef obj);
GateRef LoadHClass(GateRef object);
void StoreHClass(GateRef glue, GateRef object, GateRef hClass);
void StoreHClassWithoutBarrier(GateRef glue, GateRef object, GateRef hClass);
@ -931,6 +933,9 @@ public:
inline void SetToPropertiesCache(GateRef glue, GateRef cache, GateRef cls, GateRef key, GateRef result,
GateRef hir = Circuit::NullGate());
GateRef HashFromHclassAndKey(GateRef glue, GateRef cls, GateRef key, GateRef hir = Circuit::NullGate());
GateRef CreateDataProperty(GateRef glue, GateRef obj, GateRef proKey, GateRef value);
GateRef CreateDataPropertyOrThrow(GateRef glue, GateRef onj, GateRef proKey, GateRef value);
GateRef DefineField(GateRef glue, GateRef obj, GateRef proKey, GateRef value);
GateRef GetKeyHashCode(GateRef glue, GateRef key, GateRef hir = Circuit::NullGate());
inline GateRef GetSortedKey(GateRef layoutInfo, GateRef index);
inline GateRef GetSortedIndex(GateRef layoutInfo, GateRef index);

View File

@ -62,7 +62,10 @@ namespace panda::ecmascript {
V(ObjIsNotCallable, "obj is not Callable") \
V(SharedObjectRefersLocalObject, "shared object refers a local object") \
V(InvalidRadixLength, "radix must be 2 to 36") \
V(SetPrototypeOfFailed, "SetPrototypeOf: prototype set failed")
V(SetPrototypeOfFailed, "SetPrototypeOf: prototype set failed") \
V(DefineFieldField, "DefineField: obj is not Object") \
V(IsNotPropertyKey, "key is not a property key") \
V(CreateDataPropertyFailed, "failed to create data property")
#define DEBUG_CHECK_MESSAGE_STRING_LIST(V) \
V(IsCallable) \

View File

@ -155,6 +155,17 @@ DEF_RUNTIME_STUBS(FunctionDefineOwnProperty)
return JSTaggedValue::Hole().GetRawData();
}
DEF_RUNTIME_STUBS(DefineOwnProperty)
{
RUNTIME_STUBS_HEADER(DefineOwnProperty);
JSHandle<JSTaggedValue> obj = GetHArg<JSTaggedValue>(argv, argc, 0);
JSHandle<JSTaggedValue> key = GetHArg<JSTaggedValue>(argv, argc, 1); // 1: means the first parameter
JSHandle<JSTaggedValue> value = GetHArg<JSTaggedValue>(argv, argc, 2); // 2: means the second parameter
PropertyDescriptor desc(thread, value, true, true, true);
bool res = JSTaggedValue::DefineOwnProperty(thread, obj, key, desc);
return JSTaggedValue(res).GetRawData();
}
DEF_RUNTIME_STUBS(AllocateInYoung)
{
RUNTIME_STUBS_HEADER(AllocateInYoung);

View File

@ -480,6 +480,7 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
V(ThrowRangeError) \
V(InitializeGeneratorFunction) \
V(FunctionDefineOwnProperty) \
V(DefineOwnProperty) \
V(AOTEnableProtoChangeMarker) \
V(HasProperty) \
V(DumpObject) \