v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
constant-array-builder.h
Go to the documentation of this file.
1// Copyright 2015 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#ifndef V8_INTERPRETER_CONSTANT_ARRAY_BUILDER_H_
6#define V8_INTERPRETER_CONSTANT_ARRAY_BUILDER_H_
7
10#include "src/handles/handles.h"
12#include "src/objects/smi.h"
14
15namespace v8 {
16namespace internal {
17
18class Isolate;
19class AstRawString;
20class AstValue;
21
22namespace interpreter {
23
24// Constant array entries that represent singletons.
25#define SINGLETON_CONSTANT_ENTRY_TYPES(V) \
26 V(AsyncIteratorSymbol, async_iterator_symbol) \
27 V(ClassFieldsSymbol, class_fields_symbol) \
28 V(EmptyObjectBoilerplateDescription, empty_object_boilerplate_description) \
29 V(EmptyArrayBoilerplateDescription, empty_array_boilerplate_description) \
30 V(EmptyFixedArray, empty_fixed_array) \
31 V(IteratorSymbol, iterator_symbol) \
32 V(InterpreterTrampolineSymbol, interpreter_trampoline_symbol) \
33 V(NaN, nan_value)
34
35// A helper class for constructing constant arrays for the
36// interpreter. Each instance of this class is intended to be used to
37// generate exactly one FixedArray of constants via the ToFixedArray
38// method.
40 public:
41 // Capacity of the 8-bit operand slice.
42 static const size_t k8BitCapacity = 1u << kBitsPerByte;
43
44 // Capacity of the 16-bit operand slice.
45 static const size_t k16BitCapacity = (1u << 2 * kBitsPerByte) - k8BitCapacity;
46
47 // Capacity of the 32-bit operand slice.
48 static const size_t k32BitCapacity =
49 kMaxUInt32 - k16BitCapacity - k8BitCapacity + 1;
50
51 explicit ConstantArrayBuilder(Zone* zone);
52
53 // Generate a fixed array of constant handles based on inserted objects.
54 template <typename IsolateT>
56 Handle<TrustedFixedArray> ToFixedArray(IsolateT* isolate);
57
58 // Returns the object, as a handle in |isolate|, that is in the constant pool
59 // array at index |index|. Returns null if there is no handle at this index.
60 // Only expected to be used in tests.
61 template <typename IsolateT>
63 MaybeHandle<Object> At(size_t index, IsolateT* isolate) const;
64
65 // Returns the number of elements in the array.
66 size_t size() const;
67
68 // Insert an object into the constants array if it is not already present.
69 // Returns the array index associated with the object.
70 size_t Insert(Tagged<Smi> smi);
71 size_t Insert(double number);
72 size_t Insert(const AstRawString* raw_string);
73 size_t Insert(const AstConsString* cons_string);
74 size_t Insert(AstBigInt bigint);
75 size_t Insert(const Scope* scope);
76#define INSERT_ENTRY(NAME, ...) size_t Insert##NAME();
78#undef INSERT_ENTRY
79
80 // Inserts an empty entry and returns the array index associated with the
81 // reservation. The entry's handle value can be inserted by calling
82 // SetDeferredAt().
83 size_t InsertDeferred();
84
85 // Inserts |size| consecutive empty entries and returns the array index
86 // associated with the first reservation. Each entry's Smi value can be
87 // inserted by calling SetJumpTableSmi().
88 size_t InsertJumpTable(size_t size);
89
90 // Sets the deferred value at |index| to |object|.
91 void SetDeferredAt(size_t index, Handle<Object> object);
92
93 // Sets the jump table entry at |index| to |smi|. Note that |index| is the
94 // constant pool index, not the switch case value.
95 void SetJumpTableSmi(size_t index, Tagged<Smi> smi);
96
97 // Creates a reserved entry in the constant pool and returns
98 // the size of the operand that'll be required to hold the entry
99 // when committed.
100 OperandSize CreateReservedEntry(
101 OperandSize minimum_operand_size = OperandSize::kNone);
102
103 // Commit reserved entry and returns the constant pool index for the
104 // SMI value.
105 size_t CommitReservedEntry(OperandSize operand_size, Tagged<Smi> value);
106
107 // Discards constant pool reservation.
108 void DiscardReservedEntry(OperandSize operand_size);
109
110 private:
111 using index_t = uint32_t;
112
113 struct ConstantArraySlice;
114
115 class Entry {
116 private:
117 enum class Tag : uint8_t;
118
119 public:
120 explicit Entry(Tagged<Smi> smi) : smi_(smi), tag_(Tag::kSmi) {}
121 explicit Entry(double heap_number)
122 : heap_number_(heap_number), tag_(Tag::kHeapNumber) {}
123 explicit Entry(const AstRawString* raw_string)
124 : raw_string_(raw_string), tag_(Tag::kRawString) {}
125 explicit Entry(const AstConsString* cons_string)
126 : cons_string_(cons_string), tag_(Tag::kConsString) {}
127 explicit Entry(AstBigInt bigint) : bigint_(bigint), tag_(Tag::kBigInt) {}
128 explicit Entry(const Scope* scope) : scope_(scope), tag_(Tag::kScope) {}
129
130#define CONSTRUCT_ENTRY(NAME, LOWER_NAME) \
131 static Entry NAME() { return Entry(Tag::k##NAME); }
133#undef CONSTRUCT_ENTRY
134
135 static Entry Deferred() { return Entry(Tag::kDeferred); }
136
138 return Entry(Tag::kUninitializedJumpTableSmi);
139 }
140
141 bool IsDeferred() const { return tag_ == Tag::kDeferred; }
142
143 bool IsJumpTableEntry() const {
144 return tag_ == Tag::kUninitializedJumpTableSmi ||
145 tag_ == Tag::kJumpTableSmi;
146 }
147
149 DCHECK_EQ(tag_, Tag::kDeferred);
150 tag_ = Tag::kHandle;
151 handle_ = handle;
152 }
153
155 DCHECK_EQ(tag_, Tag::kUninitializedJumpTableSmi);
156 tag_ = Tag::kJumpTableSmi;
157 smi_ = smi;
158 }
159
160 template <typename IsolateT>
161 Handle<Object> ToHandle(IsolateT* isolate) const;
162
163 private:
164 explicit Entry(Tag tag) : tag_(tag) {}
165
166 union {
173 const Scope* scope_;
174 };
175
176 enum class Tag : uint8_t {
177 kDeferred,
178 kHandle,
179 kSmi,
180 kRawString,
181 kConsString,
182 kHeapNumber,
183 kBigInt,
184 kScope,
185 kUninitializedJumpTableSmi,
186 kJumpTableSmi,
187#define ENTRY_TAG(NAME, ...) k##NAME,
189#undef ENTRY_TAG
190 } tag_;
191
192#if DEBUG
193 // Required by CheckAllElementsAreUnique().
194 friend struct ConstantArraySlice;
195#endif
196 };
197
198 index_t AllocateIndex(Entry constant_entry);
199 index_t AllocateIndexArray(Entry constant_entry, size_t size);
200 index_t AllocateReservedEntry(Tagged<Smi> value);
201
202 struct ConstantArraySlice final : public ZoneObject {
203 ConstantArraySlice(Zone* zone, size_t start_index, size_t capacity,
204 OperandSize operand_size);
207
208 void Reserve();
209 void Unreserve();
210 size_t Allocate(Entry entry, size_t count = 1);
211 Entry& At(size_t index);
212 const Entry& At(size_t index) const;
213
214#if DEBUG
215 template <typename IsolateT>
216 void CheckAllElementsAreUnique(IsolateT* isolate) const;
217#endif
218
219 inline size_t available() const { return capacity() - reserved() - size(); }
220 inline size_t reserved() const { return reserved_; }
221 inline size_t capacity() const { return capacity_; }
222 inline size_t size() const { return constants_.size(); }
223 inline size_t start_index() const { return start_index_; }
224 inline size_t max_index() const { return start_index_ + capacity() - 1; }
225 inline OperandSize operand_size() const { return operand_size_; }
226
227 private:
228 const size_t start_index_;
229 const size_t capacity_;
230 size_t reserved_;
233 };
234
235 ConstantArraySlice* IndexToSlice(size_t index) const;
236 ConstantArraySlice* OperandSizeToSlice(OperandSize operand_size) const;
237
238 ConstantArraySlice* idx_slice_[3];
246
247#define SINGLETON_ENTRY_FIELD(NAME, LOWER_NAME) int LOWER_NAME##_ = -1;
249#undef SINGLETON_ENTRY_FIELD
250};
251
252} // namespace interpreter
253} // namespace internal
254} // namespace v8
255
256#endif // V8_INTERPRETER_CONSTANT_ARRAY_BUILDER_H_
base::TemplateHashMapImpl< intptr_t, index_t, base::KeyEqualityMatcher< intptr_t >, ZoneAllocationPolicy > constants_map_
ZoneVector< std::pair< Tagged< Smi >, index_t > > smi_pairs_
#define INSERT_ENTRY(NAME, LOWER_NAME)
#define ENTRY_TAG(NAME,...)
#define SINGLETON_ENTRY_FIELD(NAME, LOWER_NAME)
#define SINGLETON_CONSTANT_ENTRY_TYPES(V)
#define CONSTRUCT_ENTRY(NAME, LOWER_NAME)
DeclarationScope * scope_
#define EXPORT_TEMPLATE_DECLARE(export)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
constexpr int kBitsPerByte
Definition globals.h:682
constexpr uint32_t kMaxUInt32
Definition globals.h:387
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460
ConstantArraySlice & operator=(const ConstantArraySlice &)=delete
WasmOrphanedGlobalHandle * handle_