!5338 opt number ic

Merge pull request !5338 from maojunwei/master
This commit is contained in:
openharmony_ci 2023-12-01 14:40:43 +00:00 committed by Gitee
commit 3832b92e7c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 77 additions and 8 deletions

View File

@ -800,6 +800,7 @@ void Builtins::InitializeNumber(const JSHandle<GlobalEnv> &env, const JSHandle<J
}
env->SetNumberFunction(thread_, numFunction);
env->SetNumberPrototype(thread_, numFuncPrototype);
}
void Builtins::InitializeBigIntWithRealm(const JSHandle<GlobalEnv> &realm) const
{

View File

@ -21,9 +21,10 @@ void ICStubBuilder::NamedICAccessor(Variable* cachedHandler, Label *tryICHandler
{
auto env = GetEnvironment();
Label receiverIsHeapObject(env);
Label receiverNotHeapObject(env);
Label tryIC(env);
Branch(TaggedIsHeapObject(receiver_), &receiverIsHeapObject, slowPath_);
Branch(TaggedIsHeapObject(receiver_), &receiverIsHeapObject, &receiverNotHeapObject);
Bind(&receiverIsHeapObject);
{
Branch(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
@ -36,6 +37,8 @@ void ICStubBuilder::NamedICAccessor(Variable* cachedHandler, Label *tryICHandler
Branch(TaggedIsHeapObject(firstValue), &isHeapObject, &notHeapObject);
Bind(&isHeapObject);
{
GateRef secondValue = GetValueFromTaggedArray(profileTypeInfo_, Int32Add(slotId_, Int32(1)));
cachedHandler->WriteVariable(secondValue);
Label tryPoly(env);
GateRef hclass = LoadHClass(receiver_);
Branch(Equal(LoadObjectFromWeakRef(firstValue), hclass),
@ -53,6 +56,29 @@ void ICStubBuilder::NamedICAccessor(Variable* cachedHandler, Label *tryICHandler
}
}
}
Bind(&receiverNotHeapObject);
{
Label tryNumber(env);
Label profileNotUndefined(env);
Branch(TaggedIsNumber(receiver_), &tryNumber, slowPath_);
Bind(&tryNumber);
{
Branch(TaggedIsUndefined(profileTypeInfo_), slowPath_, &profileNotUndefined);
Bind(&profileNotUndefined);
{
GateRef firstValue = GetValueFromTaggedArray(profileTypeInfo_, slotId_);
GateRef secondValue = GetValueFromTaggedArray(profileTypeInfo_, Int32Add(slotId_, Int32(1)));
cachedHandler->WriteVariable(secondValue);
GateRef glueGlobalEnvOffset = IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(env->Is32Bit()));
GateRef glueGlobalEnv = Load(VariableType::NATIVE_POINTER(), glue_, glueGlobalEnvOffset);
auto numberFunction = GetGlobalEnvValue(VariableType::JS_ANY(),
glueGlobalEnv, GlobalEnv::NUMBER_FUNCTION_INDEX);
GateRef hclass = LoadHClass(numberFunction);
Branch(BoolAnd(TaggedIsHeapObject(firstValue), Equal(LoadObjectFromWeakRef(firstValue), hclass)),
tryICHandler, slowPath_);
}
}
}
}
void ICStubBuilder::ValuedICAccessor(Variable* cachedHandler, Label *tryICHandler, Label* tryElementIC)
@ -122,9 +148,7 @@ void ICStubBuilder::LoadICByName(
Label loadWithHandler(env);
SetLabels(tryFastPath, slowPath, success);
GateRef secondValue = GetValueFromTaggedArray(
profileTypeInfo_, Int32Add(slotId_, Int32(1)));
DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), Undefined());
NamedICAccessor(&cachedHandler, &loadWithHandler);
Bind(&loadWithHandler);
{

View File

@ -1897,8 +1897,23 @@ GateRef StubBuilder::LoadICWithHandler(
Branch(IsField(handlerInfo), &handlerInfoIsField, &handlerInfoNotField);
Bind(&handlerInfoIsField);
{
result = LoadFromField(*holder, handlerInfo);
Jump(&exit);
Label receiverIsNumber(env);
Label receiverNotNumber(env);
Branch(TaggedIsNumber(receiver), &receiverIsNumber, &receiverNotNumber);
Bind(&receiverIsNumber);
{
GateRef glueGlobalEnvOffset = IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(env->Is32Bit()));
GateRef glueGlobalEnv = Load(VariableType::NATIVE_POINTER(), glue, glueGlobalEnvOffset);
auto numberProto = GetGlobalEnvValue(VariableType::JS_ANY(),
glueGlobalEnv, GlobalEnv::NUMBER_PROTOTYPE_INDEX);
result = LoadFromField(numberProto, handlerInfo);
Jump(&exit);
}
Bind(&receiverNotNumber);
{
result = LoadFromField(*holder, handlerInfo);
Jump(&exit);
}
}
Bind(&handlerInfoNotField);
{

View File

@ -29,6 +29,7 @@
V(JSTaggedValue, FunctionFunction, FUNCTION_FUNCTION_INDEX) \
V(JSTaggedValue, FunctionPrototype, FUNCTION_PROTOTYPE_INDEX) \
V(JSTaggedValue, NumberFunction, NUMBER_FUNCTION_INDEX) \
V(JSTaggedValue, NumberPrototype, NUMBER_PROTOTYPE_INDEX) \
V(JSTaggedValue, BigIntFunction, BIGINT_FUNCTION_INDEX) \
V(JSTaggedValue, DateFunction, DATE_FUNCTION_INDEX) \
V(JSTaggedValue, DatePrototype, DATE_PROTOTYPE_INDEX) \

View File

@ -41,6 +41,9 @@ void ICRuntime::UpdateLoadHandler(const ObjectOperator &op, JSHandle<JSTaggedVal
key = JSHandle<JSTaggedValue>();
}
JSHandle<JSTaggedValue> handlerValue;
if (receiver->IsNumber()) {
receiver = thread_->GetEcmaVM()->GetGlobalEnv()->GetNumberFunction();
}
JSHandle<JSHClass> hclass(GetThread(), receiver->GetTaggedObject()->GetClass());
// When a transition occurs without the shadow property, AOT does not trigger the
// notifyprototypechange behavior, so for the case where the property does not
@ -216,7 +219,8 @@ JSTaggedValue LoadICRuntime::LoadValueMiss(JSHandle<JSTaggedValue> receiver, JSH
JSTaggedValue LoadICRuntime::LoadMiss(JSHandle<JSTaggedValue> receiver, JSHandle<JSTaggedValue> key)
{
if ((!receiver->IsJSObject() || receiver->HasOrdinaryGet()) && !receiver->IsString()) {
if ((!receiver->IsJSObject() || receiver->HasOrdinaryGet()) &&
!receiver->IsString() && !receiver->IsNumber()) {
icAccessor_.SetAsMega();
JSHandle<JSTaggedValue> propKey = JSTaggedValue::ToPropertyKey(thread_, key);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread_);

View File

@ -95,6 +95,11 @@ ARK_INLINE JSTaggedValue ICRuntimeStub::TryLoadICByName(JSThread *thread, JSTagg
if (!cachedHandler.IsHole()) {
return LoadICWithHandler(thread, receiver, receiver, cachedHandler);
}
} else if (receiver.IsNumber()) {
auto hclass = thread->GetEcmaVM()->GetGlobalEnv()->GetNumberFunction()->GetTaggedObject()->GetClass();
if (firstValue.GetWeakReferentUnChecked() == hclass) {
return LoadICWithHandler(thread, receiver, receiver, secondValue);
}
}
return JSTaggedValue::Hole();
}
@ -413,6 +418,12 @@ ARK_INLINE JSTaggedValue ICRuntimeStub::LoadICWithHandler(JSThread *thread, JSTa
if (LIKELY(handler.IsInt())) {
auto handlerInfo = static_cast<uint32_t>(handler.GetInt());
if (LIKELY(HandlerBase::IsField(handlerInfo))) {
if (!receiver.IsNumber()) {
return LoadFromField(JSObject::Cast(holder.GetTaggedObject()), handlerInfo);
}
ASSERT(receiver.IsNumber());
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
holder = env->GetNumberFunction().GetObject<JSFunction>()->GetFunctionPrototype();
return LoadFromField(JSObject::Cast(holder.GetTaggedObject()), handlerInfo);
}
if (LIKELY(HandlerBase::IsString(handlerInfo))) {

View File

@ -12,3 +12,4 @@
# limitations under the License.
false
number ic load success

View File

@ -45,4 +45,16 @@ try {
} catch (e) {
flag1 = true;
}
print(flag1);
print(flag1);
// for number inline cache
const numObj1 = 10928;
const numObj2 = 123.456;
const numObj3 = new Number(42);
for (let i = 0; i < 100; i++) {
let res1 = numObj1.toString();
let res2 = numObj2.toPrecision(4);
let res3 = numObj3.valueOf();
}
print("number ic load success")