V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
growable-fixed-array-gen.cc
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 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  Label grow(this), store(this);
17  Branch(IntPtrEqual(capacity, length), &grow, &store);
18 
19  BIND(&grow);
20  {
21  var_capacity_ = NewCapacity(capacity);
22  var_array_ = ResizeFixedArray(length, var_capacity_.value());
23 
24  Goto(&store);
25  }
26 
27  BIND(&store);
28  {
29  TNode<FixedArray> const array = var_array_.value();
30  StoreFixedArrayElement(array, length, value);
31 
32  var_length_ = IntPtrAdd(length, IntPtrConstant(1));
33  }
34 }
35 
36 TNode<JSArray> GrowableFixedArray::ToJSArray(TNode<Context> const context) {
37  const ElementsKind kind = PACKED_ELEMENTS;
38 
39  TNode<Context> const native_context = LoadNativeContext(context);
40  TNode<Map> const array_map = LoadJSArrayElementsMap(kind, native_context);
41 
42  // Shrink to fit if necessary.
43  {
44  Label next(this);
45 
46  TNode<IntPtrT> const length = var_length_.value();
47  TNode<IntPtrT> const capacity = var_capacity_.value();
48 
49  GotoIf(WordEqual(length, capacity), &next);
50 
51  var_array_ = ResizeFixedArray(length, length);
52  var_capacity_ = length;
53  Goto(&next);
54 
55  BIND(&next);
56  }
57 
58  TNode<Smi> const result_length = SmiTag(length());
59  TNode<JSArray> const result = AllocateUninitializedJSArrayWithoutElements(
60  array_map, result_length, nullptr);
61 
62  StoreObjectField(result, JSObject::kElementsOffset, var_array_.value());
63 
64  return result;
65 }
66 
67 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  IntPtrConstant(16));
78 
79  return new_capacity;
80 }
81 
82 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  TNode<FixedArray> to_array = CAST(ExtractFixedArray(
93  from_array, nullptr, element_count, new_capacity, flags));
94 
95  return to_array;
96 }
97 
98 } // namespace internal
99 } // namespace v8
Definition: libplatform.h:13