mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-23 01:59:58 +00:00
optimize get interface of list container
Signed-off-by: shilei <shilei91@huawei.com> Change-Id: I2a8ff19917847baf36c3b1c7db61362838b0c7fa
This commit is contained in:
parent
50a0b1195d
commit
78eb353337
@ -44,6 +44,7 @@ JSTaggedValue ContainersList::ListConstructor(EcmaRuntimeCallInfo *argv)
|
||||
JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
JSHandle<JSAPIList> list = JSHandle<JSAPIList>::Cast(obj);
|
||||
list->SetIsOrderedList(true);
|
||||
|
||||
JSTaggedValue singleList = TaggedSingleList::Create(thread);
|
||||
list->SetSingleList(thread, singleList);
|
||||
@ -213,7 +214,8 @@ JSTaggedValue ContainersList::Get(EcmaRuntimeCallInfo *argv)
|
||||
JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::TYPE_ERROR, errorMsg.c_str());
|
||||
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
|
||||
}
|
||||
return jsAPIList->Get(index->GetInt());
|
||||
|
||||
return JSAPIList::FastGet(thread, index->GetInt(), jsAPIList);
|
||||
}
|
||||
|
||||
JSTaggedValue ContainersList::GetIndexOf(EcmaRuntimeCallInfo *argv)
|
||||
|
@ -2275,6 +2275,7 @@ void JSAPIList::Dump(std::ostream &os) const
|
||||
os << " - length: " << std::dec << list->GetCapacityFromTaggedArray() << "\n";
|
||||
os << " - node num: " << std::dec << list->NumberOfNodes() << "\n";
|
||||
os << " - delete node num: " << std::dec << list->NumberOfDeletedNodes() << "\n";
|
||||
os << " - is odered list: " << std::dec << this->IsOrderedList() << "\n";
|
||||
JSObject::Dump(os);
|
||||
list->Dump(os);
|
||||
}
|
||||
|
@ -67,6 +67,9 @@ JSTaggedValue JSAPIList::Insert(JSThread *thread, const JSHandle<JSAPIList> &lis
|
||||
}
|
||||
JSTaggedValue newList = TaggedSingleList::Insert(thread, singleList, value, index);
|
||||
list->SetSingleList(thread, newList);
|
||||
if (index != nodeLength) {
|
||||
list->SetIsOrderedList(false);
|
||||
}
|
||||
return JSTaggedValue::True();
|
||||
}
|
||||
|
||||
@ -108,6 +111,26 @@ JSTaggedValue JSAPIList::Get(const int index)
|
||||
return singleList->Get(index);
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIList::FastGet(JSThread *thread, const int index, const JSHandle<JSAPIList> &list)
|
||||
{
|
||||
JSHandle<TaggedSingleList> singleList(thread, list->GetSingleList());
|
||||
if (index < 0 || index >= singleList->Length()) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
int dataIndex = TaggedSingleList::ELEMENTS_START_INDEX + (index + 1) * TaggedSingleList::ENTRY_SIZE;
|
||||
if (!list->IsOrderedList()) {
|
||||
auto newSingleList = TaggedSingleList::SortByNodeOrder(thread, singleList);
|
||||
TaggedSingleList *newList = TaggedSingleList::Cast(newSingleList.GetTaggedObject());
|
||||
if (newList == nullptr) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
list->SetSingleList(thread, newSingleList);
|
||||
list->SetIsOrderedList(true);
|
||||
return newList->GetElement(dataIndex);
|
||||
}
|
||||
return singleList->GetElement(dataIndex);
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIList::GetIndexOf(const JSTaggedValue &element)
|
||||
{
|
||||
TaggedSingleList *singleList = TaggedSingleList::Cast(GetSingleList().GetTaggedObject());
|
||||
@ -126,6 +149,7 @@ void JSAPIList::Clear(JSThread *thread)
|
||||
if (singleList->NumberOfNodes() > 0) {
|
||||
singleList->Clear(thread);
|
||||
}
|
||||
SetIsOrderedList(true);
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIList::RemoveByIndex(JSThread *thread, const JSHandle<JSAPIList> &list, const int &index)
|
||||
@ -140,12 +164,16 @@ JSTaggedValue JSAPIList::RemoveByIndex(JSThread *thread, const JSHandle<JSAPILis
|
||||
JSTaggedValue error = ContainerError::BusinessError(thread, ErrorFlag::RANGE_ERROR, oss.str().c_str());
|
||||
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, JSTaggedValue::Exception());
|
||||
}
|
||||
if (index != (nodeLength - 1)) {
|
||||
list->SetIsOrderedList(false);
|
||||
}
|
||||
return singleList->RemoveByIndex(thread, index);
|
||||
}
|
||||
|
||||
JSTaggedValue JSAPIList::Remove(JSThread *thread, const JSTaggedValue &element)
|
||||
{
|
||||
TaggedSingleList *singleList = TaggedSingleList::Cast(GetSingleList().GetTaggedObject());
|
||||
SetIsOrderedList(false);
|
||||
return singleList->Remove(thread, element);
|
||||
}
|
||||
|
||||
@ -163,6 +191,7 @@ JSTaggedValue JSAPIList::Sort(JSThread *thread, const JSHandle<JSTaggedValue> &t
|
||||
{
|
||||
JSHandle<JSAPIList> list = JSHandle<JSAPIList>::Cast(thisHandle);
|
||||
JSHandle<TaggedSingleList> singleList(thread, list->GetSingleList());
|
||||
list->SetIsOrderedList(false);
|
||||
return TaggedSingleList::Sort(thread, callbackFn, singleList);
|
||||
}
|
||||
|
||||
@ -204,6 +233,7 @@ JSTaggedValue JSAPIList::GetSubList(JSThread *thread, const JSHandle<JSAPIList>
|
||||
JSHandle<JSAPIList> sublist = thread->GetEcmaVM()->GetFactory()->NewJSAPIList();
|
||||
TaggedSingleList::GetSubList(thread, singleList, fromIndex, toIndex, subSingleList);
|
||||
sublist->SetSingleList(thread, subSingleList);
|
||||
sublist->SetIsOrderedList(true);
|
||||
return sublist.GetTaggedValue();
|
||||
}
|
||||
|
||||
|
@ -24,12 +24,36 @@ namespace panda::ecmascript {
|
||||
class JSAPIList : public JSObject {
|
||||
public:
|
||||
static constexpr uint32_t DEFAULT_CAPACITY_LENGTH = 10;
|
||||
static constexpr uint32_t UNUSED_BIT_FILEDS_NUM = 31;
|
||||
using IsOrderedListBit = BitField<uint32_t, 0, UNUSED_BIT_FILEDS_NUM>::NextFlag;
|
||||
|
||||
static JSAPIList *Cast(TaggedObject *object)
|
||||
{
|
||||
ASSERT(JSTaggedValue(object).IsJSAPIList());
|
||||
return static_cast<JSAPIList *>(object);
|
||||
}
|
||||
|
||||
inline void SetIsOrderedList(bool flag) const
|
||||
{
|
||||
IsOrderedListBit::Set<uint32_t>(flag, GetBitFieldAddr());
|
||||
}
|
||||
|
||||
inline bool IsOrderedList() const
|
||||
{
|
||||
uint32_t bits = GetBitField();
|
||||
return IsOrderedListBit::Decode(bits);
|
||||
}
|
||||
|
||||
uint32_t *GetBitFieldAddr() const
|
||||
{
|
||||
return reinterpret_cast<uint32_t *>(ToUintPtr(this) + BIT_FIELD_OFFSET);
|
||||
}
|
||||
|
||||
inline void ClearBitField()
|
||||
{
|
||||
SetBitField(0UL);
|
||||
}
|
||||
|
||||
static void Add(JSThread *thread, const JSHandle<JSAPIList> &list, const JSHandle<JSTaggedValue> &value);
|
||||
static JSTaggedValue Insert(JSThread *thread, const JSHandle<JSAPIList> &list,
|
||||
const JSHandle<JSTaggedValue> &value, const int index);
|
||||
@ -52,6 +76,7 @@ public:
|
||||
static bool SetProperty(JSThread *thread, const JSHandle<JSAPIList> &obj,
|
||||
const JSHandle<JSTaggedValue> &key,
|
||||
const JSHandle<JSTaggedValue> &value);
|
||||
static JSTaggedValue FastGet(JSThread *thread, const int index, const JSHandle<JSAPIList> &list);
|
||||
|
||||
JSTaggedValue GetFirst();
|
||||
JSTaggedValue GetLast();
|
||||
@ -69,8 +94,10 @@ public:
|
||||
}
|
||||
|
||||
static constexpr size_t SINGLY_LIST_OFFSET = JSObject::SIZE;
|
||||
ACCESSORS(SingleList, SINGLY_LIST_OFFSET, SIZE);
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, SINGLY_LIST_OFFSET, SIZE)
|
||||
ACCESSORS(SingleList, SINGLY_LIST_OFFSET, BIT_FIELD_OFFSET)
|
||||
ACCESSORS_PRIMITIVE_FIELD(BitField, uint32_t, BIT_FIELD_OFFSET, LAST_OFFSET)
|
||||
DEFINE_ALIGN_SIZE(LAST_OFFSET);
|
||||
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, SINGLY_LIST_OFFSET, BIT_FIELD_OFFSET)
|
||||
DECL_DUMP()
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -1335,6 +1335,7 @@ void ObjectFactory::InitializeJSObject(const JSHandle<JSObject> &obj, const JSHa
|
||||
}
|
||||
case JSType::JS_API_LIST: {
|
||||
JSAPIList::Cast(*obj)->SetSingleList(thread_, JSTaggedValue::Undefined());
|
||||
JSAPIList::Cast(*obj)->SetBitField(0UL);
|
||||
break;
|
||||
}
|
||||
case JSType::JS_API_LINKED_LIST: {
|
||||
|
@ -570,6 +570,32 @@ JSHandle<TaggedArray> TaggedSingleList::OwnKeys(JSThread *thread, const JSHandle
|
||||
return TaggedList<TaggedSingleList>::OwnKeys(thread, taggedList);
|
||||
}
|
||||
|
||||
JSTaggedValue TaggedSingleList::SortByNodeOrder(const JSThread *thread, const JSHandle<TaggedSingleList> &taggedList)
|
||||
{
|
||||
int actualNodeNum = taggedList->NumberOfNodes();
|
||||
int nextDataIndex = taggedList->GetElement(ELEMENTS_START_INDEX + NEXT_PTR_OFFSET).GetInt();
|
||||
uint32_t length = static_cast<uint32_t>(actualNodeNum);
|
||||
JSHandle<TaggedSingleList> list = TaggedList<TaggedSingleList>::Create(
|
||||
thread, length < DEFAULT_ARRAY_LENGHT ? DEFAULT_ARRAY_LENGHT : length);
|
||||
|
||||
int tailTableIndex = ELEMENTS_START_INDEX + actualNodeNum * TaggedSingleList::ENTRY_SIZE;
|
||||
int nextTailIndex = ELEMENTS_START_INDEX + TaggedSingleList::ENTRY_SIZE;
|
||||
list->SetNumberOfNodes(thread, actualNodeNum);
|
||||
list->SetElement(thread, TAIL_TABLE_INDEX, JSTaggedValue(tailTableIndex));
|
||||
list->SetElement(thread, ELEMENTS_START_INDEX, JSTaggedValue::Hole());
|
||||
list->SetElement(thread, ELEMENTS_START_INDEX + NEXT_PTR_OFFSET, JSTaggedValue(nextTailIndex));
|
||||
|
||||
for (int i = 0; i < actualNodeNum; ++i) {
|
||||
int curDataIndex = ELEMENTS_START_INDEX + (i + 1) * TaggedSingleList::ENTRY_SIZE;
|
||||
list->SetElement(thread, curDataIndex, taggedList->GetElement(nextDataIndex));
|
||||
list->SetElement(thread, curDataIndex + NEXT_PTR_OFFSET,
|
||||
JSTaggedValue(curDataIndex + TaggedSingleList::ENTRY_SIZE));
|
||||
nextDataIndex = taggedList->GetElement(nextDataIndex + NEXT_PTR_OFFSET).GetInt();
|
||||
}
|
||||
list->SetElement(thread, tailTableIndex + NEXT_PTR_OFFSET, JSTaggedValue(ELEMENTS_START_INDEX));
|
||||
return list.GetTaggedValue();
|
||||
}
|
||||
|
||||
// TaggedDoubleList
|
||||
JSTaggedValue TaggedDoubleList::Create(const JSThread *thread, int numberOfElements)
|
||||
{
|
||||
|
@ -146,6 +146,8 @@ public:
|
||||
static void GetSubList(JSThread *thread, const JSHandle<TaggedSingleList> &taggedList,
|
||||
const int fromIndex, const int toIndex, const JSHandle<TaggedSingleList> &subList);
|
||||
static JSHandle<TaggedArray> OwnKeys(JSThread *thread, const JSHandle<TaggedSingleList> &taggedList);
|
||||
static JSTaggedValue SortByNodeOrder(const JSThread *thread, const JSHandle<TaggedSingleList> &taggedList);
|
||||
|
||||
void Clear(const JSThread *thread);
|
||||
bool IsEmpty() const;
|
||||
bool Has(const JSTaggedValue &value);
|
||||
|
@ -1301,7 +1301,7 @@ HWTEST_F_L0(EcmaDumpTest, HeapProfileDump)
|
||||
}
|
||||
case JSType::JS_API_LIST: {
|
||||
// 1 : 1 dump fileds number
|
||||
CHECK_DUMP_FIELDS(JSObject::SIZE, JSAPIList::SIZE, 1U);
|
||||
CHECK_DUMP_FIELDS(JSObject::SIZE, JSAPIList::SIZE, 2U);
|
||||
JSHandle<JSAPIList> jsAPIList = NewJSAPIList(thread, factory);
|
||||
DUMP_FOR_HANDLE(jsAPIList);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user