Fix AOT IC bugs

1.Fix wrong initial value when using AOT hclass in NewObjectStubBuilder.
2.Fix wrong BitFiled in StubBuilder::IsAOTHClass.
3.Fix holder to receiver in StubBuilder::StoreICWithHandler.
4.Fill the missing flags in AOT branch of ObjectOperator::AddPropertyInternal.
5.Fix checkReceiverHoleEntry wrong compare(not equal -> equal) in StubBuilder::SetPropertyByName.
6.Add corresponding test case.

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

Signed-off-by: dingding <dingding5@huawei.com>
Change-Id: I1e4f6085f579610e5209300cab6ff9dc5ae49c79
This commit is contained in:
dingding 2023-02-04 09:03:03 +08:00
parent bc4484cb7d
commit e4feca21b9
9 changed files with 85 additions and 4 deletions

View File

@ -74,9 +74,21 @@ void NewObjectStubBuilder::NewJSObject(Variable *result, Label *exit, GateRef hc
Bind(&noException);
{
StoreHClass(glue_, result->ReadVariable(), hclass);
DEFVARIABLE(initValue, VariableType::JS_ANY(), Undefined());
Label isAOT(env);
Label initialize(env);
Branch(IsAOTHClass(hclass), &isAOT, &initialize);
Bind(&isAOT);
{
// The object which created by AOT speculative hclass, should be initialized as hole, means does not exist,
// to follow ECMA spec.
initValue = Hole();
Jump(&initialize);
}
Bind(&initialize);
Label afterInitialize(env);
InitializeWithSpeicalValue(&afterInitialize,
result->ReadVariable(), Undefined(), Int32(JSObject::SIZE), ChangeIntPtrToInt32(size_));
result->ReadVariable(), *initValue, Int32(JSObject::SIZE), ChangeIntPtrToInt32(size_));
Bind(&afterInitialize);
auto emptyArray = GetGlobalConstantValue(
VariableType::JS_POINTER(), glue_, ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX);

View File

@ -1548,7 +1548,7 @@ inline GateRef StubBuilder::GetNumberOfPropsFromHClass(GateRef hClass)
inline GateRef StubBuilder::IsAOTHClass(GateRef hClass)
{
GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD1_OFFSET));
GateRef bitfield = Load(VariableType::INT32(), hClass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
return Int32NotEqual(Int32And(Int32LSR(bitfield,
Int32(JSHClass::IsAOTBit::START_BIT)),
Int32((1LU << JSHClass::IsAOTBit::SIZE) - 1)),

View File

@ -1709,7 +1709,7 @@ GateRef StubBuilder::StoreICWithHandler(GateRef glue, GateRef receiver, GateRef
Branch(IsField(handlerInfo), &aotHandlerInfoIsField, &aotHandlerInfoNotField);
Bind(&aotHandlerInfoIsField);
{
StoreField(glue, *holder, value, handlerInfo);
StoreField(glue, receiver, value, handlerInfo);
Jump(&exit);
}
Bind(&aotHandlerInfoNotField);
@ -2673,7 +2673,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
{
Label storeReceiverHoleEntry(env);
Label noNeedStore(env);
GateRef checkReceiverHoleEntry = Int32NotEqual(*receiverHoleEntry, Int32(-1));
GateRef checkReceiverHoleEntry = Int32Equal(*receiverHoleEntry, Int32(-1));
GateRef checkHolderEqualsRecv = Equal(*holder, receiver);
Branch(BoolAnd(checkReceiverHoleEntry, checkHolderEqualsRecv),
&storeReceiverHoleEntry, &noNeedStore);

View File

@ -1352,6 +1352,8 @@ void ObjectFactory::InitializeExtraProperties(const JSHandle<JSHClass> &hclass,
{
ASSERT(inobjPropCount * JSTaggedValue::TaggedTypeSize() < hclass->GetObjectSize());
auto paddr = reinterpret_cast<uintptr_t>(obj) + hclass->GetObjectSize();
// The object which created by AOT speculative hclass, should be initialized as hole, means does not exist,
// to follow ECMA spec.
JSTaggedType initVal = hclass->IsAOT() ? JSTaggedValue::VALUE_HOLE : JSTaggedValue::VALUE_UNDEFINED;
for (uint32_t i = 0; i < inobjPropCount; ++i) {
paddr -= JSTaggedValue::TaggedTypeSize();

View File

@ -724,6 +724,8 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
return;
}
// The property has already existed whose value is hole, initialized by speculative hclass.
// Not need AddProperty,just SetProperty
if (receiverHoleEntry_ != -1) {
auto *hclass = receiver_->GetTaggedObject()->GetClass();
LayoutInfo *layoutInfo = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
@ -731,6 +733,8 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
JSObject::Cast(receiver_.GetTaggedValue())->SetProperty(thread_, hclass, attr, value.GetTaggedValue());
uint32_t index = attr.IsInlinedProps() ? attr.GetOffset() :
attr.GetOffset() - obj->GetJSHClass()->GetInlinedProperties();
SetIsAOT(true);
SetIsOnPrototype(false);
SetFound(index, value.GetTaggedValue(), attr.GetValue(), true);
return;
}

View File

@ -84,6 +84,7 @@ group("ark_aot_test") {
"getunmappedargs:getunmappedargsAotAction",
"global_this_ts:global_this_tsAotAction",
"helloaot:helloaotAotAction",
"ic:icAotAction",
"inc:incAotAction",
"inline:inlineAotAction",
"instanceof:instanceofAotAction",

18
test/aottest/ic/BUILD.gn Normal file
View File

@ -0,0 +1,18 @@
# Copyright (c) 2023 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.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("ic") {
deps = []
}

View File

@ -0,0 +1,15 @@
# Copyright (c) 2023 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.
123
123

29
test/aottest/ic/ic.ts Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 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.
*/
declare function print(a:any):string;
class C {
x:number;
constructor() {
this.x = 123;
}
}
let c1 = new C();
print(c1.x);
let c2 = new C();
print(c2.x);