!8328 Fix deopt of hclass

Merge pull request !8328 from xing-yunhao/fix_deopt_hclass
This commit is contained in:
openharmony_ci 2024-08-04 02:33:36 +00:00 committed by Gitee
commit a65dfdea3a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
20 changed files with 168 additions and 138 deletions

View File

@ -22,10 +22,10 @@
#include "ecmascript/compiler/aot_file/an_file_data_manager.h"
#include "ecmascript/compiler/aot_file/an_file_info.h"
#include "ecmascript/compiler/aot_file/aot_file_info.h"
#include "ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.h"
#include "ecmascript/compiler/aot_file/binary_buffer_parser.h"
#include "ecmascript/compiler/aot_file/module_section_des.h"
#include "ecmascript/compiler/aot_file/stub_file_info.h"
#include "ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.h"
#include "ecmascript/compiler/binary_section.h"
#include "ecmascript/deoptimizer/calleeReg.h"
#include "ecmascript/js_function.h"
@ -42,18 +42,20 @@ namespace kungfu {
class ArkStackMapParser;
} // namespace kungfu
/* AOTLiteralInfo (TaggedArray)
* +--------------------------------------------------+------
* | AOT Function CodeEntry of 1st Method | ^
* | (NO_FUNC_ENTRY_VALUE if NoMethodEntry) | |
* | ... | MethodsCache
* | ... | |
* | AOT Function CodeEntry of nth Method | v
* +--------------------------------------------------+------
* | AOT Instance Hclass (IHC) (JSTaggedValue) |
* | AOT Constructor Hclass (CHC) (JSTaggedValue) |
* +--------------------------------------------------+
*
/* AOTLiteralInfo
* +-----------------------------------+----
* | ... | ^
* | ... | |
* | cache(store function entry index) | AOT Function Entry Index, if its value is -1,
* | ... | means the function has not been compiled with AOT.
* | ... | v
* +-----------------------------------+----
* | Literal Type | JSTaggedValue(int32_t)
* +-----------------------------------+----
* | AOT Instance Hclass (IHC) | JSTaggedValue(HClass)
* +-----------------------------------+----
* | AOT Constructor Hclass (CHC) | JSTaggedValue(HClass)
* +-----------------------------------+----
*/
class AOTLiteralInfo : public TaggedArray {
public:
@ -66,10 +68,10 @@ public:
static constexpr int32_t METHOD_LITERAL_TYPE = 1;
static constexpr int32_t INVALID_LITERAL_TYPE = 0;
static AOTLiteralInfo *Cast(TaggedObject *object)
static AOTLiteralInfo* Cast(TaggedObject* object)
{
ASSERT(JSTaggedValue(object).IsTaggedArray());
return static_cast<AOTLiteralInfo *>(object);
return static_cast<AOTLiteralInfo*>(object);
}
static size_t ComputeSize(uint32_t cacheSize)
@ -121,8 +123,8 @@ public:
{
return Get(index);
}
private:
private:
inline size_t GetIhcOffset() const
{
return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_IHC_INDEX);
@ -141,7 +143,7 @@ private:
class AOTFileManager {
public:
explicit AOTFileManager(EcmaVM *vm);
explicit AOTFileManager(EcmaVM* vm);
virtual ~AOTFileManager();
static constexpr char FILE_EXTENSION_AN[] = ".an";
@ -152,36 +154,40 @@ public:
static void SetJsAotReader(JsAotReaderCallback cb);
static JsAotReaderCallback GetJsAotReader();
#endif
void LoadStubFile(const std::string &fileName);
static bool LoadAnFile(const std::string &fileName);
void LoadStubFile(const std::string& fileName);
static bool LoadAnFile(const std::string& fileName);
static AOTFileInfo::CallSiteInfo CalCallSiteInfo(uintptr_t retAddr);
static bool TryReadLock();
static bool InsideStub(uintptr_t pc);
static bool InsideAOT(uintptr_t pc);
bool IsEnableAOT() const;
void Iterate(const RootVisitor &v);
void Iterate(const RootVisitor& v);
const std::shared_ptr<AnFileInfo> GetAnFileInfo(const JSPandaFile *jsPandaFile) const;
bool IsLoadMain(const JSPandaFile *jsPandaFile, const CString &entry) const;
const std::shared_ptr<AnFileInfo> GetAnFileInfo(const JSPandaFile* jsPandaFile) const;
bool IsLoadMain(const JSPandaFile* jsPandaFile, const CString& entry) const;
uint32_t GetFileIndex(uint32_t anFileInfoIndex, CString abcNormalizedName) const;
std::list<CString> GetPandaFiles(uint32_t aotFileInfoIndex);
uint32_t GetAnFileIndex(const JSPandaFile *jsPandaFile) const;
void BindPreloadedPandaFilesInAotFile(const std::string &moduleName);
bool HasPandaFile(uint32_t aotFileInfoIndex, const CString &abcNormalizedName) const;
void BindPandaFileInAotFile(const std::string &aotFileBaseName, JSPandaFile *jsPandaFile) const;
void SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile,
uint32_t GetAnFileIndex(const JSPandaFile* jsPandaFile) const;
void BindPreloadedPandaFilesInAotFile(const std::string& moduleName);
bool HasPandaFile(uint32_t aotFileInfoIndex, const CString& abcNormalizedName) const;
void BindPandaFileInAotFile(const std::string& aotFileBaseName, JSPandaFile* jsPandaFile) const;
void SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc,
const JSPandaFile* jsPandaFile,
std::string_view entryPoint);
void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, JSFunction *function,
Method *method, uint32_t entryIndex = 0, bool *canFastCall = nullptr);
bool LoadAiFile([[maybe_unused]] const std::string &filename);
bool LoadAiFile(const JSPandaFile *jsPandaFile);
void SetAOTFuncEntry(const JSPandaFile* jsPandaFile,
JSFunction* function,
Method* method,
uint32_t entryIndex = 0,
bool* canFastCall = nullptr);
bool LoadAiFile([[maybe_unused]] const std::string& filename);
bool LoadAiFile(const JSPandaFile* jsPandaFile);
kungfu::ArkStackMapParser* GetStackMapParser() const;
static JSTaggedValue GetAbsolutePath(JSThread *thread, JSTaggedValue relativePathVal);
static bool GetAbsolutePath(const CString &relativePathCstr, CString &absPathCstr);
static JSTaggedValue GetAbsolutePath(JSThread* thread, JSTaggedValue relativePathVal);
static bool GetAbsolutePath(const CString& relativePathCstr, CString& absPathCstr);
static bool RewriteDataSection(uintptr_t dataSec, size_t size, uintptr_t newData, size_t newSize);
void ParseDeserializedData(const CString &snapshotFileName, JSTaggedValue deserializedData);
JSHandle<JSTaggedValue> GetDeserializedConstantPool(const JSPandaFile *jsPandaFile, int32_t cpID);
const Heap *GetHeap();
void ParseDeserializedData(const CString& snapshotFileName, JSTaggedValue deserializedData);
JSHandle<JSTaggedValue> GetDeserializedConstantPool(const JSPandaFile* jsPandaFile, int32_t cpID);
const Heap* GetHeap();
static void DumpAOTInfo() DUMP_API_ATTR;
@ -211,5 +217,5 @@ private:
friend class AnFileInfo;
friend class StubFileInfo;
};
} // namespace panda::ecmascript
} // namespace panda::ecmascript
#endif // ECMASCRIPT_COMPILER_AOT_FILE_AOT_FILE_MANAGER_H

