opt SetPropertybyindex

issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8AJTA

Signed-off-by: maojunwei <maojunwei1@huawei.com>
Change-Id: I15876dde150ea0d378a720f4a3d7832fef01492a
This commit is contained in:
maojunwei 2023-10-24 17:23:26 +08:00
parent 347ab4bd0f
commit a60cb7f072
4 changed files with 88 additions and 6 deletions

View File

@ -1328,6 +1328,15 @@ inline GateRef StubBuilder::IsWritable(GateRef attr)
Int32(0));
}
inline GateRef StubBuilder::IsConfigable(GateRef attr)
{
return Int32NotEqual(
Int32And(
Int32LSR(attr, Int32(PropertyAttributes::ConfigurableField::START_BIT)),
Int32((1LLU << PropertyAttributes::ConfigurableField::SIZE) - 1)),
Int32(0));
}
inline GateRef StubBuilder::IsAccessor(GateRef attr)
{
return Int32NotEqual(

View File

@ -2265,11 +2265,12 @@ inline void StubBuilder::UpdateValueAndAttributes(GateRef glue, GateRef elements
Store(VariableType::INT64(), glue, elements, dataOffset, IntToTaggedInt(attr));
}
template<typename DictionaryT>
inline void StubBuilder::UpdateValueInDict(GateRef glue, GateRef elements, GateRef index, GateRef value)
{
GateRef arrayIndex = Int32Add(Int32(NameDictionary::TABLE_HEADER_SIZE),
Int32Mul(index, Int32(NameDictionary::ENTRY_SIZE)));
GateRef valueIndex = Int32Add(arrayIndex, Int32(NameDictionary::ENTRY_VALUE_INDEX));
GateRef arrayIndex = Int32Add(Int32(DictionaryT::TABLE_HEADER_SIZE),
Int32Mul(index, Int32(DictionaryT::ENTRY_SIZE)));
GateRef valueIndex = Int32Add(arrayIndex, Int32(DictionaryT::ENTRY_VALUE_INDEX));
SetValueToTaggedArray(VariableType::JS_ANY(), glue, elements, valueIndex, value);
}
@ -2791,7 +2792,8 @@ GateRef StubBuilder::FindTransitions(GateRef glue, GateRef receiver, GateRef hcl
return ret;
}
GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index, GateRef value, bool useOwn)
GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index, GateRef value, bool useOwn,
ProfileOperation callback)
{
auto env = GetEnvironment();
Label entry(env);
@ -2902,6 +2904,55 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
}
Bind(&isDictionaryElement);
{
GateRef entryA = FindElementFromNumberDictionary(glue, elements, index);
Label negtiveOne(env);
Label notNegtiveOne(env);
Branch(Int32NotEqual(entryA, Int32(-1)), &notNegtiveOne, &negtiveOne);
Bind(&notNegtiveOne);
{
GateRef attr = GetAttributesFromDictionary<NumberDictionary>(elements, entryA);
Label isWritandConfig(env);
Label notWritandConfig(env);
Branch(BoolAnd(IsWritable(attr), IsConfigable(attr)), &isWritandConfig, &notWritandConfig);
Bind(&isWritandConfig);
{
Label isAccessor(env);
Label notAccessor(env);
Branch(IsAccessor(attr), &isAccessor, &notAccessor);
Bind(&isAccessor);
{
GateRef accessor = GetValueFromDictionary<NumberDictionary>(elements, entryA);
Label shouldCall(env);
Branch(ShouldCallSetter(receiver, *holder, accessor, attr), &shouldCall, &notAccessor);
Bind(&shouldCall);
{
returnValue = CallSetterHelper(glue, receiver, accessor, value, callback);
Jump(&exit);
}
}
Bind(&notAccessor);
{
Label holdEqualsRecv(env);
if (useOwn) {
Branch(Equal(*holder, receiver), &holdEqualsRecv, &ifEnd);
} else {
Branch(Equal(*holder, receiver), &holdEqualsRecv, &afterLoop);
}
Bind(&holdEqualsRecv);
{
UpdateValueInDict<NumberDictionary>(glue, elements, entryA, value);
returnValue = Undefined();
Jump(&exit);
}
}
}
Bind(&notWritandConfig);
{
returnValue = Hole();
Jump(&exit);
}
}
Bind(&negtiveOne);
returnValue = Hole();
Jump(&exit);
}
@ -3181,7 +3232,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
{
// dict->UpdateValue(thread, entry, value)
// return JSTaggedValue::Undefined()
UpdateValueInDict(glue, array, entry1, value);
UpdateValueInDict<NameDictionary>(glue, array, entry1, value);
result = Undefined();
Jump(&exit);
}

View File

@ -325,6 +325,7 @@ public:
GateRef IsJSObject(GateRef obj);
GateRef IsEnumerable(GateRef attr);
GateRef IsWritable(GateRef attr);
GateRef IsConfigable(GateRef attr);
GateRef IsAccessor(GateRef attr);
GateRef IsInlinedProperty(GateRef attr);
GateRef IsField(GateRef attr);
@ -545,6 +546,7 @@ public:
GateRef IsDoubleRepInPropAttr(GateRef attr);
GateRef SetTaggedRepInPropAttr(GateRef attr);
void SetHasConstructorToHClass(GateRef glue, GateRef hClass, GateRef value);
template<typename DictionaryT>
void UpdateValueInDict(GateRef glue, GateRef elements, GateRef index, GateRef value);
GateRef GetBitMask(GateRef bitoffset);
GateRef IntPtrEuqal(GateRef x, GateRef y);
@ -559,7 +561,8 @@ public:
void FastSetPropertyByName(GateRef glue, GateRef obj, GateRef key, GateRef value,
ProfileOperation callback = ProfileOperation());
void FastSetPropertyByIndex(GateRef glue, GateRef obj, GateRef index, GateRef value);
GateRef SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index, GateRef value, bool useOwn);
GateRef SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index,
GateRef value, bool useOwn, ProfileOperation callback = ProfileOperation());
GateRef SetPropertyByName(GateRef glue, GateRef receiver, GateRef key,
GateRef value, bool useOwn, ProfileOperation callback = ProfileOperation()); // Crawl prototype chain
GateRef SetPropertyByValue(GateRef glue, GateRef receiver, GateRef key, GateRef value, bool useOwn,

View File

@ -352,6 +352,25 @@ JSTaggedValue ObjectFastOperator::SetPropertyByIndex(JSThread *thread, JSTaggedV
}
}
} else {
NumberDictionary *dict = NumberDictionary::Cast(elements);
int entry = dict->FindEntry(JSTaggedValue(static_cast<int>(index)));
if (entry != -1) {
auto attr = dict->GetAttributes(entry);
if (UNLIKELY(!attr.IsWritable() || !attr.IsConfigurable())) {
return JSTaggedValue::Hole();
}
if (UNLIKELY(holder != receiver)) {
break;
}
if (UNLIKELY(attr.IsAccessor())) {
auto accessor = dict->GetValue(entry);
if (ShouldCallSetter(receiver, holder, accessor, attr)) {
return CallSetter(thread, receiver, value, accessor);
}
}
dict->UpdateValue(thread, entry, value);
return JSTaggedValue::Undefined();
}
return JSTaggedValue::Hole();
}
if (UseOwn) {