Line data Source code
1 : // Copyright 2018 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 :
5 : #include "src/builtins/growable-fixed-array-gen.h"
6 :
7 : #include "src/compiler/code-assembler.h"
8 :
9 : namespace v8 {
10 : namespace internal {
11 :
12 392 : void GrowableFixedArray::Push(TNode<Object> const value) {
13 : TNode<IntPtrT> const length = var_length_.value();
14 : TNode<IntPtrT> const capacity = var_capacity_.value();
15 :
16 784 : Label grow(this), store(this);
17 784 : Branch(IntPtrEqual(capacity, length), &grow, &store);
18 :
19 392 : BIND(&grow);
20 : {
21 392 : var_capacity_ = NewCapacity(capacity);
22 392 : var_array_ = ResizeFixedArray(length, var_capacity_.value());
23 :
24 392 : Goto(&store);
25 : }
26 :
27 392 : BIND(&store);
28 : {
29 392 : TNode<FixedArray> const array = var_array_.value();
30 392 : StoreFixedArrayElement(array, length, value);
31 :
32 392 : var_length_ = IntPtrAdd(length, IntPtrConstant(1));
33 392 : }
34 392 : }
35 :
36 280 : TNode<JSArray> GrowableFixedArray::ToJSArray(TNode<Context> const context) {
37 : const ElementsKind kind = PACKED_ELEMENTS;
38 :
39 280 : TNode<Context> const native_context = LoadNativeContext(context);
40 280 : TNode<Map> const array_map = LoadJSArrayElementsMap(kind, native_context);
41 :
42 : // Shrink to fit if necessary.
43 : {
44 280 : Label next(this);
45 :
46 : TNode<IntPtrT> const length = var_length_.value();
47 : TNode<IntPtrT> const capacity = var_capacity_.value();
48 :
49 560 : GotoIf(WordEqual(length, capacity), &next);
50 :
51 280 : var_array_ = ResizeFixedArray(length, length);
52 : var_capacity_ = length;
53 280 : Goto(&next);
54 :
55 280 : BIND(&next);
56 : }
57 :
58 280 : TNode<Smi> const result_length = SmiTag(length());
59 : TNode<JSArray> const result = AllocateUninitializedJSArrayWithoutElements(
60 280 : array_map, result_length, nullptr);
61 :
62 280 : StoreObjectField(result, JSObject::kElementsOffset, var_array_.value());
63 :
64 280 : return result;
65 : }
66 :
67 392 : TNode<IntPtrT> GrowableFixedArray::NewCapacity(
68 : TNode<IntPtrT> current_capacity) {
69 : CSA_ASSERT(this,
70 : IntPtrGreaterThanOrEqual(current_capacity, IntPtrConstant(0)));
71 :
72 : // Growth rate is analog to JSObject::NewElementsCapacity:
73 : // new_capacity = (current_capacity + (current_capacity >> 1)) + 16.
74 :
75 : TNode<IntPtrT> const new_capacity =
76 : IntPtrAdd(IntPtrAdd(current_capacity, WordShr(current_capacity, 1)),
77 392 : IntPtrConstant(16));
78 :
79 392 : return new_capacity;
80 : }
81 :
82 672 : TNode<FixedArray> GrowableFixedArray::ResizeFixedArray(
83 : TNode<IntPtrT> const element_count, TNode<IntPtrT> const new_capacity) {
84 : CSA_ASSERT(this, IntPtrGreaterThanOrEqual(element_count, IntPtrConstant(0)));
85 : CSA_ASSERT(this, IntPtrGreaterThanOrEqual(new_capacity, IntPtrConstant(0)));
86 : CSA_ASSERT(this, IntPtrGreaterThanOrEqual(new_capacity, element_count));
87 :
88 : TNode<FixedArray> const from_array = var_array_.value();
89 :
90 : CodeStubAssembler::ExtractFixedArrayFlags flags;
91 : flags |= CodeStubAssembler::ExtractFixedArrayFlag::kFixedArrays;
92 672 : TNode<FixedArray> to_array = CAST(ExtractFixedArray(
93 : from_array, nullptr, element_count, new_capacity, flags));
94 :
95 672 : return to_array;
96 : }
97 :
98 : } // namespace internal
99 94089 : } // namespace v8
|