!5322 Instanceof Stub FastPath && AOT Instanceof bugfix

Merge pull request !5322 from yaoyuan/instanceof
This commit is contained in:
openharmony_ci 2023-11-25 01:57:35 +00:00 committed by Gitee
commit 2aec2809c2
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 118 additions and 11 deletions

View File

@ -4454,6 +4454,35 @@ void StubBuilder::FastSetPropertyByIndex(GateRef glue, GateRef obj, GateRef inde
env->SubCfgExit();
}
GateRef StubBuilder::GetCtorPrototype(GateRef ctor)
{
auto env = GetEnvironment();
Label entry(env);
env->SubCfgEntry(&entry);
DEFVARIABLE(constructorPrototype, VariableType::JS_ANY(), Undefined());
Label exit(env);
Label isHClass(env);
Label isPrototype(env);
GateRef ctorProtoOrHC = Load(VariableType::JS_POINTER(), ctor, IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
Branch(IsJSHClass(ctorProtoOrHC), &isHClass, &isPrototype);
Bind(&isHClass);
{
constructorPrototype = Load(VariableType::JS_POINTER(), ctorProtoOrHC, IntPtr(JSHClass::PROTOTYPE_OFFSET));
Jump(&exit);
}
Bind(&isPrototype);
{
constructorPrototype = ctorProtoOrHC;
Jump(&exit);
}
Bind(&exit);
auto ret = *constructorPrototype;
env->SubCfgExit();
return ret;
}
GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef obj)
{
auto env = GetEnvironment();
@ -4503,10 +4532,32 @@ GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef o
Bind(&objIsEcmaObject);
{
// 4. Let P be Get(C, "prototype").
auto prototypeString = GetGlobalConstantValue(
VariableType::JS_POINTER(), glue, ConstantIndex::PROTOTYPE_STRING_INDEX);
Label getCtorProtoSlowPath(env);
Label ctorIsJSFunction(env);
Label gotCtorPrototype(env);
DEFVARIABLE(constructorPrototype, VariableType::JS_ANY(), Undefined());
Branch(IsJSFunction(target), &ctorIsJSFunction, &getCtorProtoSlowPath);
Bind(&ctorIsJSFunction);
{
Label getCtorProtoFastPath(env);
GateRef ctorProtoOrHC = Load(VariableType::JS_POINTER(), target,
IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
GateRef constructorPrototype = FastGetPropertyByName(glue, target, prototypeString, ProfileOperation());
Branch(TaggedIsHole(ctorProtoOrHC), &getCtorProtoSlowPath, &getCtorProtoFastPath);
Bind(&getCtorProtoFastPath);
{
constructorPrototype = GetCtorPrototype(target);
Jump(&gotCtorPrototype);
}
}
Bind(&getCtorProtoSlowPath);
{
auto prototypeString = GetGlobalConstantValue(VariableType::JS_POINTER(), glue,
ConstantIndex::PROTOTYPE_STRING_INDEX);
constructorPrototype = FastGetPropertyByName(glue, target, prototypeString, ProfileOperation());
Jump(&gotCtorPrototype);
}
Bind(&gotCtorPrototype);
// 5. ReturnIfAbrupt(P).
// no throw exception, so needn't return
@ -4524,10 +4575,10 @@ GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef o
Label constructorPrototypeIsHeapObject(env);
Label constructorPrototypeIsEcmaObject(env);
Label constructorPrototypeNotEcmaObject(env);
Branch(TaggedIsHeapObject(constructorPrototype), &constructorPrototypeIsHeapObject,
Branch(TaggedIsHeapObject(*constructorPrototype), &constructorPrototypeIsHeapObject,
&constructorPrototypeNotEcmaObject);
Bind(&constructorPrototypeIsHeapObject);
Branch(TaggedObjectIsEcmaObject(constructorPrototype), &constructorPrototypeIsEcmaObject,
Branch(TaggedObjectIsEcmaObject(*constructorPrototype), &constructorPrototypeIsEcmaObject,
&constructorPrototypeNotEcmaObject);
Bind(&constructorPrototypeNotEcmaObject);
{
@ -4554,7 +4605,7 @@ GateRef StubBuilder::OrdinaryHasInstance(GateRef glue, GateRef target, GateRef o
Branch(TaggedIsNull(*object), &afterLoop, &loopHead);
LoopBegin(&loopHead);
{
GateRef isEqual = SameValue(glue, *object, constructorPrototype);
GateRef isEqual = SameValue(glue, *object, *constructorPrototype);
Branch(isEqual, &strictEqual1, &notStrictEqual1);
Bind(&strictEqual1);

View File

@ -388,6 +388,7 @@ public:
GateRef HclassIsTransitionHandler(GateRef hClass);
GateRef HclassIsPropertyBox(GateRef hClass);
GateRef PropAttrGetOffset(GateRef attr);
GateRef GetCtorPrototype(GateRef ctor);
GateRef InstanceOf(GateRef glue, GateRef object, GateRef target, GateRef profileTypeInfo, GateRef slotId,
ProfileOperation callback);
GateRef OrdinaryHasInstance(GateRef glue, GateRef target, GateRef obj);

View File

@ -2182,11 +2182,44 @@ void TypeHCRLowering::LowerOrdinaryHasInstance(GateRef gate, GateRef glue)
builder_.Bind(&objIsEcmaObject);
{
// 4. Let P be Get(C, "prototype").
// target must be a builtin function
GateRef ctorHClass = builder_.LoadConstOffset(VariableType::JS_POINTER(), target,
JSFunction::PROTO_OR_DYNCLASS_OFFSET);
GateRef constructorPrototype = builder_.LoadPrototype(ctorHClass);
Label getCtorProtoSlowPath(&builder_);
Label ctorIsJSFunction(&builder_);
Label gotCtorPrototype(&builder_);
DEFVALUE(constructorPrototype, (&builder_), VariableType::JS_ANY(), builder_.Undefined());
builder_.Branch(builder_.IsJSFunction(target), &ctorIsJSFunction, &getCtorProtoSlowPath);
builder_.Bind(&ctorIsJSFunction);
{
Label getCtorProtoFastPath(&builder_);
GateRef ctorProtoOrHC = builder_.LoadConstOffset(VariableType::JS_POINTER(), target,
JSFunction::PROTO_OR_DYNCLASS_OFFSET);
builder_.Branch(builder_.TaggedIsHole(ctorProtoOrHC), &getCtorProtoSlowPath, &getCtorProtoFastPath);
builder_.Bind(&getCtorProtoFastPath);
{
Label isHClass(&builder_);
Label isPrototype(&builder_);
builder_.Branch(builder_.IsJSHClass(ctorProtoOrHC), &isHClass, &isPrototype);
builder_.Bind(&isHClass);
{
constructorPrototype = builder_.LoadConstOffset(VariableType::JS_POINTER(), ctorProtoOrHC,
JSHClass::PROTOTYPE_OFFSET);
builder_.Jump(&gotCtorPrototype);
}
builder_.Bind(&isPrototype);
{
constructorPrototype = ctorProtoOrHC;
builder_.Jump(&gotCtorPrototype);
}
}
}
builder_.Bind(&getCtorProtoSlowPath);
{
auto prototypeString = builder_.GetGlobalConstantValue(ConstantIndex::PROTOTYPE_STRING_INDEX);
constructorPrototype = builder_.CallRuntime(glue, RTSTUB_ID(GetPropertyByName), Gate::InvalidGateRef,
{ target, prototypeString }, gate);
builder_.Jump(&gotCtorPrototype);
}
builder_.Bind(&gotCtorPrototype);
// 7. Repeat
// a.Let O be O.[[GetPrototypeOf]]().
// b.ReturnIfAbrupt(O).
@ -2203,7 +2236,7 @@ void TypeHCRLowering::LowerOrdinaryHasInstance(GateRef gate, GateRef glue)
builder_.Branch(builder_.TaggedIsNull(*object), &afterLoop, &loopHead);
builder_.LoopBegin(&loopHead);
{
GateRef isEqual = builder_.Equal(*object, constructorPrototype);
GateRef isEqual = builder_.Equal(*object, *constructorPrototype);
builder_.Branch(isEqual, &strictEqual1, &notStrictEqual1);
builder_.Bind(&strictEqual1);

View File

@ -2251,6 +2251,14 @@ DEF_RUNTIME_STUBS(FastCopyElementToArray)
return JSTaggedValue(JSTypedArray::FastCopyElementToArray(thread, typedArray, array)).GetRawData();
}
DEF_RUNTIME_STUBS(GetPropertyByName)
{
RUNTIME_STUBS_HEADER(GetPropertyByName);
JSHandle<JSTaggedValue> target = GetHArg<JSTaggedValue>(argv, argc, 0); // 0: means the zeroth parameter
JSHandle<JSTaggedValue> key = GetHArg<JSTaggedValue>(argv, argc, 1); // 1: means the first parameter
return JSTaggedValue::GetProperty(thread, target, key).GetValue()->GetRawData();
}
DEF_RUNTIME_STUBS(DebugAOTPrint)
{
RUNTIME_STUBS_HEADER(DebugAOTPrint);

View File

@ -316,6 +316,7 @@ using FastCallAotEntryType = JSTaggedValue (*)(uintptr_t glue, uint32_t argc, co
V(GetTypeArrayPropertyByIndex) \
V(SetTypeArrayPropertyByIndex) \
V(FastCopyElementToArray) \
V(GetPropertyByName) \
V(JSObjectGetMethod) \
V(DebugAOTPrint) \
V(ProfileOptimizedCode) \

View File

@ -22,6 +22,9 @@ true
false
true
true
false
true
true
true
true
true

View File

@ -67,6 +67,16 @@ function test5() {
}
test5();
function foo() {};
function bar() {};
const proxy = new Proxy(foo, {});
let f = new foo();
print(f instanceof foo); // true
print(f instanceof proxy); // true
print(f instanceof bar); // false
print(ArkTools.isAOTCompiled(test1));
print(ArkTools.isAOTCompiled(test2));
print(ArkTools.isAOTCompiled(test3));