// The JSArray describes JavaScript Arrays // Such an array can be in one of two modes: // - fast, backing storage is a FixedArray and length <= elements.length(); // Please note: push and pop can be used to grow and shrink the array. // - slow, backing storage is a HashTable with numbers as keys. classJSArray : public TorqueGeneratedJSArray<JSArray, JSObject> { public: // [length]: The length property. DECL_ACCESSORS(length, Tagged<Object>) DECL_RELAXED_GETTER(length, Tagged<Object>) // ... }
// v8/src/objects/js-array.h // Number of element slots to pre-allocate for an empty array. // 声明一个新的空数组时,会预分配长度为4的内存空间 staticconstint kPreallocatedArrayElements = 4;
// v8/src/objects/js-objects.h staticconstuint32_t kMinAddedElementsCapacity = 16; // Computes the new capacity when expanding the elements of a JSObject. // 计算扩容后的数组长度 staticuint32_tNewElementsCapacity(uint32_t old_capacity){ // (old_capacity + 50%) + kMinAddedElementsCapacity // 扩容公式:old_capacity*1.5 + 16 return old_capacity + (old_capacity >> 1) + kMinAddedElementsCapacity; }
if (2 * length + JSObject::kMinAddedElementsCapacity <= capacity) { // If more than half the elements won't be used, trim the array. // Do not trim from short arrays to prevent frequent trimming on // repeated pop operations. // Leave some space to allow for subsequent push operations. uint32_t new_capacity = length + 1 == old_length ? (capacity + length) / 2 : length; DCHECK_LT(new_capacity, capacity); isolate->heap()->RightTrimArray(BackingStore::cast(*backing_store), new_capacity, capacity); // Fill the non-trimmed elements with holes. BackingStore::cast(*backing_store) ->FillWithHoles(length, std::min(old_length, new_capacity)); }
// If the fast-case backing storage takes up much more memory than a dictionary // backing storage would, the object should have slow elements. // static staticinlineboolShouldConvertToSlowElements(uint32_t used_elements, uint32_t new_capacity){ uint32_t size_threshold = NumberDictionary::kPreferFastElementsSizeFactor * NumberDictionary::ComputeCapacity(used_elements) * NumberDictionary::kEntrySize; return size_threshold <= new_capacity; }