Fix AddPropertyByName tagged array extend bug

Description:Modify tagged array extend strategy
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7ZQ8G?from=project-issue

Signed-off-by: dingwen <dingwen6@huawei.com>
Change-Id: Idb88a8911b9d87df39e7e1cccc08cb1a1ddf4beb
This commit is contained in:
dingwen 2023-09-08 16:41:09 +08:00
parent d37c289fd8
commit d81259c9c7
21 changed files with 108 additions and 43 deletions

View File

@ -536,7 +536,7 @@ void StubBuilder::JSObjectSetProperty(
return;
}
GateRef StubBuilder::ComputePropertyCapacityInJSObj(GateRef oldLength)
GateRef StubBuilder::ComputeNonInlinedFastPropsCapacity(GateRef oldLength, GateRef maxNonInlinedFastPropsCapacity)
{
auto env = GetEnvironment();
Label subEntry(env);
@ -546,11 +546,10 @@ GateRef StubBuilder::ComputePropertyCapacityInJSObj(GateRef oldLength)
GateRef newL = Int32Add(oldLength, Int32(JSObject::PROPERTIES_GROW_SIZE));
Label reachMax(env);
Label notReachMax(env);
Branch(Int32GreaterThan(newL, Int32(JSHClass::MAX_CAPACITY_OF_OUT_OBJECTS)),
&reachMax, &notReachMax);
Branch(Int32GreaterThan(newL, maxNonInlinedFastPropsCapacity), &reachMax, &notReachMax);
{
Bind(&reachMax);
result = Int32(JSHClass::MAX_CAPACITY_OF_OUT_OBJECTS);
result = maxNonInlinedFastPropsCapacity;
Jump(&exit);
Bind(&notReachMax);
result = newL;
@ -860,20 +859,22 @@ GateRef StubBuilder::AddPropertyByName(GateRef glue, GateRef receiver, GateRef k
Label isArrayFull(env);
Label arrayNotFull(env);
Label afterArrLenCon(env);
Branch(Int32GreaterThanOrEqual(*length, outProps), &isArrayFull, &arrayNotFull);
Branch(Int32Equal(*length, outProps), &isArrayFull, &arrayNotFull);
{
Bind(&isArrayFull);
{
Label ChangeToDict(env);
Label notChangeToDict(env);
Label afterDictChangeCon(env);
Branch(Int32GreaterThanOrEqual(*length, Int32(JSHClass::MAX_CAPACITY_OF_OUT_OBJECTS)),
GateRef maxNonInlinedFastPropsCapacity =
Int32Sub(Int32(PropertyAttributes::MAX_FAST_PROPS_CAPACITY), inlinedProperties);
Branch(Int32GreaterThanOrEqual(*length, maxNonInlinedFastPropsCapacity),
&ChangeToDict, &notChangeToDict);
{
Bind(&ChangeToDict);
{
attr = SetDictionaryOrderFieldInPropAttr(*attr,
Int32(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES));
Int32(PropertyAttributes::MAX_FAST_PROPS_CAPACITY));
GateRef res = CallRuntime(glue, RTSTUB_ID(NameDictPutIfAbsent),
{ receiver, *array, key, value, IntToTaggedInt(*attr), TaggedTrue() });
SetPropertiesArray(VariableType::JS_POINTER(), glue, receiver, res);
@ -884,7 +885,7 @@ GateRef StubBuilder::AddPropertyByName(GateRef glue, GateRef receiver, GateRef k
Jump(&afterDictChangeCon);
}
Bind(&afterDictChangeCon);
GateRef capacity = ComputePropertyCapacityInJSObj(*length);
GateRef capacity = ComputeNonInlinedFastPropsCapacity(*length, maxNonInlinedFastPropsCapacity);
array = CallRuntime(glue, RTSTUB_ID(CopyArray),
{ *array, IntToTaggedInt(*length), IntToTaggedInt(capacity) });
SetPropertiesArray(VariableType::JS_POINTER(), glue, receiver, *array);

View File

@ -457,7 +457,7 @@ public:
GateRef IsInternalString(GateRef string);
GateRef IsDigit(GateRef ch);
GateRef StringToElementIndex(GateRef glue, GateRef string);
GateRef ComputePropertyCapacityInJSObj(GateRef oldLength);
GateRef ComputeNonInlinedFastPropsCapacity(GateRef oldLength, GateRef maxNonInlinedFastPropsCapacity);
GateRef FindTransitions(GateRef glue, GateRef receiver, GateRef hClass, GateRef key, GateRef attr);
void TransitionForRepChange(GateRef glue, GateRef receiver, GateRef key, GateRef attr);
void TransitToElementsKind(GateRef glue, GateRef receiver, GateRef value, GateRef kind);

View File

@ -183,7 +183,7 @@ JSHandle<JSHClass> TSHClassGenerator::CreateIHClass(const JSThread *thread,
JSHandle<TSObjLayoutInfo> tsLayout(thread, instanceType->GetObjLayoutInfo());
uint32_t numOfProps = tsLayout->GetNumOfProperties();
JSHandle<JSHClass> hclass;
if (LIKELY(numOfProps <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES)) {
if (LIKELY(numOfProps <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(numOfProps);
for (uint32_t index = 0; index < numOfProps; ++index) {
@ -220,7 +220,7 @@ JSHandle<JSHClass> TSHClassGenerator::CreatePHClass(const JSThread *thread,
JSHandle<TSObjLayoutInfo> tsLayout(thread, prototypeType->GetObjLayoutInfo());
uint32_t numOfProps = tsLayout->GetNumOfProperties();
JSHandle<JSHClass> hclass;
if (LIKELY(numOfProps <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES)) {
if (LIKELY(numOfProps <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
JSHandle<JSTaggedValue> ctor = globalConst->GetHandledConstructorString();
@ -295,7 +295,7 @@ JSHandle<JSHClass> TSHClassGenerator::CreateCHClass(const JSThread *thread,
uint32_t functionFirstIndex = numOfProps;
uint32_t numNonStaticFunc = 0;
bool hasFunction = false;
if (LIKELY(numOfProps <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES)) {
if (LIKELY(numOfProps <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
TSManager *tsManager = thread->GetCurrentEcmaContext()->GetTSManager();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(numOfProps);

View File

@ -301,8 +301,10 @@ void ICRuntimeStub::StoreWithTransition(JSThread *thread, JSObject *receiver, JS
properties = factory->NewTaggedArray(capacity);
} else {
auto arrayHandle = JSHandle<TaggedArray>(thread, array);
properties = factory->CopyArray(arrayHandle, capacity,
JSObject::ComputePropertyCapacity(capacity));
uint32_t maxNonInlinedFastPropsCapacity = objHandle->GetNonInlinedFastPropsCapacity();
uint32_t newLen = JSObject::ComputeNonInlinedFastPropsCapacity(capacity,
maxNonInlinedFastPropsCapacity);
properties = factory->CopyArray(arrayHandle, capacity, newLen);
}
properties->Set(thread, index, valueHandle);
objHandle->SetProperties(thread, properties);

View File

@ -322,8 +322,6 @@ public:
static_assert(BitFieldLastBit::START_BIT + BitFieldLastBit::SIZE <= sizeof(uint32_t) * BITS_PER_BYTE, "Invalid");
static constexpr int DEFAULT_CAPACITY_OF_IN_OBJECTS = 4;
static constexpr int MAX_CAPACITY_OF_OUT_OBJECTS =
PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES - DEFAULT_CAPACITY_OF_IN_OBJECTS;
static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED = 5;
static constexpr int OFFSET_MAX_OBJECT_SIZE_IN_WORDS =
PropertyAttributes::OFFSET_BITFIELD_NUM + OFFSET_MAX_OBJECT_SIZE_IN_WORDS_WITHOUT_INLINED;
@ -1560,7 +1558,7 @@ public:
inline void IncNumberOfProps()
{
ASSERT(NumberOfProps() < PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
ASSERT(NumberOfProps() < PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
SetNumberOfProps(NumberOfProps() + 1);
}
@ -1838,7 +1836,7 @@ private:
uint32_t data_ {0};
};
static_assert(PropertyLookupResult::OffsetBits::MaxValue() >
(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES * JSTaggedValue::TaggedTypeSize()));
(PropertyAttributes::MAX_FAST_PROPS_CAPACITY * JSTaggedValue::TaggedTypeSize()));
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JS_HCLASS_H

View File

@ -58,6 +58,15 @@ inline JSHClass *JSObject::GetJSHClass() const
return GetClass();
}
inline uint32_t JSObject::GetNonInlinedFastPropsCapacity() const
{
uint32_t inlineProps = GetJSHClass()->GetInlinedProperties();
if (inlineProps < JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS) {
return PropertyAttributes::MAX_FAST_PROPS_CAPACITY - JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS;
}
return PropertyAttributes::MAX_FAST_PROPS_CAPACITY - inlineProps;
}
inline bool JSObject::IsJSGlobalObject() const
{
return GetJSHClass()->IsJSGlobalObject();
@ -357,11 +366,11 @@ inline uint32_t JSObject::ComputeElementCapacityHighGrowth(uint32_t oldCapacity)
return newCapacity > MIN_ELEMENTS_LENGTH ? newCapacity : MIN_ELEMENTS_LENGTH;
}
inline uint32_t JSObject::ComputePropertyCapacity(uint32_t oldCapacity)
inline uint32_t JSObject::ComputeNonInlinedFastPropsCapacity(uint32_t oldCapacity,
uint32_t maxNonInlinedFastPropsCapacity)
{
uint32_t newCapacity = static_cast<uint32_t>(oldCapacity + PROPERTIES_GROW_SIZE);
return newCapacity > JSHClass::MAX_CAPACITY_OF_OUT_OBJECTS ? JSHClass::MAX_CAPACITY_OF_OUT_OBJECTS
: newCapacity;
return newCapacity > maxNonInlinedFastPropsCapacity ? maxNonInlinedFastPropsCapacity : newCapacity;
}
// static

View File

@ -2140,7 +2140,7 @@ JSHandle<JSObject> JSObject::CreateObjectFromProperties(const JSThread *thread,
}
propsLen++;
}
if (propsLen <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES) {
if (propsLen <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY) {
JSHandle<JSObject> obj = factory->NewOldSpaceObjLiteralByHClass(properties, propsLen);
ASSERT_PRINT(obj->IsECMAObject(), "Obj is not a valid object");
SetAllPropertys(thread, obj, properties, propsLen, ihcVal);

View File

@ -527,6 +527,7 @@ public:
void FillElementsWithHoles(const JSThread *thread, uint32_t start, uint32_t end);
JSHClass *GetJSHClass() const;
uint32_t GetNonInlinedFastPropsCapacity() const;
bool IsJSGlobalObject() const;
bool IsConstructor() const;
bool IsECMAObject() const;
@ -666,7 +667,7 @@ private:
static uint32_t ComputeElementCapacity(uint32_t oldCapacity, bool isNew = false);
static uint32_t ComputeElementCapacityHighGrowth(uint32_t oldCapacity);
static uint32_t ComputePropertyCapacity(uint32_t oldCapacity);
static uint32_t ComputeNonInlinedFastPropsCapacity(uint32_t oldCapacity, uint32_t maxNonInlinedFastPropsCapacity);
static JSTaggedValue ShouldGetValueFromBox(ObjectOperator *op);
static std::pair<JSHandle<TaggedArray>, JSHandle<TaggedArray>> GetOwnEnumerableNamesInFastMode(

View File

@ -185,7 +185,7 @@ JSHandle<JSHClass> ClassInfoExtractor::CreatePrototypeHClass(JSThread *thread, c
return JSHandle<JSHClass>(globalConst->GetHandledClassPrototypeClass());
}
JSHandle<JSHClass> hclass;
if (LIKELY(length <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES)) {
if (LIKELY(length <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
for (uint32_t index = 0; index < length; ++index) {
@ -241,7 +241,7 @@ JSHandle<JSHClass> ClassInfoExtractor::CreateConstructorHClass(JSThread *thread,
}
}
JSHandle<JSHClass> hclass;
if (LIKELY(length <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES)) {
if (LIKELY(length <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY)) {
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
JSHandle<LayoutInfo> layout = factory->CreateLayoutInfo(length, MemSpaceType::OLD_SPACE, GrowMode::KEEP);
for (uint32_t index = 0; index < length; ++index) {
@ -516,7 +516,7 @@ JSHandle<NameDictionary> ClassHelper::BuildDictionaryProperties(JSThread *thread
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
uint32_t length = keys->GetLength();
ASSERT(length > PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
ASSERT(length > PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
ASSERT(keys->GetLength() == properties->GetLength());
JSMutableHandle<NameDictionary> dict(

View File

@ -29,7 +29,7 @@ struct Properties {
class LayoutInfo : private TaggedArray {
public:
static constexpr int MIN_PROPERTIES_LENGTH = JSObject::MIN_PROPERTIES_LENGTH;
static constexpr int MAX_PROPERTIES_LENGTH = PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES;
static constexpr int MAX_PROPERTIES_LENGTH = PropertyAttributes::MAX_FAST_PROPS_CAPACITY;
static constexpr uint32_t ELEMENTS_INDEX_LOG2 = 1;
static constexpr uint32_t ATTR_INDEX_OFFSET = 1;

View File

@ -3108,7 +3108,7 @@ JSHandle<JSHClass> ObjectFactory::CreateObjectClass(const JSHandle<TaggedArray>
layoutInfoHandle->AddKey(thread_, fieldOrder, key.GetTaggedValue(), attributes);
fieldOrder++;
}
ASSERT(fieldOrder <= PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
ASSERT(fieldOrder <= PropertyAttributes::MAX_FAST_PROPS_CAPACITY);
JSHandle<JSHClass> objClass = NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, fieldOrder);
objClass->SetPrototype(thread_, proto.GetTaggedValue());
{

View File

@ -510,12 +510,12 @@ PropertyAttributes ObjectFastOperator::AddPropertyByName(JSThread *thread, JSHan
if (!array->IsDictionaryMode()) {
attr.SetIsInlinedProps(false);
uint32_t nonInlinedProps = static_cast<uint32_t>(objHandle->GetJSHClass()->GetNextNonInlinedPropsIndex());
ASSERT(length >= nonInlinedProps);
// if array is full, grow array or change to dictionary mode
if (length >= nonInlinedProps) {
if (UNLIKELY(length >= JSHClass::MAX_CAPACITY_OF_OUT_OBJECTS)) {
if (length == nonInlinedProps) {
uint32_t maxNonInlinedFastPropsCapacity = objHandle->GetNonInlinedFastPropsCapacity();
if (UNLIKELY(length >= maxNonInlinedFastPropsCapacity)) {
// change to dictionary and add one.
JSHandle<NameDictionary> dict(JSObject::TransitionToDictionary(thread, objHandle));
JSHandle<NameDictionary> newDict =
@ -525,7 +525,7 @@ PropertyAttributes ObjectFastOperator::AddPropertyByName(JSThread *thread, JSHan
return attr;
}
// Grow properties array size
uint32_t capacity = JSObject::ComputePropertyCapacity(length);
uint32_t capacity = JSObject::ComputeNonInlinedFastPropsCapacity(length, maxNonInlinedFastPropsCapacity);
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
array.Update(factory->CopyArray(array, length, capacity).GetTaggedValue());
objHandle->SetProperties(thread, array.GetTaggedValue());

View File

@ -85,7 +85,7 @@ public:
static constexpr uint32_t OFFSET_BITFIELD_NUM = 10;
static constexpr uint32_t REPRESENTATION_NUM = 2;
static constexpr uint32_t TRACK_TYPE_NUM = 3;
static constexpr uint32_t MAX_CAPACITY_OF_PROPERTIES = (1U << OFFSET_BITFIELD_NUM) - 1;
static constexpr uint32_t MAX_FAST_PROPS_CAPACITY = (1U << OFFSET_BITFIELD_NUM) - 1;
static constexpr unsigned BITS_PER_BYTE = 8;
using PropertyMetaDataField = BitField<int, 0, 4>; // 4: property metaData field occupies 4 bits

View File

@ -277,7 +277,9 @@ DEF_RUNTIME_STUBS(PropertiesSetValue)
if (capacity == 0) {
properties = factory->NewTaggedArray(JSObject::MIN_PROPERTIES_LENGTH);
} else {
properties = factory->CopyArray(arrayHandle, capacity, JSObject::ComputePropertyCapacity(capacity));
uint32_t maxNonInlinedFastPropsCapacity = objHandle->GetNonInlinedFastPropsCapacity();
uint32_t newLen = JSObject::ComputeNonInlinedFastPropsCapacity(capacity, maxNonInlinedFastPropsCapacity);
properties = factory->CopyArray(arrayHandle, capacity, newLen);
}
properties->Set(thread, index, valueHandle);
objHandle->SetProperties(thread, properties);

View File

@ -862,7 +862,7 @@ HWTEST_F_L0(JSObjectTest, FastToSlow)
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
ecmaVM->SetEnableForceGC(false);
for (uint32_t i = 0; i < PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES; i++) {
for (uint32_t i = 0; i < PropertyAttributes::MAX_FAST_PROPS_CAPACITY; i++) {
number.Update(JSTaggedValue(i));
number.Update(JSTaggedValue::ToString(thread, number).GetTaggedValue());
EcmaString *newString = *factory->ConcatFromString(key, JSTaggedValue::ToString(thread, number));
@ -871,9 +871,9 @@ HWTEST_F_L0(JSObjectTest, FastToSlow)
}
ecmaVM->SetEnableForceGC(true);
EXPECT_TRUE(TaggedArray::Cast(obj1->GetProperties().GetTaggedObject())->IsDictionaryMode());
EXPECT_FALSE(TaggedArray::Cast(obj1->GetProperties().GetTaggedObject())->IsDictionaryMode());
number.Update(JSTaggedValue(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES));
number.Update(JSTaggedValue(PropertyAttributes::MAX_FAST_PROPS_CAPACITY));
number.Update(JSTaggedValue::ToString(thread, number).GetTaggedValue());
EcmaString *newString = *factory->ConcatFromString(key, JSTaggedValue::ToString(thread, number));
newkey.Update(JSTaggedValue(newString));
@ -881,9 +881,9 @@ HWTEST_F_L0(JSObjectTest, FastToSlow)
EXPECT_TRUE(TaggedArray::Cast(obj1->GetProperties().GetTaggedObject())->IsDictionaryMode());
NameDictionary *dict = NameDictionary::Cast(obj1->GetProperties().GetTaggedObject());
EXPECT_EQ(dict->EntriesCount(), static_cast<int>(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES + 1));
EXPECT_EQ(dict->EntriesCount(), static_cast<int>(PropertyAttributes::MAX_FAST_PROPS_CAPACITY + 1));
EXPECT_EQ(dict->NextEnumerationIndex(thread),
static_cast<int>(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES + 1));
static_cast<int>(PropertyAttributes::MAX_FAST_PROPS_CAPACITY + 1));
}
HWTEST_F_L0(JSObjectTest, DeleteMiddle)

View File

@ -30,7 +30,7 @@ namespace panda::ecmascript {
class TSObjLayoutInfo : private TaggedArray {
public:
static constexpr int MIN_PROPERTIES_LENGTH = JSObject::MIN_PROPERTIES_LENGTH;
static constexpr int MAX_PROPERTIES_LENGTH = PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES;
static constexpr int MAX_PROPERTIES_LENGTH = PropertyAttributes::MAX_FAST_PROPS_CAPACITY;
static constexpr int ELEMENTS_COUNT_INDEX = 0;
static constexpr int ELEMENTS_START_INDEX = 1;
static constexpr int ENTRY_SIZE = 3;

View File

@ -33,6 +33,10 @@ host_moduletest_action("builtinsobject") {
deps = []
}
host_moduletest_action("builtinsobjectaddproperty") {
deps = []
}
host_moduletest_action("builtins") {
extra_modules = [
"builtinsstring",
@ -40,11 +44,13 @@ host_moduletest_action("builtins") {
"builtinsnumber",
"builtinsregexp",
"builtinsobject",
"builtinsobjectaddproperty",
]
deps = [
":gen_builtinsir_abc",
":gen_builtinsnumber_abc",
":gen_builtinsobject_abc",
":gen_builtinsobjectaddproperty_abc",
":gen_builtinsregexp_abc",
":gen_builtinsstring_abc",
]

View File

@ -19,7 +19,7 @@
* @tc.type: FUNC
* @tc.require:
*/
print("builtins object begin");
const object1 = {
prop: 'exists'
};
@ -31,4 +31,6 @@ print(Object.hasOwn(object1, 'toString'));
// Expected output: false
print(Object.hasOwn(object1, 'undeclaredPropertyValue'));
// Expected output: false
// Expected output: false
print("builtins object end");

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 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.
*/
/*
* @tc.name:builtinsobjectaddproperty
* @tc.desc:test builtinsobject addproperty
* @tc.type: FUNC
* @tc.require:
*/
print("builtins object add property begin");
var object = {
"aa": "aa",
"bb": "bb",
"cc": "cc",
"dd": "dd",
"ee": "ee",
"ff": "ff"
}
var str = "g";
for (var i = 0; i < 1100; i++) {
object[str + i] = str;
}
print(Reflect.ownKeys(object).length);
// Expected output: 1106
print("builtins object add property end");

View File

@ -50,6 +50,11 @@ AAA
AAA
true
builtins regexp end
builtins object begin
true
false
false
builtins object end
builtins object add property begin
1106
builtins object add property end

View File

@ -576,7 +576,7 @@
* SetPropertyByName(); SetTypeArrayPropertyByName(); CallSetterHelper(); ShouldCallSetter(); IsWritable(); UpdateValueInDict();
* AddPropertyByName(); SetHasConstructorCondition(); SetHasConstructorToHClass(); SetPropertyInlinedProps(); SetOffsetFieldInPropAttr();
* SetIsInlinePropsFieldInPropAttr(); JSHClassAddProperty(); IsDictionaryMode(); SetPropertiesArray(); SetDictionaryOrderFieldInPropAttr();
* ComputePropertyCapacityInJSObj();
* ComputeNonInlinedFastPropsCapacity;
*/
/**************HandleStobjbynameImm8Id16V8****************/
{