Optimize Object.keys, Array.foreach, Map, Set, WeakMap, WeakSet

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7Z6NE?from=project-issue
Signed-off-by: yaochaonan <yaochaonan@huawei.com>

Change-Id: Ied4e891b35cb02f85df512f3339247a2a01fe73e
This commit is contained in:
yaochaonan 2023-09-06 20:07:06 +08:00
parent c633d4a865
commit bfaa39a31e
9 changed files with 27 additions and 37 deletions

View File

@ -1104,7 +1104,7 @@ JSTaggedValue BuiltinsArray::ForEach(EcmaRuntimeCallInfo *argv)
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
uint32_t k = 0;
if (thisObjVal->IsStableJSArray(thread)) {
JSStableArray::HandleforEachOfStable(thread, thisObjHandle, callbackFnHandle, thisArgHandle, k);
JSStableArray::HandleforEachOfStable(thread, thisObjHandle, callbackFnHandle, thisArgHandle, len, k);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
}
const uint32_t argsLength = 3; // 3: «kValue, k, O»

View File

@ -133,8 +133,7 @@ JSTaggedValue BuiltinsMap::Has(EcmaRuntimeCallInfo *argv)
if (!self->IsJSMap()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSMap", JSTaggedValue::Exception());
}
JSMap *jsMap = JSMap::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSMap *jsMap = JSMap::Cast(self.GetTaggedValue().GetTaggedObject());
JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
bool flag = jsMap->Has(key.GetTaggedValue());
return GetTaggedBoolean(flag);
@ -151,8 +150,7 @@ JSTaggedValue BuiltinsMap::Get(EcmaRuntimeCallInfo *argv)
if (!self->IsJSMap()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSMap", JSTaggedValue::Exception());
}
JSMap *jsMap = JSMap::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSMap *jsMap = JSMap::Cast(self.GetTaggedValue().GetTaggedObject());
JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
JSTaggedValue value = jsMap->Get(key.GetTaggedValue());
return value;
@ -229,8 +227,7 @@ JSTaggedValue BuiltinsMap::GetSize(EcmaRuntimeCallInfo *argv)
if (!self->IsJSMap()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSMap", JSTaggedValue::Exception());
}
JSMap *jsMap = JSMap::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSMap *jsMap = JSMap::Cast(self.GetTaggedValue().GetTaggedObject());
uint32_t count = jsMap->GetSize();
return JSTaggedValue(count);
}

View File

@ -117,8 +117,7 @@ JSTaggedValue BuiltinsSet::Add(EcmaRuntimeCallInfo *argv)
}
JSHandle<JSTaggedValue> value(GetCallArg(argv, 0));
JSHandle<JSSet> set(JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSSet> set(self);
JSSet::Add(thread, set, value);
return set.GetTaggedValue();
}
@ -136,8 +135,7 @@ JSTaggedValue BuiltinsSet::Clear(EcmaRuntimeCallInfo *argv)
if (!self->IsJSSet()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSSet", JSTaggedValue::Exception());
}
JSHandle<JSSet> set(thread, JSSet::Cast(*JSTaggedValue::ToObject(thread, self)));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSSet> set(self);
JSSet::Clear(thread, set);
return JSTaggedValue::Undefined();
}
@ -155,8 +153,7 @@ JSTaggedValue BuiltinsSet::Delete(EcmaRuntimeCallInfo *argv)
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSSet", JSTaggedValue::Exception());
}
JSHandle<JSSet> set(thread, JSSet::Cast(*JSTaggedValue::ToObject(thread, self)));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSSet> set(self);
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
bool flag = JSSet::Delete(thread, set, value);
return GetTaggedBoolean(flag);
@ -174,8 +171,7 @@ JSTaggedValue BuiltinsSet::Has(EcmaRuntimeCallInfo *argv)
if (!self->IsJSSet()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSSet", JSTaggedValue::Exception());
}
JSSet *jsSet = JSSet::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSSet* jsSet = JSSet::Cast(self.GetTaggedValue().GetTaggedObject());
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
bool flag = jsSet->Has(value.GetTaggedValue());
return GetTaggedBoolean(flag);
@ -252,8 +248,7 @@ JSTaggedValue BuiltinsSet::GetSize(EcmaRuntimeCallInfo *argv)
if (!self->IsJSSet()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSSet", JSTaggedValue::Exception());
}
JSSet *jsSet = JSSet::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSSet* jsSet = JSSet::Cast(self.GetTaggedValue().GetTaggedObject());
uint32_t count = jsSet->GetSize();
return JSTaggedValue(count);
}

