mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Fix(Aot): Class AOT deopt bugfix
Issue: #I8F16D Change-Id: I9226d15c8ac4da5452d98b3a5b23bb925bf3ac8f Signed-off-by: yingguofeng@huawei.com <yingguofeng@huawei.com>
This commit is contained in:
parent
cb2ce85337
commit
8fef64c0a6
@ -407,26 +407,31 @@ void JSHClass::ShouldUpdateProtoClass(const JSThread *thread, const JSHandle<JST
|
||||
JSHandle<JSHClass> hclass(thread, proto->GetTaggedObject()->GetClass());
|
||||
ASSERT(!Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*hclass))->InReadOnlySpace());
|
||||
if (!hclass->IsPrototype()) {
|
||||
// If the objcet should be changed to the proto of an object,
|
||||
// the original hclass cannot be shared.
|
||||
JSHandle<JSHClass> newProtoClass = JSHClass::Clone(thread, hclass);
|
||||
JSTaggedValue layout = newProtoClass->GetLayout();
|
||||
// If the type of object is JSObject, the layout info value is initialized to the default value,
|
||||
// if the value is not JSObject, the layout info value is initialized to null.
|
||||
if (!layout.IsNull()) {
|
||||
JSMutableHandle<LayoutInfo> layoutInfoHandle(thread, layout);
|
||||
layoutInfoHandle.Update(
|
||||
thread->GetEcmaVM()->GetFactory()->CopyLayoutInfo(layoutInfoHandle).GetTaggedValue());
|
||||
newProtoClass->SetLayout(thread, layoutInfoHandle);
|
||||
}
|
||||
// There is no sharing in AOT hclass. Therefore, it is not necessary or possible to clone here.
|
||||
if (!hclass->IsTS()) {
|
||||
// If the objcet should be changed to the proto of an object,
|
||||
// the original hclass cannot be shared.
|
||||
JSHandle<JSHClass> newProtoClass = JSHClass::Clone(thread, hclass);
|
||||
JSTaggedValue layout = newProtoClass->GetLayout();
|
||||
// If the type of object is JSObject, the layout info value is initialized to the default value,
|
||||
// if the value is not JSObject, the layout info value is initialized to null.
|
||||
if (!layout.IsNull()) {
|
||||
JSMutableHandle<LayoutInfo> layoutInfoHandle(thread, layout);
|
||||
layoutInfoHandle.Update(
|
||||
thread->GetEcmaVM()->GetFactory()->CopyLayoutInfo(layoutInfoHandle).GetTaggedValue());
|
||||
newProtoClass->SetLayout(thread, layoutInfoHandle);
|
||||
}
|
||||
|
||||
#if ECMASCRIPT_ENABLE_IC
|
||||
// After the hclass is updated, check whether the proto chain status of ic is updated.
|
||||
NotifyHclassChanged(thread, hclass, newProtoClass);
|
||||
// After the hclass is updated, check whether the proto chain status of ic is updated.
|
||||
NotifyHclassChanged(thread, hclass, newProtoClass);
|
||||
#endif
|
||||
JSObject::Cast(proto->GetTaggedObject())->SynchronizedSetClass(*newProtoClass);
|
||||
newProtoClass->SetIsPrototype(true);
|
||||
thread->GetEcmaVM()->GetPGOProfiler()->UpdateProfileType(*hclass, *newProtoClass);
|
||||
JSObject::Cast(proto->GetTaggedObject())->SynchronizedSetClass(*newProtoClass);
|
||||
newProtoClass->SetIsPrototype(true);
|
||||
thread->GetEcmaVM()->GetPGOProfiler()->UpdateProfileType(*hclass, *newProtoClass);
|
||||
} else {
|
||||
hclass->SetIsPrototype(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,17 +223,20 @@ JSHandle<JSHClass> ClassInfoExtractor::CreateConstructorHClass(JSThread *thread,
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
|
||||
uint32_t length = keys->GetLength();
|
||||
if (length == ClassInfoExtractor::STATIC_RESERVED_LENGTH && base->IsHole() &&
|
||||
properties->Get(NAME_INDEX).IsString()) {
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
if (method->IsAotWithCallField()) {
|
||||
if (method->IsFastCall()) {
|
||||
return JSHandle<JSHClass>(globalConst->GetHandledClassConstructorOptimizedWithFastCallClass());
|
||||
if (!thread->GetEcmaVM()->IsEnablePGOProfiler()) {
|
||||
// The class constructor of AOT is not shared, and PGO collect cannot be shared.
|
||||
if (length == ClassInfoExtractor::STATIC_RESERVED_LENGTH && base->IsHole() &&
|
||||
properties->Get(NAME_INDEX).IsString()) {
|
||||
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
|
||||
if (method->IsAotWithCallField()) {
|
||||
if (method->IsFastCall()) {
|
||||
return JSHandle<JSHClass>(globalConst->GetHandledClassConstructorOptimizedWithFastCallClass());
|
||||
} else {
|
||||
return JSHandle<JSHClass>(globalConst->GetHandledClassConstructorOptimizedClass());
|
||||
}
|
||||
} else {
|
||||
return JSHandle<JSHClass>(globalConst->GetHandledClassConstructorOptimizedClass());
|
||||
return JSHandle<JSHClass>(globalConst->GetHandledClassConstructorClass());
|
||||
}
|
||||
} else {
|
||||
return JSHandle<JSHClass>(globalConst->GetHandledClassConstructorClass());
|
||||
}
|
||||
}
|
||||
JSHandle<JSHClass> hclass;
|
||||
|
@ -221,7 +221,7 @@ bool LayoutInfo::IsUninitializedProperty(const JSObject *object, uint32_t index)
|
||||
return false;
|
||||
}
|
||||
|
||||
JSTaggedValue val = object->GetPropertyInlinedProps(attr.GetOffset());
|
||||
JSTaggedValue val = object->GetPropertyInlinedPropsWithRep(attr.GetOffset(), attr);
|
||||
return val.IsHole();
|
||||
}
|
||||
|
||||
|
@ -640,6 +640,10 @@ void PGOProfiler::DumpICByName(ApEntityId abcId, const CString &recordName, Enti
|
||||
{
|
||||
JSTaggedValue firstValue = profileTypeInfo->Get(slotId);
|
||||
if (!firstValue.IsHeapObject()) {
|
||||
if (firstValue.IsHole()) {
|
||||
// Mega state
|
||||
AddObjectInfoWithMega(abcId, recordName, methodId, bcOffset);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (firstValue.IsWeak()) {
|
||||
@ -659,6 +663,10 @@ void PGOProfiler::DumpICByValue(ApEntityId abcId, const CString &recordName, Ent
|
||||
{
|
||||
JSTaggedValue firstValue = profileTypeInfo->Get(slotId);
|
||||
if (!firstValue.IsHeapObject()) {
|
||||
if (firstValue.IsHole()) {
|
||||
// Mega state
|
||||
AddObjectInfoWithMega(abcId, recordName, methodId, bcOffset);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (firstValue.IsWeak()) {
|
||||
@ -1099,6 +1107,15 @@ void PGOProfiler::AddObjectInfo(ApEntityId abcId, const CString &recordName, Ent
|
||||
AddTranstionObjectInfo(recordType, methodId, bcOffset, receiver, hold, holdTra);
|
||||
}
|
||||
|
||||
void PGOProfiler::AddObjectInfoWithMega(
|
||||
ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset)
|
||||
{
|
||||
auto megaType = ProfileType::CreateMegeType();
|
||||
PGOObjectInfo info(megaType, megaType, megaType, megaType, megaType, megaType);
|
||||
ProfileType recordType = GetRecordProfileType(abcId, recordName);
|
||||
recordInfos_->AddObjectInfo(recordType, methodId, bcOffset, info);
|
||||
}
|
||||
|
||||
void PGOProfiler::AddElementInfo(
|
||||
ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, JSHClass *receiver)
|
||||
{
|
||||
|
@ -140,6 +140,7 @@ private:
|
||||
|
||||
void AddObjectInfo(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
|
||||
JSHClass *receiver, JSHClass *hold, JSHClass *holdTra);
|
||||
void AddObjectInfoWithMega(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset);
|
||||
void AddElementInfo(
|
||||
ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, JSHClass *receiver);
|
||||
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
ModuleRecordId,
|
||||
PrototypeId,
|
||||
ConstructorId,
|
||||
MegaStateKinds,
|
||||
TotalKinds,
|
||||
UnknowId
|
||||
};
|
||||
@ -78,6 +79,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static ProfileType CreateMegeType()
|
||||
{
|
||||
ProfileType type;
|
||||
type.UpdateKind(Kind::MegaStateKinds);
|
||||
return type;
|
||||
}
|
||||
|
||||
ProfileType &Remap(const PGOContext &context);
|
||||
|
||||
bool IsNone() const
|
||||
@ -135,6 +143,11 @@ public:
|
||||
return GetKind() == Kind::PrototypeId;
|
||||
}
|
||||
|
||||
bool IsMegaStateType() const
|
||||
{
|
||||
return GetKind() == Kind::MegaStateKinds;
|
||||
}
|
||||
|
||||
uint32_t GetId() const
|
||||
{
|
||||
return IdBits::Decode(type_);
|
||||
@ -231,6 +244,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsMegaStateType() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ApEntityId GetId() const
|
||||
{
|
||||
return typeId_;
|
||||
|
@ -446,6 +446,11 @@ public:
|
||||
return receiverType_.IsNone();
|
||||
}
|
||||
|
||||
bool IsMegaStateType() const
|
||||
{
|
||||
return receiverType_.IsMegaStateType();
|
||||
}
|
||||
|
||||
bool InConstructor() const
|
||||
{
|
||||
return receiverType_.IsConstructor();
|
||||
@ -507,6 +512,10 @@ public:
|
||||
if (info.IsNone()) {
|
||||
return;
|
||||
}
|
||||
if (info.IsMegaStateType()) {
|
||||
count_ = 0;
|
||||
return;
|
||||
}
|
||||
uint32_t count = 0;
|
||||
for (; count < count_; count++) {
|
||||
if (infos_[count] == info) {
|
||||
|
@ -17,4 +17,6 @@ host_aot_test_action("pgo_class_operation") {
|
||||
deps = []
|
||||
is_only_typed_path = true
|
||||
is_enable_pgo = true
|
||||
is_enable_trace_deopt = true
|
||||
log_option = " --log-info=trace"
|
||||
}
|
||||
|
@ -13,5 +13,3 @@
|
||||
|
||||
5
|
||||
5
|
||||
5
|
||||
5
|
||||
|
@ -18,6 +18,7 @@ declare function print(arg:any):string;
|
||||
class A {
|
||||
x: number;
|
||||
constructor() {
|
||||
// Mega state
|
||||
this.x = 5;
|
||||
}
|
||||
}
|
||||
@ -33,8 +34,34 @@ class C extends A {
|
||||
}
|
||||
}
|
||||
|
||||
class D extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
class E extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
class F extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
class G {
|
||||
x: number;
|
||||
constructor() {
|
||||
this.x = 5;
|
||||
}
|
||||
}
|
||||
|
||||
function foo(a) {
|
||||
print(a.x);
|
||||
// Mega state
|
||||
a.x;
|
||||
}
|
||||
|
||||
function bar(t) {
|
||||
@ -44,8 +71,26 @@ function bar(t) {
|
||||
let a = new A();
|
||||
let b = new B();
|
||||
let c = new C();
|
||||
let d = new D();
|
||||
let e = new E();
|
||||
let f = new F();
|
||||
|
||||
foo(a);
|
||||
foo(b);
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
foo(c);
|
||||
}
|
||||
foo(d);
|
||||
foo(e);
|
||||
foo(f);
|
||||
|
||||
bar(b);
|
||||
bar(c);
|
||||
|
||||
function getPrototypeOf(a)
|
||||
{
|
||||
return a.prototype
|
||||
}
|
||||
|
||||
getPrototypeOf(A);
|
||||
getPrototypeOf(B);
|
||||
|
@ -13,5 +13,3 @@
|
||||
|
||||
5
|
||||
5
|
||||
5
|
||||
5
|
||||
|
Loading…
Reference in New Issue
Block a user