mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
efdee45a09
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAMPAW Description:1:短路求值整改,修改BoolAnd/BoolOr为LogicAnd/LogicOr;2:为降低性能影响,部分确定无问题的场景,依然使用BoolAnd类接口,并修改其名称为BitAnd Signed-off-by: zhangyinlu <zhangyinlu@huawei.com> Change-Id: Ia7dc6f73322dc7588213c6a4c1a14f87104bf378
314 lines
12 KiB
C++
314 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "ecmascript/compiler/ic_stub_builder.h"
|
|
|
|
#include "ecmascript/compiler/builtins/builtins_typedarray_stub_builder.h"
|
|
#include "ecmascript/compiler/stub_builder-inl.h"
|
|
|
|
namespace panda::ecmascript::kungfu {
|
|
void ICStubBuilder::NamedICAccessor(Variable* cachedHandler, Label *tryICHandler)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label receiverIsHeapObject(env);
|
|
Label receiverNotHeapObject(env);
|
|
Label tryIC(env);
|
|
|
|
BRANCH(TaggedIsHeapObject(receiver_), &receiverIsHeapObject, &receiverNotHeapObject);
|
|
Bind(&receiverIsHeapObject);
|
|
{
|
|
BRANCH(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
|
|
Bind(&tryIC);
|
|
{
|
|
Label isHeapObject(env);
|
|
Label notHeapObject(env);
|
|
GateRef firstValue = GetValueFromTaggedArray(
|
|
profileTypeInfo_, slotId_);
|
|
BRANCH(TaggedIsHeapObject(firstValue), &isHeapObject, ¬HeapObject);
|
|
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),
|
|
tryICHandler,
|
|
&tryPoly);
|
|
Bind(&tryPoly);
|
|
{
|
|
cachedHandler->WriteVariable(CheckPolyHClass(firstValue, hclass));
|
|
BRANCH(TaggedIsHole(cachedHandler->ReadVariable()), slowPath_, tryICHandler);
|
|
}
|
|
}
|
|
Bind(¬HeapObject);
|
|
{
|
|
BRANCH(TaggedIsUndefined(firstValue), slowPath_, tryFastPath_);
|
|
}
|
|
}
|
|
}
|
|
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);
|
|
Label isHeapObject(env);
|
|
BRANCH(TaggedIsHeapObject(firstValue), &isHeapObject, slowPath_)
|
|
Bind(&isHeapObject);
|
|
{
|
|
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 ctorProtoOrHC =
|
|
Load(VariableType::JS_POINTER(), numberFunction,
|
|
IntPtr(JSFunction::PROTO_OR_DYNCLASS_OFFSET));
|
|
BRANCH(Equal(LoadObjectFromWeakRef(firstValue), ctorProtoOrHC), tryICHandler, slowPath_);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ICStubBuilder::ValuedICAccessor(Variable* cachedHandler, Label *tryICHandler, Label* tryElementIC)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label receiverIsHeapObject(env);
|
|
|
|
BRANCH(TaggedIsHeapObject(receiver_), &receiverIsHeapObject, slowPath_);
|
|
Bind(&receiverIsHeapObject);
|
|
{
|
|
Label tryIC(env);
|
|
BRANCH(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
|
|
Bind(&tryIC);
|
|
{
|
|
Label isHeapObject(env);
|
|
Label notHeapObject(env);
|
|
GateRef firstValue = GetValueFromTaggedArray(
|
|
profileTypeInfo_, slotId_);
|
|
BRANCH(TaggedIsHeapObject(firstValue), &isHeapObject, ¬HeapObject);
|
|
Bind(&isHeapObject);
|
|
{
|
|
Label tryPoly(env);
|
|
Label tryWithElementPoly(env);
|
|
GateRef hclass = LoadHClass(receiver_);
|
|
BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass),
|
|
tryElementIC,
|
|
&tryPoly);
|
|
Bind(&tryPoly);
|
|
{
|
|
Label firstIsKey(env);
|
|
BRANCH(Int64Equal(firstValue, propKey_), &firstIsKey, &tryWithElementPoly);
|
|
Bind(&firstIsKey);
|
|
{
|
|
GateRef handler = CheckPolyHClass(cachedHandler->ReadVariable(), hclass);
|
|
cachedHandler->WriteVariable(handler);
|
|
BRANCH(TaggedIsHole(cachedHandler->ReadVariable()), slowPath_, tryICHandler);
|
|
}
|
|
Bind(&tryWithElementPoly);
|
|
{
|
|
Label checkSecond(env);
|
|
Label checkPoly(env);
|
|
BRANCH(TaggedIsWeak(firstValue), slowPath_, &checkSecond);
|
|
Bind(&checkSecond);
|
|
{
|
|
BRANCH(TaggedIsHole(cachedHandler->ReadVariable()), &checkPoly, slowPath_);
|
|
}
|
|
Bind(&checkPoly);
|
|
{
|
|
cachedHandler->WriteVariable(CheckPolyHClass(firstValue, hclass));
|
|
BRANCH(TaggedIsHole(cachedHandler->ReadVariable()), slowPath_, tryElementIC);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Bind(¬HeapObject);
|
|
{
|
|
BRANCH(TaggedIsUndefined(firstValue), slowPath_, tryFastPath_);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ICStubBuilder::LoadICByName(
|
|
Variable *result, Label *tryFastPath, Label *slowPath, Label *success, ProfileOperation callback)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label loadWithHandler(env);
|
|
|
|
SetLabels(tryFastPath, slowPath, success);
|
|
DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), Undefined());
|
|
NamedICAccessor(&cachedHandler, &loadWithHandler);
|
|
Bind(&loadWithHandler);
|
|
{
|
|
GateRef ret = LoadICWithHandler(glue_, receiver_, receiver_, *cachedHandler, callback);
|
|
result->WriteVariable(ret);
|
|
BRANCH(TaggedIsHole(ret), slowPath_, success_);
|
|
}
|
|
}
|
|
|
|
void ICStubBuilder::StoreICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label storeWithHandler(env);
|
|
|
|
SetLabels(tryFastPath, slowPath, success);
|
|
GateRef secondValue = GetValueFromTaggedArray(
|
|
profileTypeInfo_, Int32Add(slotId_, Int32(1)));
|
|
DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
|
|
NamedICAccessor(&cachedHandler, &storeWithHandler);
|
|
Bind(&storeWithHandler);
|
|
{
|
|
GateRef ret = StoreICWithHandler(glue_, receiver_, receiver_, value_, *cachedHandler, callback_);
|
|
result->WriteVariable(ret);
|
|
BRANCH(TaggedIsHole(ret), slowPath_, success_);
|
|
}
|
|
}
|
|
|
|
void ICStubBuilder::LoadICByValue(
|
|
Variable *result, Label *tryFastPath, Label *slowPath, Label *success, ProfileOperation callback)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label loadWithHandler(env);
|
|
Label loadElement(env);
|
|
Label handlerInfoIsElement(env);
|
|
Label handlerInfoNotElement(env);
|
|
Label handlerInfoIsStringElement(env);
|
|
Label handlerInfoNotStringElement(env);
|
|
Label handlerInfoIsTypedArrayElement(env);
|
|
Label exit(env);
|
|
|
|
SetLabels(tryFastPath, slowPath, success);
|
|
GateRef secondValue = GetValueFromTaggedArray(
|
|
profileTypeInfo_, Int32Add(slotId_, Int32(1)));
|
|
DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
|
|
DEFVARIABLE(ret, VariableType::JS_ANY(), secondValue);
|
|
|
|
ValuedICAccessor(&cachedHandler, &loadWithHandler, &loadElement);
|
|
Bind(&loadElement);
|
|
{
|
|
GateRef handlerInfo = GetInt64OfTInt(*cachedHandler);
|
|
BRANCH(IsElement(handlerInfo), &handlerInfoIsElement, &handlerInfoNotElement);
|
|
Bind(&handlerInfoIsElement);
|
|
{
|
|
ret = LoadElement(glue_, receiver_, propKey_);
|
|
Jump(&exit);
|
|
}
|
|
Bind(&handlerInfoNotElement);
|
|
{
|
|
BRANCH(IsStringElement(handlerInfo), &handlerInfoIsStringElement, &handlerInfoNotStringElement);
|
|
Bind(&handlerInfoIsStringElement);
|
|
{
|
|
ret = LoadStringElement(glue_, receiver_, propKey_);
|
|
Jump(&exit);
|
|
}
|
|
Bind(&handlerInfoNotStringElement);
|
|
{
|
|
BRANCH(IsTypedArrayElement(handlerInfo), &handlerInfoIsTypedArrayElement, &exit);
|
|
Bind(&handlerInfoIsTypedArrayElement);
|
|
{
|
|
GateRef hclass = LoadHClass(receiver_);
|
|
GateRef jsType = GetObjectType(hclass);
|
|
BuiltinsTypedArrayStubBuilder typedArrayBuilder(reinterpret_cast<StubBuilder*>(this));
|
|
ret = typedArrayBuilder.LoadTypedArrayElement(glue_, receiver_, propKey_, jsType);
|
|
Jump(&exit);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Bind(&loadWithHandler);
|
|
{
|
|
ret = LoadICWithHandler(glue_, receiver_, receiver_, *cachedHandler, callback);
|
|
Jump(&exit);
|
|
}
|
|
Bind(&exit);
|
|
result->WriteVariable(*ret);
|
|
BRANCH(TaggedIsHole(*ret), slowPath_, success_);
|
|
}
|
|
|
|
void ICStubBuilder::StoreICByValue(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label storeWithHandler(env);
|
|
Label storeElement(env);
|
|
SetLabels(tryFastPath, slowPath, success);
|
|
GateRef secondValue = GetValueFromTaggedArray(
|
|
profileTypeInfo_, Int32Add(slotId_, Int32(1)));
|
|
DEFVARIABLE(cachedHandler, VariableType::JS_ANY(), secondValue);
|
|
ValuedICAccessor(&cachedHandler, &storeWithHandler, &storeElement);
|
|
Bind(&storeElement);
|
|
{
|
|
GateRef ret = ICStoreElement(glue_, receiver_, propKey_, value_, *cachedHandler,
|
|
true, profileTypeInfo_, Int32Add(slotId_, Int32(1)));
|
|
result->WriteVariable(ret);
|
|
BRANCH(TaggedIsHole(ret), slowPath_, success_);
|
|
}
|
|
Bind(&storeWithHandler);
|
|
{
|
|
GateRef ret = StoreICWithHandler(glue_, receiver_, receiver_, value_, *cachedHandler, callback_);
|
|
result->WriteVariable(ret);
|
|
BRANCH(TaggedIsHole(ret), slowPath_, success_);
|
|
}
|
|
}
|
|
|
|
void ICStubBuilder::TryLoadGlobalICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label tryIC(env);
|
|
|
|
SetLabels(tryFastPath, slowPath, success);
|
|
BRANCH(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
|
|
Bind(&tryIC);
|
|
{
|
|
GateRef handler = GetValueFromTaggedArray(profileTypeInfo_, slotId_);
|
|
Label isHeapObject(env);
|
|
BRANCH(TaggedIsHeapObject(handler), &isHeapObject, slowPath_);
|
|
Bind(&isHeapObject);
|
|
{
|
|
GateRef ret = LoadGlobal(handler);
|
|
result->WriteVariable(ret);
|
|
BRANCH(TaggedIsHole(ret), slowPath_, success_);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ICStubBuilder::TryStoreGlobalICByName(Variable* result, Label* tryFastPath, Label *slowPath, Label *success)
|
|
{
|
|
auto env = GetEnvironment();
|
|
Label tryIC(env);
|
|
|
|
SetLabels(tryFastPath, slowPath, success);
|
|
BRANCH(TaggedIsUndefined(profileTypeInfo_), tryFastPath_, &tryIC);
|
|
Bind(&tryIC);
|
|
{
|
|
GateRef handler = GetValueFromTaggedArray(profileTypeInfo_, slotId_);
|
|
Label isHeapObject(env);
|
|
BRANCH(TaggedIsHeapObject(handler), &isHeapObject, slowPath_);
|
|
Bind(&isHeapObject);
|
|
{
|
|
GateRef ret = StoreGlobal(glue_, value_, handler);
|
|
result->WriteVariable(ret);
|
|
BRANCH(TaggedIsHole(ret), slowPath_, success_);
|
|
}
|
|
}
|
|
}
|
|
} // namespace panda::ecmascript::kungfu
|