!8196 Fuzz Bugfix:StObjByName Load Key and Hclass Prototype Check

Merge pull request !8196 from yaoyuan/fuzz-hclassPrototype
This commit is contained in:
openharmony_ci 2024-07-18 15:28:23 +00:00 committed by Gitee
commit c90a2da41e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 64 additions and 7 deletions

View File

@ -676,6 +676,19 @@ void TypedBytecodeLowering::LowerTypedStPrivateProperty(GateRef gate)
DeleteConstDataIfNoUser(key);
}
GateRef TypedBytecodeLowering::LoadObjectFromConstantPool(GateRef gate, StoreObjByNameTypeInfoAccessor &tacc,
GateRef frameState, ConstPoolType type)
{
GateRef jsFunc = argAcc_.GetFrameArgsIn(frameState, FrameArgIdx::FUNC);
GateRef module = builder_.GetModuleFromFunction(jsFunc);
GateRef unsharedConstpool = argAcc_.GetFrameArgsIn(frameState, FrameArgIdx::UNSHARED_CONST_POOL);
GateRef sharedConstpool = argAcc_.GetFrameArgsIn(frameState, FrameArgIdx::SHARED_CONST_POOL);
GateRef propKey = builder_.GetObjectFromConstPool(glue_, gate, sharedConstpool, unsharedConstpool,
module, builder_.TruncInt64ToInt32(tacc.GetKey()),
type);
return propKey;
}
void TypedBytecodeLowering::LowerTypedStObjByName(GateRef gate)
{
DISALLOW_GARBAGE_COLLECTION;
@ -725,9 +738,7 @@ void TypedBytecodeLowering::LowerTypedStObjByName(GateRef gate)
builder_.MonoStorePropertyLookUpProto(tacc.GetReceiver(), plrGate, unsharedConstPool, holderHClassIndex,
value);
} else {
auto propKey =
builder_.LoadObjectFromConstPool(argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL),
tacc.GetKey());
GateRef propKey = LoadObjectFromConstantPool(gate, tacc, frameState, ConstPoolType::STRING);
builder_.MonoStoreProperty(tacc.GetReceiver(), plrGate, unsharedConstPool, holderHClassIndex, value,
propKey);
}
@ -786,9 +797,7 @@ void TypedBytecodeLowering::LowerTypedStObjByName(GateRef gate)
builder_.Branch(builder_.IsProtoTypeHClass(receiverHC), &isProto, &notProto,
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isProtoTypeHClass");
builder_.Bind(&isProto);
auto propKey =
builder_.LoadObjectFromConstPool(argAcc_.GetFrameArgsIn(gate, FrameArgIdx::SHARED_CONST_POOL),
tacc.GetKey());
GateRef propKey = LoadObjectFromConstantPool(gate, tacc, frameState, ConstPoolType::STRING);
builder_.CallRuntime(glue_, RTSTUB_ID(UpdateAOTHClass), Gate::InvalidGateRef,
{ receiverHC, newHolderHC, propKey }, gate);
builder_.Jump(&notProto);

View File

@ -124,6 +124,8 @@ private:
void LowerTypedLdPrivateProperty(GateRef gate);
void LowerTypedLdObjByName(GateRef gate);
void LowerTypedStObjByName(GateRef gate);
GateRef LoadObjectFromConstantPool(GateRef gate, StoreObjByNameTypeInfoAccessor &tacc,
GateRef frameState, ConstPoolType type);
void LowerTypedStOwnByName(GateRef gate);
GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder, PropertyLookupResult plr);
GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder,

View File

@ -855,7 +855,33 @@ void JSHClass::NotifyHclassChanged(const JSThread *thread, JSHandle<JSHClass> ol
if (oldHclass.GetTaggedValue() == newHclass.GetTaggedValue()) {
return;
}
ASSERT(newHclass->IsPrototype());
// For now, at pgo profiling stage, we use ProfileType::Kind to mark a hclass is CHC, PHC or IHC.
// We can have case like the following:
//
// class C3 {
// constructor(a5) {
// }
// }
// class C18 extends C3 {
// constructor() {
// super(1);
// C3.valueOf = 1;
// }
// }
// const v37 = new C18();
//
// C3 is profiled as CHC even though its IsPrototype bit is marked as true when 'class C18 extends C3' is executed.
// Since C3 is marked as CHC and it has ProfileType::Kind::ConstructorId,
// when generating hclass at aot, its child hclass and itself will not have IsPrototype bit set as true.
//
// However, we currently support hclass substitution when executing 'C3.valueOf' for C3's oldHclass at runtime.
// Therefore, oldHclass's IsPrototype bit is set as true; But for newHclass, it is generated at aot stage,
// it will not have IsPrototype bit set as true.
//
// Good neww is our AOT hclass can not be shared, hence we can set newHclass IsPrototype as true at here.
if (newHclass->IsTS() && !newHclass->IsPrototype()) {
newHclass->SetIsPrototype(true);
}
JSHClass::NoticeThroughChain(thread, oldHclass, addedKey);
JSHClass::RefreshUsers(thread, oldHclass, newHclass);
}

View File

@ -16,3 +16,6 @@ undefined
a
b
false
1
true
true

View File

@ -56,3 +56,17 @@ function test2()
test2();
print(ArkTools.isAOTDeoptimized(test2));
class C3 {
constructor(a5) {
}
}
class C18 extends C3 {
constructor() {
super(1);
C3.valueOf = 1;
}
}
const v37 = new C18();
print(C3.valueOf);
print(ArkTools.isTSHClass(C3));
print(ArkTools.isAOTCompiled(C18));

View File

@ -16,3 +16,6 @@ undefined
a
b
false
1
false
false