v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
fixed-array.cc
Go to the documentation of this file.
1// Copyright 2023 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
8
9namespace v8 {
10namespace internal {
11
16
18 return map() == GetReadOnlyRoots().fixed_cow_array_map();
19}
20
21template <template <typename> typename HandleType>
22 requires(
23 std::is_convertible_v<HandleType<FixedArray>, DirectHandle<FixedArray>>)
24HandleType<FixedArray> FixedArray::SetAndGrow(Isolate* isolate,
25 HandleType<FixedArray> array,
26 int index,
28 int len = array->length();
29 if (index >= len) {
30 int new_capacity = FixedArray::NewCapacityForIndex(index, len);
31 array = Cast<FixedArray>(FixedArray::Resize(isolate, array, new_capacity));
32 // TODO(jgruber): This is somewhat subtle - other FixedArray methods
33 // use `undefined` as a filler. Make this more explicit.
34 array->FillWithHoles(len, new_capacity);
35 }
36
37 array->set(index, *value);
38 return array;
39}
40
42 Isolate* isolate, DirectHandle<FixedArray> array, int index,
45 Isolate* isolate, IndirectHandle<FixedArray> array, int index,
47
48void FixedArray::RightTrim(Isolate* isolate, int new_capacity) {
49 DCHECK_NE(map(), ReadOnlyRoots{isolate}.fixed_cow_array_map());
50 Super::RightTrim(isolate, new_capacity);
51}
52
53template <template <typename> typename HandleType>
54 requires(
55 std::is_convertible_v<HandleType<FixedArray>, DirectHandle<FixedArray>>)
56HandleType<FixedArray> FixedArray::RightTrimOrEmpty(
57 Isolate* isolate, HandleType<FixedArray> array, int new_length) {
58 if (new_length == 0) {
59 return isolate->factory()->empty_fixed_array();
60 }
61 array->RightTrim(isolate, new_length);
62 return array;
63}
64
67 Isolate* isolate, DirectHandle<FixedArray> array, int new_length);
70 Isolate* isolate, IndirectHandle<FixedArray> array, int new_length);
71
72// static
75 Tagged<Smi> obj,
76 AllocationType allocation) {
77 int length = array->length();
78 int new_length = length + 1;
79 array = EnsureSpace(isolate, array, new_length, allocation);
80 DCHECK_EQ(array->length(), length);
81
83 array->set(length, obj, SKIP_WRITE_BARRIER);
84 array->set_length(new_length);
85 return array;
86}
87
88// static
92 AllocationType allocation) {
93 int length = array->length();
94 int new_length = length + 1;
95 array = EnsureSpace(isolate, array, new_length, allocation);
96 DCHECK_EQ(array->length(), length);
97
99 array->set(length, *obj);
100 array->set_length(new_length);
101 return array;
102}
103
104// static
109 AllocationType allocation) {
110 int length = array->length();
111 int new_length = length + 2;
112 array = EnsureSpace(isolate, array, new_length, allocation);
113 DCHECK_EQ(array->length(), length);
114
116 array->set(length + 0, *obj0);
117 array->set(length + 1, *obj1);
118 array->set_length(new_length);
119 return array;
120}
121
122// static
125 AllocationType allocation) {
126 int length = array->length();
127 if (length == 0) return isolate->factory()->empty_fixed_array();
128
130 FixedArray::New(isolate, length, allocation);
132 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
133 ObjectSlot dst_slot(result->RawFieldOfElementAt(0));
134 ObjectSlot src_slot(array->RawFieldOfElementAt(0));
135 isolate->heap()->CopyRange(*result, dst_slot, src_slot, length, mode);
136 return result;
137}
138
139void ArrayList::RightTrim(Isolate* isolate, int new_capacity) {
140 Super::RightTrim(isolate, new_capacity);
141 if (new_capacity < length()) set_length(new_capacity);
142}
143
144// static
147 int length,
148 AllocationType allocation) {
149 DCHECK_LT(0, length);
150 int old_capacity = array->capacity();
151 if (old_capacity >= length) return array;
152
153 int old_length = array->length();
154 // Ensure calculation matches CodeStubAssembler::ArrayListEnsureSpace.
155 int new_capacity = length + std::max(length / 2, 2);
156 DirectHandle<ArrayList> new_array =
157 ArrayList::New(isolate, new_capacity, allocation);
159 new_array->set_length(old_length);
160 WriteBarrierMode mode = new_array->GetWriteBarrierMode(no_gc);
161 CopyElements(isolate, *new_array, 0, *array, 0, old_length, mode);
162 return new_array;
163}
164
165// static
169 int length = array->length();
170 array = EnsureSpace(isolate, array, length + 1);
171 {
173 Tagged<WeakArrayList> raw = *array;
174 // Reload length; GC might have removed elements from the array.
175 length = raw->length();
176 raw->Set(length, *value);
177 raw->set_length(length + 1);
178 }
179 return array;
180}
181
185 Tagged<Smi> value2) {
186 int length = array->length();
187 array = EnsureSpace(isolate, array, length + 2);
188 {
190 Tagged<WeakArrayList> raw = *array;
191 // Reload length; GC might have removed elements from the array.
192 length = array->length();
193 raw->Set(length, *value1);
194 raw->Set(length + 1, value2);
195 raw->set_length(length + 2);
196 }
197 return array;
198}
199
200// static
202 Isolate* isolate, DirectHandle<WeakArrayList> array,
203 MaybeObjectDirectHandle value, AllocationType allocation) {
204 int length = 0;
205 int new_length = 0;
206 {
208 Tagged<WeakArrayList> raw = *array;
209 length = raw->length();
210
211 if (length < raw->capacity()) {
212 raw->Set(length, *value);
213 raw->set_length(length + 1);
214 return array;
215 }
216
217 // Not enough space in the array left, either grow, shrink or
218 // compact the array.
219 new_length = raw->CountLiveElements() + 1;
220 }
221
222 bool shrink = new_length < length / 4;
223 bool grow = 3 * (length / 4) < new_length;
224
225 if (shrink || grow) {
226 // Grow or shrink array and compact out-of-place.
227 int new_capacity = CapacityForLength(new_length);
228 array = isolate->factory()->CompactWeakArrayList(array, new_capacity,
229 allocation);
230
231 } else {
232 // Perform compaction in the current array.
233 array->Compact(isolate);
234 }
235
236 // Now append value to the array, there should always be enough space now.
237 DCHECK_LT(array->length(), array->capacity());
238
239 {
241 Tagged<WeakArrayList> raw = *array;
242 // Reload length, allocation might have killed some weak refs.
243 int index = raw->length();
244 raw->Set(index, *value);
245 raw->set_length(index + 1);
246 }
247 return array;
248}
249
252 int length = this->length();
253 int new_length = 0;
254
255 for (int i = 0; i < length; i++) {
256 Tagged<MaybeObject> value = Get(isolate, i);
257
258 if (!value.IsCleared()) {
259 if (new_length != i) {
260 Set(new_length, value);
261 }
262 ++new_length;
263 }
264 }
265
266 set_length(new_length);
267}
268
269bool WeakArrayList::IsFull() const { return length() == capacity(); }
270
271// static
274 int length,
275 AllocationType allocation) {
276 int capacity = array->capacity();
277 if (capacity < length) {
278 int grow_by = CapacityForLength(length) - capacity;
279 array = isolate->factory()->CopyWeakArrayListAndGrow(array, grow_by,
280 allocation);
281 }
282 return array;
283}
284
286 int live_weak_references = 0;
287 for (int i = 0; i < length(); i++) {
288 if (Get(i).IsWeak()) {
289 ++live_weak_references;
290 }
291 }
292 return live_weak_references;
293}
294
296 int non_cleared_objects = 0;
297 for (int i = 0; i < length(); i++) {
298 if (!Get(i).IsCleared()) {
299 ++non_cleared_objects;
300 }
301 }
302 return non_cleared_objects;
303}
304
306 int last_index = length() - 1;
307 // Optimize for the most recently added element to be removed again.
308 for (int i = last_index; i >= 0; --i) {
309 if (Get(i) != *value) continue;
310 // Move the last element into this slot (or no-op, if this is the last
311 // slot).
312 Set(i, Get(last_index));
313 Set(last_index, ClearedValue(GetIsolate()));
314 set_length(last_index);
315 return true;
316 }
317 return false;
318}
319
321 for (int i = 0; i < length(); ++i) {
322 if (Get(i) == value) return true;
323 }
324 return false;
325}
326
327} // namespace internal
328} // namespace v8
Builtins::Kind kind
Definition builtins.cc:40
static V8_EXPORT_PRIVATE DirectHandle< ArrayList > Add(Isolate *isolate, DirectHandle< ArrayList > array, Tagged< Smi > obj, AllocationType allocation=AllocationType::kYoung)
static V8_EXPORT_PRIVATE DirectHandle< FixedArray > ToFixedArray(Isolate *isolate, DirectHandle< ArrayList > array, AllocationType allocation=AllocationType::kYoung)
static DirectHandle< ArrayList > EnsureSpace(Isolate *isolate, DirectHandle< ArrayList > array, int length, AllocationType allocation=AllocationType::kYoung)
void RightTrim(Isolate *isolate, int new_capacity)
static DirectHandle< ArrayList > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
V8_EXPORT_PRIVATE bool IsCowArray() const
static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind)
static constexpr int kHeaderSize
V8_EXPORT_PRIVATE void RightTrim(Isolate *isolate, int new_capacity)
static HandleType< FixedArray > RightTrimOrEmpty(Isolate *isolate, HandleType< FixedArray > array, int new_length)
static Handle< FixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
static V8_EXPORT_PRIVATE HandleType< FixedArray > SetAndGrow(Isolate *isolate, HandleType< FixedArray > array, int index, DirectHandle< Object > value)
static Handle< FixedArray > Resize(Isolate *isolate, DirectHandle< FixedArray > xs, int new_capacity, AllocationType allocation=AllocationType::kYoung, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
static void CopyElements(Isolate *isolate, Tagged< ArrayList > dst, int dst_index, Tagged< ArrayList > src, int src_index, int len, WriteBarrierMode mode=kDefaultMode)
static constexpr int NewCapacityForIndex(int index, int old_capacity)
V8_EXPORT_PRIVATE bool Contains(Tagged< MaybeObject > value)
static Handle< WeakArrayList > EnsureSpace(Isolate *isolate, Handle< WeakArrayList > array, int length, AllocationType allocation=AllocationType::kYoung)
V8_EXPORT_PRIVATE bool IsFull() const
V8_EXPORT_PRIVATE bool RemoveOne(MaybeObjectDirectHandle value)
static V8_WARN_UNUSED_RESULT DirectHandle< WeakArrayList > Append(Isolate *isolate, DirectHandle< WeakArrayList > array, MaybeObjectDirectHandle value, AllocationType allocation=AllocationType::kYoung)
void Set(int index, Tagged< MaybeObject > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
NEVER_READ_ONLY_SPACE static V8_EXPORT_PRIVATE Handle< WeakArrayList > AddToEnd(Isolate *isolate, Handle< WeakArrayList > array, MaybeObjectDirectHandle value)
static constexpr int CapacityForLength(int length)
V8_EXPORT_PRIVATE void Compact(Isolate *isolate)
Tagged< MaybeObject > Get(int index) const
#define EXPORT_TEMPLATE_DEFINE(export)
std::map< const std::string, const std::string > map
ZoneVector< RpoNumber > & result
constexpr int kMaxRegularHeapObjectSize
Definition globals.h:680
@ SKIP_WRITE_BARRIER
Definition objects.h:52
ReadOnlyRoots GetReadOnlyRoots()
Definition roots-inl.h:86
V8_INLINE constexpr bool IsWeak(TaggedImpl< HeapObjectReferenceType::WEAK, StorageType > obj)
Definition objects.h:673
constexpr int ElementsKindToShiftSize(ElementsKind elements_kind)
Tagged< ClearedWeakValue > ClearedValue(PtrComprCageBase cage_base)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460