View File

@ -1298,12 +1298,50 @@ void StubBuilder::JSHClassAddProperty(GateRef glue, GateRef receiver, GateRef ke
Label exit(env);
GateRef hclass = LoadHClass(receiver);
GateRef metaData = GetPropertyMetaDataFromAttr(attr);
GateRef newClass = FindTransitions(glue, receiver, hclass, key, metaData, value);
GateRef newClass = FindTransitions(glue, hclass, key, metaData, value);
Label findHClass(env);
Label notFindHClass(env);
BRANCH(Equal(newClass, Undefined()), &notFindHClass, &findHClass);
Bind(&findHClass);
{
GateRef isTSHClass = IsTSHClass(newClass);
Label setPrototype(env);
Label endSetPrototypeCheck(env);
Branch(isTSHClass, &setPrototype, &endSetPrototypeCheck);
Bind(&setPrototype);
{
GateRef prototype = GetPrototypeFromHClass(hclass);
StorePrototype(glue, newClass, prototype);
Jump(&endSetPrototypeCheck);
}
Bind(&endSetPrototypeCheck);
StoreHClass(glue, receiver, newClass);
#if ECMASCRIPT_ENABLE_IC
Label needUpdateAOTHClass(env);
Label normalNotify(env);
Label endUpdate(env);
GateRef updateCondition = BoolAnd(isTSHClass, IsProtoTypeHClass(newClass));
Branch(updateCondition, &needUpdateAOTHClass, &normalNotify);
Bind(&needUpdateAOTHClass);
{
// Use single CallRuntime here to perform both function: UpadteAOTHClass and
// TryRestoreElementsKind, reducing the overhead of one CallRuntime
CallRuntime(glue, RTSTUB_ID(UpdateAOTHcAndTryResotreEleKind),
{ receiver, hclass, newClass, key });
Jump(&endUpdate);
}
Bind(&normalNotify);
{
// Because we currently only supports Fast ElementsKind
CallRuntime(glue, RTSTUB_ID(TryRestoreElementsKind), { receiver, newClass });
NotifyHClassChanged(glue, hclass, newClass);
Jump(&endUpdate);
}
Bind(&endUpdate);
#else
// Because we currently only supports Fast ElementsKind
CallRuntime(glue, RTSTUB_ID(TryRestoreElementsKind), { receiver, newClass });
#endif
Jump(&exit);
}
Bind(&notFindHClass);
@ -3996,9 +4034,7 @@ GateRef StubBuilder::CheckHClassForRep(GateRef hclass, GateRef value)
return ret;
}
GateRef StubBuilder::FindTransitions(GateRef glue, GateRef receiver,
GateRef hclass, GateRef key,
GateRef metaData, GateRef value)
GateRef StubBuilder::FindTransitions(GateRef glue, GateRef hclass, GateRef key, GateRef metaData, GateRef value)
{
auto env = GetEnvironment();
Label entry(env);
@ -4006,7 +4042,7 @@ GateRef StubBuilder::FindTransitions(GateRef glue, GateRef receiver,
Label exit(env);
GateRef transitionOffset = IntPtr(JSHClass::TRANSTIONS_OFFSET);
GateRef transition = Load(VariableType::JS_POINTER(), hclass, transitionOffset);
DEFVARIABLE(result, VariableType::JS_ANY(), transition);
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
Label notUndefined(env);
BRANCH(Equal(transition, Undefined()), &exit, &notUndefined);
@ -4026,71 +4062,37 @@ GateRef StubBuilder::FindTransitions(GateRef glue, GateRef receiver,
GateRef cachedMetaData = GetPropertyMetaDataFromAttr(cachedAttr);
Label keyMatch(env);
Label isMatch(env);
Label notMatch(env);
Label repMatch(env);
BRANCH(Equal(cachedKey, key), &keyMatch, &notMatch);
BRANCH(Equal(cachedKey, key), &keyMatch, &exit);
Bind(&keyMatch);
{
BRANCH(Int32Equal(metaData, cachedMetaData), &isMatch, &notMatch);
BRANCH(Int32Equal(metaData, cachedMetaData), &isMatch, &exit);
Bind(&isMatch);
{
BRANCH(CheckHClassForRep(transitionHClass, value), &repMatch, &notMatch);
BRANCH(CheckHClassForRep(transitionHClass, value), &repMatch, &exit);
Bind(&repMatch);
GateRef oldHClass = LoadHClass(receiver);
GateRef prototype = GetPrototypeFromHClass(oldHClass);
StorePrototype(glue, transitionHClass, prototype);
#if ECMASCRIPT_ENABLE_IC
NotifyHClassChanged(glue, hclass, transitionHClass);
#endif
StoreHClass(glue, receiver, transitionHClass);
// Because we currently only supports Fast ElementsKind
CallRuntime(glue, RTSTUB_ID(TryRestoreElementsKind), { receiver, transitionHClass });
result = transitionHClass;
Jump(&exit);
}
}
Bind(&notMatch);
{
result = Undefined();
Jump(&exit);
}
}
Bind(&notWeak);
{
// need to find from dictionary
GateRef entryA = FindEntryFromTransitionDictionary(glue, transition, key, metaData);
Label isFound(env);
Label notFound(env);
BRANCH(Int32NotEqual(entryA, Int32(-1)), &isFound, &notFound);
BRANCH(Int32NotEqual(entryA, Int32(-1)), &isFound, &exit);
Bind(&isFound);
auto cachedValue = GetValueFromDictionary<TransitionsDictionary>(transition, entryA);
Label valueUndefined(env);
Label valueNotUndefined(env);
Label repMatch(env);
BRANCH(Int64NotEqual(cachedValue, Undefined()), &valueNotUndefined,
&valueUndefined);
BRANCH(Int64NotEqual(cachedValue, Undefined()), &valueNotUndefined, &exit);
Bind(&valueNotUndefined);
{
GateRef newHClass = LoadObjectFromWeakRef(cachedValue);
BRANCH(CheckHClassForRep(newHClass, value), &repMatch, &valueUndefined);
BRANCH(CheckHClassForRep(newHClass, value), &repMatch, &exit);
Bind(&repMatch);
result = newHClass;
GateRef oldHClass = LoadHClass(receiver);
GateRef prototype = GetPrototypeFromHClass(oldHClass);
StorePrototype(glue, newHClass, prototype);
#if ECMASCRIPT_ENABLE_IC
NotifyHClassChanged(glue, hclass, newHClass);
#endif
StoreHClass(glue, receiver, newHClass);
// Because we currently only supports Fast ElementsKind
CallRuntime(glue, RTSTUB_ID(TryRestoreElementsKind), { receiver, newHClass });
Jump(&exit);
Bind(&notFound);
result = Undefined();
Jump(&exit);
}
Bind(&valueUndefined);
{
result = Undefined();
Jump(&exit);
}
}

View File

@ -625,7 +625,7 @@ ShortcutBoolOr([&]{ return first; }, [&]{ return second; })
GateRef ComputeElementCapacity(GateRef oldLength);
GateRef ComputeNonInlinedFastPropsCapacity(GateRef glue, GateRef oldLength,
GateRef maxNonInlinedFastPropsCapacity);
GateRef FindTransitions(GateRef glue, GateRef receiver, GateRef hClass, GateRef key, GateRef attr, GateRef value);
GateRef FindTransitions(GateRef glue, GateRef hClass, GateRef key, GateRef attr, GateRef value);
GateRef CheckHClassForRep(GateRef hClass, GateRef rep);
void TransitionForRepChange(GateRef glue, GateRef receiver, GateRef key, GateRef attr);
void TransitToElementsKind(GateRef glue, GateRef receiver, GateRef value, GateRef kind);

View File

@ -304,13 +304,19 @@ void JSHClass::AddProperty(const JSThread *thread, const JSHandle<JSObject> &obj
JSHandle<JSHClass> newHClass(thread, newClass);
TryRestoreElementsKind(thread, newHClass, obj);
#if ECMASCRIPT_ENABLE_IC
JSHClass::NotifyHclassChanged(thread, jshclass, JSHandle<JSHClass>(thread, newClass), key.GetTaggedValue());
#endif
// The transition hclass from AOT, which does not have protochangemarker, needs to be reset here
if (newClass->IsTS() && newClass->IsPrototype()) {
JSHClass::RefreshUsers(thread, jshclass, JSHandle<JSHClass>(thread, newClass));
JSHClass::EnableProtoChangeMarker(thread, JSHandle<JSHClass>(thread, newClass));
if (JSHClass::IsNeedNotifyHclassChangedForAotTransition(thread, jshclass, key.GetTaggedValue())) {
JSHClass::EnableProtoChangeMarker(thread, JSHandle<JSHClass>(thread, newClass));
JSHClass::NotifyHclassChanged(thread, jshclass, newHClass, key.GetTaggedValue());
} else {
JSHClass::RefreshUsers(thread, jshclass, newHClass);
}
JSHClass::EnablePHCProtoChangeMarker(thread, newHClass);
} else {
JSHClass::NotifyHclassChanged(thread, jshclass, newHClass, key.GetTaggedValue());
}
#endif
return;
}
JSHandle<JSHClass> newJsHClass = JSHClass::Clone(thread, jshclass);
@ -1655,5 +1661,17 @@ void JSHClass::CreateSDictLayout(JSThread *thread,
hclass->SetNumberOfProps(0);
hclass->SetIsDictionaryMode(true);
}
bool JSHClass::IsNeedNotifyHclassChangedForAotTransition(const JSThread *thread, const JSHandle<JSHClass> &hclass,
JSTaggedValue key)
{
JSMutableHandle<JSObject> protoHandle(thread, hclass->GetPrototype());
while (protoHandle.GetTaggedValue().IsHeapObject()) {
JSHClass *protoHclass = protoHandle->GetJSHClass();
if (JSHClass::FindPropertyEntry(thread, protoHclass, key) != -1) {
return true;
}
protoHandle.Update(protoHclass->GetPrototype());
}
return false;
}
} // namespace panda::ecmascript

View File

@ -517,6 +517,9 @@ public:
static void RefreshUsers(const JSThread *thread, const JSHandle<JSHClass> &oldHclass,
const JSHandle<JSHClass> &newHclass);
static bool IsNeedNotifyHclassChangedForAotTransition(const JSThread *thread, const JSHandle<JSHClass> &hclass,
JSTaggedValue key);
static JSHandle<JSTaggedValue> ParseKeyFromPGOCString(ObjectFactory* factory,
const CString& key,
const PGOHandler& handler);

View File

@ -480,25 +480,41 @@ JSHandle<JSFunction> ClassHelper::DefineClassFromExtractor(JSThread *thread, con
return constructor;
}
JSHandle<JSFunction> ClassHelper::DefineClassWithIHClass(JSThread *thread,
JSHandle<JSFunction> ClassHelper::DefineClassWithIHClass(JSThread *thread, const JSHandle<JSTaggedValue> &base,
JSHandle<ClassInfoExtractor> &extractor,
const JSHandle<JSTaggedValue> &lexenv,
const JSHandle<JSTaggedValue> &prototypeOrHClass,
const JSHandle<JSHClass> &constructorHClass)
const JSHandle<JSTaggedValue> &prototypeOrHClassVal,
const JSHandle<JSTaggedValue> &constructorHClassVal)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<TaggedArray> staticKeys(thread, extractor->GetStaticKeys());
JSHandle<TaggedArray> staticProperties(thread, extractor->GetStaticProperties());
ClassInfoExtractor::CorrectConstructorHClass(thread,
staticProperties, *constructorHClass);
JSHandle<JSHClass> constructorHClass;
// When constructorHClassVal is undefined, it means that AOT has not generated the corresponding hclass (chc),
// then chc will be created through the interpreter.
if (constructorHClassVal->IsUndefined()) {
constructorHClass = ClassInfoExtractor::CreateConstructorHClass(thread, base, staticKeys, staticProperties);
} else {
constructorHClass = JSHandle<JSHClass>(constructorHClassVal);
ClassInfoExtractor::CorrectConstructorHClass(thread, staticProperties, *constructorHClass);
}
JSHandle<TaggedArray> nonStaticKeys(thread, extractor->GetNonStaticKeys());
JSHandle<TaggedArray> nonStaticProperties(thread, extractor->GetNonStaticProperties());
JSHandle<JSObject> prototype;
if (prototypeOrHClass->IsJSHClass()) {
JSHandle<JSHClass> ihclass(prototypeOrHClass);
JSHandle<JSTaggedValue> prototypeOrHClass = prototypeOrHClassVal;
// When prototypeOrHClassVal is undefined, it means that AOT has not generated the corresponding hclass or
// prototype, then prototype will be created through the interpreter.
if (prototypeOrHClassVal->IsUndefined()) {
JSHandle<JSHClass> prototypeHClass = ClassInfoExtractor::CreatePrototypeHClass(thread, nonStaticKeys,
nonStaticProperties);
prototype = factory->NewOldSpaceJSObject(prototypeHClass);
prototypeOrHClass = JSHandle<JSTaggedValue>(prototype);
} else if (prototypeOrHClassVal->IsJSHClass()) {
JSHandle<JSHClass> ihclass(prototypeOrHClassVal);
prototype = JSHandle<JSObject>(thread, ihclass->GetProto());
} else {
prototype = JSHandle<JSObject>(prototypeOrHClass);
prototype = JSHandle<JSObject>(prototypeOrHClassVal);
}
JSHandle<Method> method(thread, Method::Cast(extractor->GetConstructorMethod().GetTaggedObject()));

View File

@ -114,11 +114,11 @@ public:
JSHandle<ClassInfoExtractor> &extractor,
const JSHandle<JSTaggedValue> &lexenv);
static JSHandle<JSFunction> DefineClassWithIHClass(JSThread *thread,
static JSHandle<JSFunction> DefineClassWithIHClass(JSThread *thread, const JSHandle<JSTaggedValue> &base,
JSHandle<ClassInfoExtractor> &extractor,
const JSHandle<JSTaggedValue> &lexenv,
const JSHandle<JSTaggedValue> &ihclass,
const JSHandle<JSHClass> &constructorHClass);
const JSHandle<JSTaggedValue> &prototypeOrHClassVal,
const JSHandle<JSTaggedValue> &constructorHClassVal);
static bool PUBLIC_API MatchFieldType(SharedFieldType fieldType, JSTaggedValue value);
private:

View File

@ -473,6 +473,7 @@ namespace panda::ecmascript {
V(FunctionPrototypeBind) \
V(FunctionPrototypeCall) \
V(SetPrototypeTransition) \
V(UpdateAOTHcAndTryResotreEleKind) \
V(GetSharedModule)
#define RUNTIME_STUB_LIST(V) \

View File

@ -895,7 +895,9 @@ bool RuntimeStubs::ShouldUseAOTHClass(const JSHandle<JSTaggedValue> &ihc,
const JSHandle<JSTaggedValue> &chc,
const JSHandle<ClassLiteral> &classLiteral)
{
return !(ihc->IsUndefined() || chc->IsUndefined() || classLiteral->GetIsAOTUsed());
// In the case of incomplete data collection in PGO, AOT may not create ihc and chc at the same time.
// Therefore, there is no need to check for the existence of both at this point.
return (!ihc->IsUndefined() || !chc->IsUndefined()) && !classLiteral->GetIsAOTUsed();
}
// clone class may need re-set inheritance relationship due to extends may be a variable.
JSTaggedValue RuntimeStubs::RuntimeCreateClassWithBuffer(JSThread *thread,
@ -945,9 +947,7 @@ JSTaggedValue RuntimeStubs::RuntimeCreateClassWithBuffer(JSThread *thread,
if (ShouldUseAOTHClass(ihc, chc, classLiteral)) {
classLiteral->SetIsAOTUsed(true);
JSHandle<JSHClass> chclass(chc);
cls = ClassHelper::DefineClassWithIHClass(thread, extractor,
lexenv, ihc, chclass);
cls = ClassHelper::DefineClassWithIHClass(thread, base, extractor, lexenv, ihc, chc);
} else {
cls = ClassHelper::DefineClassFromExtractor(thread, base, extractor, lexenv);
}
@ -3115,31 +3115,15 @@ JSTaggedValue RuntimeStubs::RuntimeNotifyConcurrentResult(JSThread *thread, JSTa
return JSTaggedValue::Undefined();
}
bool RuntimeStubs::IsNeedNotifyHclassChangedForAotTransition(JSThread *thread, const JSHandle<JSHClass> &hclass,
JSTaggedValue key)
{
JSMutableHandle<JSObject> protoHandle(thread, hclass->GetPrototype());
while (true) {
if (!protoHandle.GetTaggedValue().IsHeapObject()) {
break;
}
JSHClass *protoHclass = protoHandle->GetJSHClass();
if (JSHClass::FindPropertyEntry(thread, protoHclass, key) != -1) {
return true;
}
protoHandle.Update(protoHclass->GetPrototype());
}
return false;
}
JSTaggedValue RuntimeStubs::RuntimeUpdateAOTHClass(JSThread *thread,
const JSHandle<JSHClass> &oldhclass, const JSHandle<JSHClass> &newhclass, JSTaggedValue key)
{
#if ECMASCRIPT_ENABLE_IC
if (IsNeedNotifyHclassChangedForAotTransition(thread, oldhclass, key)) {
if (JSHClass::IsNeedNotifyHclassChangedForAotTransition(thread, oldhclass, key)) {
JSHClass::NotifyHclassChanged(thread, oldhclass, newhclass, key);
} else {
JSHClass::RefreshUsers(thread, oldhclass, newhclass);
}
JSHClass::RefreshUsers(thread, oldhclass, newhclass);
JSHClass::EnablePHCProtoChangeMarker(thread, newhclass);
#endif
return JSTaggedValue::Undefined();

View File

@ -2974,11 +2974,22 @@ DEF_RUNTIME_STUBS(NotifyConcurrentResult)
DEF_RUNTIME_STUBS(UpdateAOTHClass)
{
RUNTIME_STUBS_HEADER(UpdateAOTHClass);
JSTaggedValue oldhc = GetArg(argv, argc, 0); // 0: means the zeroth parameter
JSTaggedValue newhc = GetArg(argv, argc, 1); // 1: means the first parameter
JSHandle<JSHClass> oldhclass = GetHArg<JSHClass>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSHClass> newhclass = GetHArg<JSHClass>(argv, argc, 1); // 1: means the first parameter
JSTaggedValue key = GetArg(argv, argc, 2); // 2: means the second parameter
JSHandle<JSHClass> oldhclass(thread, oldhc);
JSHandle<JSHClass> newhclass(thread, newhc);
return RuntimeUpdateAOTHClass(thread, oldhclass, newhclass, key).GetRawData();
}
DEF_RUNTIME_STUBS(UpdateAOTHcAndTryResotreEleKind)
{
RUNTIME_STUBS_HEADER(UpdateAOTHClass);
JSHandle<JSObject> receiver = GetHArg<JSObject>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSHClass> oldhclass = GetHArg<JSHClass>(argv, argc, 1); // 1: means the first parameter
JSHandle<JSHClass> newhclass = GetHArg<JSHClass>(argv, argc, 2); // 2: means the second parameter
JSTaggedValue key = GetArg(argv, argc, 3); // 3: means the third parameter
JSHClass::TryRestoreElementsKind(thread, newhclass, receiver);
return RuntimeUpdateAOTHClass(thread, oldhclass, newhclass, key).GetRawData();
}

View File

@ -495,8 +495,6 @@ private:
uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj, JSTaggedValue value);
static inline JSTaggedValue RuntimeTestIn(JSThread *thread, JSTaggedValue lexicalEnv,
uint32_t levelIndex, uint32_t slotIndex, JSTaggedValue obj);
static inline bool IsNeedNotifyHclassChangedForAotTransition(JSThread *thread, const JSHandle<JSHClass> &hclass,
JSTaggedValue key);
static inline JSTaggedValue RuntimeUpdateAOTHClass(JSThread *thread, const JSHandle<JSHClass> &oldhclass,
const JSHandle<JSHClass> &newhclass, JSTaggedValue key);
static inline JSTaggedValue RuntimeNotifyDebuggerStatement(JSThread *thread);

View File

@ -202,7 +202,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -188,7 +188,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -130,7 +130,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -136,7 +136,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -171,7 +171,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -136,7 +136,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -136,7 +136,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -191,7 +191,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {

View File

@ -136,7 +136,6 @@ Throwing.prototype.valueOf = function() {
}
return this.value;
}
//aot: [trace] Check Type: ProtoTypeChanged2
let throwingObj = new Throwing();
try {