mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
Add fastpath for elementkind
issue:#I9O499 Signed-off-by: dov1s <maojunwei1@huawei.com> Change-Id: Icad8c5624d50fa492c56fed8eec568d63a5d682c
This commit is contained in:
parent
873b85e648
commit
555f00b5e3
@ -1812,6 +1812,49 @@ void BuiltinsArrayStubBuilder::Reverse(GateRef glue, GateRef thisValue, [[maybe_
|
||||
DEFVARIABLE(i, VariableType::INT64(), Int64(0));
|
||||
DEFVARIABLE(j, VariableType::INT64(), Int64Sub(thisArrLen, Int64(1)));
|
||||
|
||||
GateRef hclass = LoadHClass(thisValue);
|
||||
GateRef kind = GetElementsKindFromHClass(hclass);
|
||||
Label isInt(env);
|
||||
Label isNotInt(env);
|
||||
Label notFastKind(env);
|
||||
GateRef elementsKindIntLB = Int32GreaterThanOrEqual(kind,
|
||||
Int32(static_cast<int32_t>(ElementsKind::INT)));
|
||||
GateRef elementsKindIntUB = Int32LessThanOrEqual(kind,
|
||||
Int32(static_cast<int32_t>(ElementsKind::HOLE_INT)));
|
||||
GateRef checkIntKind = BoolAnd(elementsKindIntLB, elementsKindIntUB);
|
||||
BRANCH(checkIntKind, &isInt, &isNotInt);
|
||||
Bind(&isInt);
|
||||
{
|
||||
FastReverse(glue, thisValue, thisArrLen, ElementsKind::INT, result, exit);
|
||||
}
|
||||
Bind(&isNotInt);
|
||||
{
|
||||
Label isNumber(env);
|
||||
Label isNotNumber(env);
|
||||
GateRef elementsKindNumberLB = Int32GreaterThanOrEqual(kind,
|
||||
Int32(static_cast<int32_t>(ElementsKind::NUMBER)));
|
||||
GateRef elementsKindNumberUB = Int32LessThanOrEqual(kind,
|
||||
Int32(static_cast<int32_t>(ElementsKind::HOLE_NUMBER)));
|
||||
GateRef checkNumberKind = BoolAnd(elementsKindNumberLB, elementsKindNumberUB);
|
||||
BRANCH(checkNumberKind, &isNumber, &isNotNumber);
|
||||
Bind(&isNumber);
|
||||
{
|
||||
FastReverse(glue, thisValue, thisArrLen, ElementsKind::NUMBER, result, exit);
|
||||
}
|
||||
Bind(&isNotNumber);
|
||||
{
|
||||
FastReverse(glue, thisValue, thisArrLen, ElementsKind::TAGGED, result, exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BuiltinsArrayStubBuilder::FastReverse(GateRef glue, GateRef thisValue, GateRef len,
|
||||
ElementsKind kind, Variable *result, Label *exit)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
DEFVARIABLE(i, VariableType::INT64(), Int64(0));
|
||||
DEFVARIABLE(j, VariableType::INT64(), Int64Sub(len, Int64(1)));
|
||||
GateRef elements = GetElementsArray(thisValue);
|
||||
Label loopHead(env);
|
||||
Label loopEnd(env);
|
||||
Label next(env);
|
||||
@ -1824,12 +1867,10 @@ void BuiltinsArrayStubBuilder::Reverse(GateRef glue, GateRef thisValue, [[maybe_
|
||||
BRANCH(Int64LessThan(*i, *j), &next, &loopExit);
|
||||
Bind(&next);
|
||||
{
|
||||
GateRef lower = GetTaggedValueWithElementsKind(thisValue, *i);
|
||||
GateRef upper = GetTaggedValueWithElementsKind(thisValue, *j);
|
||||
SetValueWithElementsKind(glue, thisValue, upper, *i, Boolean(false),
|
||||
Int32(static_cast<uint32_t>(ElementsKind::NONE)));
|
||||
SetValueWithElementsKind(glue, thisValue, lower, *j, Boolean(false),
|
||||
Int32(static_cast<uint32_t>(ElementsKind::NONE)));
|
||||
GateRef lower = FastGetValueWithElementsKind(elements, *i, kind);
|
||||
GateRef upper = FastGetValueWithElementsKind(elements, *j, kind);
|
||||
FastSetValueWithElementsKind(glue, elements, upper, *i, kind);
|
||||
FastSetValueWithElementsKind(glue, elements, lower, *j, kind);
|
||||
Jump(&loopEnd);
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,9 @@ BUILTINS_WITH_ARRAY_STUB_BUILDER(DECLARE_BUILTINS_ARRAY_STUB_BUILDER)
|
||||
|
||||
GateRef DoSort(GateRef glue, GateRef receiver, GateRef receiverState,
|
||||
Variable *result, Label *exit, Label *slowPath);
|
||||
|
||||
void FastReverse(GateRef glue, GateRef thisValue, GateRef len,
|
||||
ElementsKind kind, Variable *result, Label *exit);
|
||||
private:
|
||||
static constexpr uint32_t MAX_LENGTH_ZERO = 0;
|
||||
static constexpr uint32_t MAX_LENGTH_ONE = 1;
|
||||
|
@ -9834,6 +9834,55 @@ GateRef StubBuilder::SetValueWithElementsKind(GateRef glue, GateRef receiver, Ga
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef StubBuilder::FastGetValueWithElementsKind(GateRef elements, GateRef index, ElementsKind kind)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entryPass(env);
|
||||
env->SubCfgEntry(&entryPass);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Hole());
|
||||
Label exit(env);
|
||||
if (kind == ElementsKind::INT || kind == ElementsKind::NUMBER) {
|
||||
result = GetValueFromTaggedArray(elements, index);
|
||||
Jump(&exit);
|
||||
} else {
|
||||
result = GetValueFromTaggedArray(elements, index);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void StubBuilder::FastSetValueWithElementsKind(GateRef glue, GateRef elements, GateRef rawValue,
|
||||
GateRef index, ElementsKind kind)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label entryPass(env);
|
||||
env->SubCfgEntry(&entryPass);
|
||||
Label exit(env);
|
||||
if (kind == ElementsKind::INT || kind == ElementsKind::NUMBER) {
|
||||
SetValueToTaggedArray(VariableType::INT64(), glue, elements, index, rawValue);
|
||||
Jump(&exit);
|
||||
} else {
|
||||
Label storeToNormalArray(env);
|
||||
Label storeToMutantArray(env);
|
||||
BRANCH(TaggedIsHeapObject(rawValue), &storeToNormalArray, &storeToMutantArray);
|
||||
Bind(&storeToNormalArray);
|
||||
{
|
||||
SetValueToTaggedArray(VariableType::JS_ANY(), glue, elements, index, rawValue);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&storeToMutantArray);
|
||||
{
|
||||
SetValueToTaggedArray(VariableType::INT64(), glue, elements, index, rawValue);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
env->SubCfgExit();
|
||||
}
|
||||
|
||||
GateRef StubBuilder::CopyJSArrayToTaggedArrayArgs(GateRef glue, GateRef srcObj)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
@ -516,6 +516,9 @@ public:
|
||||
GateRef GetFieldTypeFromHandler(GateRef attr);
|
||||
GateRef ClearSharedStoreKind(GateRef handlerInfo);
|
||||
GateRef GetTaggedValueWithElementsKind(GateRef receiver, GateRef index);
|
||||
GateRef FastGetValueWithElementsKind(GateRef elements, GateRef index, ElementsKind kind);
|
||||
void FastSetValueWithElementsKind(GateRef glue, GateRef elements, GateRef rawValue,
|
||||
GateRef index, ElementsKind kind);
|
||||
GateRef SetValueWithElementsKind(GateRef glue, GateRef receiver, GateRef rawValue, GateRef index,
|
||||
GateRef needTransition, GateRef extraKind);
|
||||
GateRef CopyJSArrayToTaggedArrayArgs(GateRef glue, GateRef srcObj);
|
||||
|
@ -55,5 +55,41 @@ inline void ElementAccessor::Set(const JSThread *thread, JSHandle<JSObject> rece
|
||||
Barriers::SetPrimitive<JSTaggedType>(elements->GetData(), offset, convertedValue);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ElementAccessor::FastSet(const JSThread *thread, JSHandle<TaggedArray> elements, uint32_t idx,
|
||||
const JSHandle<T> &value, ElementsKind kind)
|
||||
{
|
||||
ASSERT(idx < elements->GetLength());
|
||||
size_t offset = JSTaggedValue::TaggedTypeSize() * idx;
|
||||
JSTaggedValue rawValue = value.GetTaggedValue();
|
||||
switch (kind) {
|
||||
case ElementsKind::INT:
|
||||
Barriers::SetPrimitive<JSTaggedType>(elements->GetData(), offset,
|
||||
static_cast<JSTaggedType>(rawValue.GetInt()));
|
||||
break;
|
||||
case ElementsKind::NUMBER:
|
||||
if (rawValue.IsInt()) {
|
||||
int intValue = rawValue.GetInt();
|
||||
Barriers::SetPrimitive<JSTaggedType>(elements->GetData(), offset,
|
||||
base::bit_cast<JSTaggedType>(static_cast<double>(intValue)));
|
||||
} else {
|
||||
Barriers::SetPrimitive<JSTaggedType>(elements->GetData(), offset,
|
||||
base::bit_cast<JSTaggedType>(rawValue.GetDouble()));
|
||||
}
|
||||
break;
|
||||
case ElementsKind::TAGGED:
|
||||
if (value.GetTaggedValue().IsHeapObject()) {
|
||||
Barriers::SetObject<true>(thread, elements->GetData(), offset, rawValue.GetRawData());
|
||||
} else { // NOLINTNEXTLINE(readability-misleading-indentation)
|
||||
Barriers::SetPrimitive<JSTaggedType>(elements->GetData(), offset, rawValue.GetRawData());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_ECMA(FATAL) << "Trying to Convert TaggedValue With Unknown ElementsKind";
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_ELEMENT_ACCESSOR_INL_H
|
||||
|
@ -56,6 +56,15 @@ JSTaggedValue ElementAccessor::Get(JSObject *receiver, uint32_t idx)
|
||||
return GetTaggedValueWithElementsKind(rawValue, kind);
|
||||
}
|
||||
|
||||
JSTaggedValue ElementAccessor::FastGet(JSHandle<TaggedArray> elements, uint32_t idx, ElementsKind kind)
|
||||
{
|
||||
ASSERT(idx < elements->GetLength());
|
||||
size_t offset = JSTaggedValue::TaggedTypeSize() * idx;
|
||||
// NOLINTNEXTLINE(readability-braces-around-statements, bugprone-suspicious-semicolon)
|
||||
JSTaggedType rawValue = Barriers::GetValue<JSTaggedType>(elements->GetData(), offset);
|
||||
return GetTaggedValueWithElementsKind(rawValue, kind);
|
||||
}
|
||||
|
||||
bool ElementAccessor::IsDictionaryMode(JSHandle<JSObject> receiver)
|
||||
{
|
||||
TaggedArray *elements = TaggedArray::Cast(receiver->GetElements());
|
||||
|
@ -27,11 +27,15 @@ class ElementAccessor {
|
||||
public:
|
||||
static JSTaggedValue PUBLIC_API Get(JSHandle<JSObject> receiver, uint32_t idx);
|
||||
static JSTaggedValue Get(JSObject *receiver, uint32_t idx);
|
||||
static JSTaggedValue PUBLIC_API FastGet(JSHandle<TaggedArray> elements, uint32_t idx, ElementsKind kind);
|
||||
|
||||
template<typename T>
|
||||
static void Set(const JSThread *thread, JSHandle<JSObject> receiver, uint32_t idx, const JSHandle<T> &value,
|
||||
bool needTransition, ElementsKind extraKind = ElementsKind::NONE);
|
||||
|
||||
template<typename T>
|
||||
static void FastSet(const JSThread *thread, JSHandle<TaggedArray> elements, uint32_t idx,
|
||||
const JSHandle<T> &value, ElementsKind kind);
|
||||
static bool IsDictionaryMode(JSHandle<JSObject> receiver);
|
||||
static bool IsDictionaryMode(JSObject *receiver);
|
||||
|
||||
|
@ -1048,23 +1048,32 @@ JSTaggedValue JSStableArray::Reverse(JSThread *thread, JSHandle<JSObject> thisOb
|
||||
if (thisObjHandle->IsJSArray()) {
|
||||
JSArray::CheckAndCopyArray(thread, JSHandle<JSArray>::Cast(thisObjHandle));
|
||||
}
|
||||
JSMutableHandle<JSTaggedValue> lowerP(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> upperP(thread, JSTaggedValue::Undefined());
|
||||
ElementsKind kind = thisObjHandle->GetClass()->GetElementsKind();
|
||||
JSHandle<TaggedArray> elements(thread, thisObjHandle->GetElements());
|
||||
if (kind == ElementsKind::INT || kind == ElementsKind::HOLE_INT) {
|
||||
return FastReverse(thread, elements, lower, len, ElementsKind::INT);
|
||||
} else if (kind == ElementsKind::NUMBER || kind == ElementsKind::HOLE_NUMBER) {
|
||||
return FastReverse(thread, elements, lower, len, ElementsKind::NUMBER);
|
||||
} else {
|
||||
return FastReverse(thread, elements, lower, len, ElementsKind::TAGGED);
|
||||
}
|
||||
}
|
||||
|
||||
JSTaggedValue JSStableArray::FastReverse(JSThread *thread, JSHandle<TaggedArray> elements,
|
||||
int64_t &lower, uint32_t len, ElementsKind kind)
|
||||
{
|
||||
JSMutableHandle<JSTaggedValue> lowerValueHandle(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> upperValueHandle(thread, JSTaggedValue::Undefined());
|
||||
int64_t middle = std::floor(len / 2);
|
||||
bool needTransition = true;
|
||||
while (lower != middle) {
|
||||
if (ElementAccessor::GetElementsLength(thisObjHandle) != len) {
|
||||
if (elements->GetLength() != len) {
|
||||
break;
|
||||
}
|
||||
int64_t upper = static_cast<int64_t>(len) - lower - 1;
|
||||
lowerP.Update(JSTaggedValue(lower));
|
||||
upperP.Update(JSTaggedValue(upper));
|
||||
lowerValueHandle.Update(ElementAccessor::Get(thisObjHandle, lower));
|
||||
upperValueHandle.Update(ElementAccessor::Get(thisObjHandle, upper));
|
||||
ElementAccessor::Set(thread, thisObjHandle, lower, upperValueHandle, needTransition);
|
||||
ElementAccessor::Set(thread, thisObjHandle, upper, lowerValueHandle, needTransition);
|
||||
lowerValueHandle.Update(ElementAccessor::FastGet(elements, lower, kind));
|
||||
upperValueHandle.Update(ElementAccessor::FastGet(elements, upper, kind));
|
||||
ElementAccessor::FastSet(thread, elements, lower, upperValueHandle, kind);
|
||||
ElementAccessor::FastSet(thread, elements, upper, lowerValueHandle, kind);
|
||||
lower++;
|
||||
}
|
||||
return base::BuiltinsBase::GetTaggedDouble(true);
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
EcmaRuntimeCallInfo *argv, uint32_t &k, uint32_t len);
|
||||
static JSTaggedValue Reverse(JSThread *thread, JSHandle<JSObject> thisObjHandle,
|
||||
int64_t &lower, uint32_t len);
|
||||
static JSTaggedValue FastReverse(JSThread *thread, JSHandle<TaggedArray> elements,
|
||||
int64_t &lower, uint32_t len, ElementsKind kind);
|
||||
static JSTaggedValue Concat(JSThread *thread, JSHandle<JSObject> newArrayHandle,
|
||||
JSHandle<JSObject> thisObjHandle, int64_t &k, int64_t &n);
|
||||
template<base::TypedArrayKind typedArrayKind = base::TypedArrayKind::NON_SHARED>
|
||||
|
Loading…
Reference in New Issue
Block a user