View File

@ -106,8 +106,7 @@ JSTaggedValue BuiltinsWeakMap::Has(EcmaRuntimeCallInfo *argv)
if (!self->IsJSWeakMap()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSWeakMap.", JSTaggedValue::Exception());
}
JSWeakMap *jsWeakMap = JSWeakMap::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSWeakMap *jsWeakMap = JSWeakMap::Cast(self.GetTaggedValue().GetTaggedObject());
JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
// 5.If CanBeHeldWeakly(key) is false, return false.
if (!JSTaggedValue::CanBeHeldWeakly(thread, key)) {
@ -128,8 +127,7 @@ JSTaggedValue BuiltinsWeakMap::Get(EcmaRuntimeCallInfo *argv)
if (!self->IsJSWeakMap()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSWeakMap.", JSTaggedValue::Exception());
}
JSWeakMap *jsWeakMap = JSWeakMap::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSWeakMap *jsWeakMap = JSWeakMap::Cast(self.GetTaggedValue().GetTaggedObject());
JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
// 4.If CanBeHeldWeakly(key) is false, return undefined.
if (!JSTaggedValue::CanBeHeldWeakly(thread, key)) {

View File

@ -125,8 +125,7 @@ JSTaggedValue BuiltinsWeakSet::Add(EcmaRuntimeCallInfo *argv)
THROW_TYPE_ERROR_AND_RETURN(thread, "invalid value used in weak set", JSTaggedValue::Exception());
}
JSHandle<JSWeakSet> weakSet(thread, JSWeakSet::Cast(*JSTaggedValue::ToObject(thread, self)));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSWeakSet> weakSet(self);
JSWeakSet::Add(thread, weakSet, value);
return weakSet.GetTaggedValue();
}
@ -144,8 +143,7 @@ JSTaggedValue BuiltinsWeakSet::Delete(EcmaRuntimeCallInfo *argv)
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSWeakSet", JSTaggedValue::Exception());
}
JSHandle<JSWeakSet> weakSet(thread, JSWeakSet::Cast(*JSTaggedValue::ToObject(thread, self)));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSHandle<JSWeakSet> weakSet(self);
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
// 4.If CanBeHeldWeakly(value) is false, return false.
if (!JSTaggedValue::CanBeHeldWeakly(thread, value)) {
@ -166,8 +164,7 @@ JSTaggedValue BuiltinsWeakSet::Has(EcmaRuntimeCallInfo *argv)
if (!self->IsJSWeakSet()) {
THROW_TYPE_ERROR_AND_RETURN(thread, "obj is not JSWeakSet", JSTaggedValue::Exception());
}
JSWeakSet *jsWeakSet = JSWeakSet::Cast(*JSTaggedValue::ToObject(thread, self));
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
JSWeakSet *jsWeakSet = JSWeakSet::Cast(self.GetTaggedValue().GetTaggedObject());
JSHandle<JSTaggedValue> value = GetCallArg(argv, 0);
// 4.If CanBeHeldWeakly(value) is false, return false.
if (!JSTaggedValue::CanBeHeldWeakly(thread, value)) {

View File

@ -398,8 +398,9 @@ JSHandle<TaggedArray> JSObject::GetAllEnumKeys(const JSThread *thread, const JSH
JSHClass *jsHclass = obj->GetJSHClass();
JSTaggedValue enumCache = jsHclass->GetEnumCache();
if (!enumCache.IsNull()) {
auto keyArray = JSHandle<TaggedArray>(thread, enumCache);
*keys = keyArray->GetLength();
JSHandle<TaggedArray> cacheArray = JSHandle<TaggedArray>(thread, enumCache);
*keys = cacheArray->GetLength();
JSHandle<TaggedArray> keyArray = factory->CopyArray(cacheArray, *keys, *keys);
return keyArray;
}
JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(numOfKeys);
@ -409,6 +410,8 @@ JSHandle<TaggedArray> JSObject::GetAllEnumKeys(const JSThread *thread, const JSH
->GetAllEnumKeys(thread, end, offset, *keyArray, keys, obj);
if (*keys == keyArray->GetLength()) {
jsHclass->SetEnumCache(thread, keyArray.GetTaggedValue());
JSHandle<TaggedArray> newkeyArray = factory->CopyArray(keyArray, *keys, *keys);
return newkeyArray;
}
}
return keyArray;
@ -1563,9 +1566,11 @@ JSHandle<TaggedArray> JSObject::EnumerableOwnNames(JSThread *thread, const JSHan
if (copyLengthOfKeys != 0 && copyLengthOfElements != 0) {
keys = TaggedArray::AppendSkipHole(thread, elementArray, keyArray, copyLengthOfKeys + copyLengthOfElements);
} else if (copyLengthOfKeys != 0) {
keys = factory->CopyArray(keyArray, copyLengthOfKeys, copyLengthOfKeys);
keyArray->SetLength(copyLengthOfKeys); // keyArray will skip nonEnumerable properties, need re-set length.
return keyArray;
} else if (copyLengthOfElements != 0) {
keys = factory->CopyArray(elementArray, copyLengthOfElements, copyLengthOfElements);
elementArray->SetLength(copyLengthOfElements); // elementArray will skip hole value, need re-set length.
return elementArray;
} else {
keys = factory->EmptyArray();
}

View File

@ -429,13 +429,12 @@ JSTaggedValue JSStableArray::HandleEveryOfStable(JSThread *thread, JSHandle<JSOb
JSTaggedValue JSStableArray::HandleforEachOfStable(JSThread *thread, JSHandle<JSObject> thisObjHandle,
JSHandle<JSTaggedValue> callbackFnHandle,
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k)
JSHandle<JSTaggedValue> thisArgHandle, uint32_t len, uint32_t &k)
{
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
JSMutableHandle<TaggedArray> array(thread, thisObjHandle->GetElements());
uint64_t len = static_cast<uint64_t>(base::ArrayHelper::GetArrayLength(thread, thisObjVal));
const int32_t argsLength = 3; // 3: ?kValue, k, O?
JSMutableHandle<JSTaggedValue> kValue(thread, JSTaggedValue::Undefined());
if (array->GetLength() <= k) {

View File

@ -42,7 +42,7 @@ public:
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k);
static JSTaggedValue HandleforEachOfStable(JSThread *thread, JSHandle<JSObject> thisObjHandle,
JSHandle<JSTaggedValue> callbackFnHandle,
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k);
JSHandle<JSTaggedValue> thisArgHandle, uint32_t len, uint32_t &k);
static JSTaggedValue IndexOf(JSThread *thread, JSHandle<JSTaggedValue> receiver,
JSHandle<JSTaggedValue> searchElement, uint32_t from, uint32_t len);
static JSTaggedValue LastIndexOf(JSThread *thread, JSHandle<JSTaggedValue> receiver,
@ -62,7 +62,7 @@ public:
int64_t insertCount, int64_t index, JSHandle<JSTaggedValue> value);
static JSTaggedValue ToSpliced(JSHandle<JSArray> receiver, EcmaRuntimeCallInfo *argv,
int64_t argc, int64_t actualStart, int64_t actualSkipCount, int64_t insertCount);
static JSTaggedValue ToReversed(JSThread *thread, JSHandle<JSArray> receiver, int64_t insertCount);
static JSTaggedValue ToReversed(JSThread *thread, JSHandle<JSArray> receiver, int64_t insertCount);
static JSTaggedValue Reduce(JSThread *thread, JSHandle<JSObject> thisObjHandle,
JSHandle<JSTaggedValue> callbackFnHandle,
JSMutableHandle<JSTaggedValue> accumulator, int64_t &k, int64_t &len);

View File

@ -873,8 +873,7 @@ JSHandle<JSObject> ObjectFactory::NewJSObjectByConstructor(const JSHandle<JSFunc
{
if (!constructor->HasFunctionPrototype() ||
(constructor->GetProtoOrHClass().IsHeapObject() && constructor->GetFunctionPrototype().IsECMAObject())) {
JSHandle<JSHClass> jshclass = JSFunction::GetInstanceJSHClass(thread_, constructor,
JSHandle<JSTaggedValue>(constructor));
JSHandle<JSHClass> jshclass(thread_, JSFunction::GetOrCreateInitialJSHClass(thread_, constructor));
return NewJSObjectWithInit(jshclass);
}
JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();