Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
object_pool_builder.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
6#define RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
7
8#include "platform/assert.h"
9#include "platform/globals.h"
10#include "vm/bitfield.h"
11#include "vm/hash_map.h"
12
13namespace dart {
14
15class Object;
16
17namespace compiler {
18
19class ExternalLabel;
20
21bool IsSameObject(const Object& a, const Object& b);
22
28
31
32 // This should never be snapshot. Typically an memory address in the current
33 // process.
35
36 // Set the value to StubCode::CallBootstrapNative() on snapshot reading.
38
39 // Only used in AOT. Every switchable call site will put (`ic_data`,
40 // [kTaggedObject] `code`) into the object pool. The `code` is initialized
41 // (at AOT compile-time) to be [StubCode::SwitchableCallMiss].
42 //
43 // The extra indirection via the `code` object is removed by storing
44 // (`ic_data`, [kImmediate] `entrypoint`) in the object pool instead on
45 // deserialization.
47
48 // Set the value to 0 on snapshot writing.
50 };
51
52 enum EntryType {
56
57 // Used only during object pool building to find duplicates. Become multiple
58 // kImmediate in the final pool.
59#if defined(TARGET_ARCH_IS_32_BIT)
60 kImmediate64,
61#endif
63 };
64
69
78
99#if defined(ARCH_IS_32_BIT)
101 : imm64_(value),
103 equivalence_() {}
104#endif
111
113
115
119
120 union {
121 const Object* obj_;
123 uint64_t imm64_;
125 };
126 uint8_t entry_bits_;
128};
129
130// Pair type parameter for DirectChainedHashMap used for the constant pool.
132 public:
133 // Typedefs needed for the DirectChainedHashMap template.
135 typedef intptr_t Value;
137
138 static constexpr intptr_t kNoIndex = -1;
139
141 : key_(reinterpret_cast<uword>(nullptr),
142 ObjectPoolBuilderEntry::kTaggedObject,
143 ObjectPoolBuilderEntry::kPatchable),
144 value_(kNoIndex) {}
145
146 ObjIndexPair(Key key, Value value) : value_(value) {
147 key_.entry_bits_ = key.entry_bits_;
149 key_.obj_ = key.obj_;
150 key_.equivalence_ = key.equivalence_;
151 } else if (key.type() == ObjectPoolBuilderEntry::kImmediate128) {
152 key_.imm128_ = key.imm128_;
153#if defined(TARGET_ARCH_IS_32_BIT)
154 } else if (key.type() == ObjectPoolBuilderEntry::kImmediate64) {
155 key_.imm64_ = key.imm64_;
156#endif
157 } else {
158 key_.imm_ = key.imm_;
159 }
160 }
161
162 static Key KeyOf(Pair kv) { return kv.key_; }
163
164 static Value ValueOf(Pair kv) { return kv.value_; }
165
166 static uword Hash(Key key);
167
168 static inline bool IsKeyEqual(Pair kv, Key key) {
169 if (kv.key_.entry_bits_ != key.entry_bits_) return false;
171 return IsSameObject(*kv.key_.obj_, *key.obj_) &&
172 IsSameObject(*kv.key_.equivalence_, *key.equivalence_);
173 }
175 return (kv.key_.imm128_.int_storage[0] == key.imm128_.int_storage[0]) &&
176 (kv.key_.imm128_.int_storage[1] == key.imm128_.int_storage[1]) &&
177 (kv.key_.imm128_.int_storage[2] == key.imm128_.int_storage[2]) &&
178 (kv.key_.imm128_.int_storage[3] == key.imm128_.int_storage[3]);
179 }
180#if defined(TARGET_ARCH_IS_32_BIT)
181 if (kv.key_.type() == ObjectPoolBuilderEntry::kImmediate64) {
182 return kv.key_.imm64_ == key.imm64_;
183 }
184#endif
185 return kv.key_.imm_ == key.imm_;
186 }
187
188 private:
189 Key key_;
190 Value value_;
191};
192
194 public:
195 // When generating AOT code in the bare instructions mode we might use a two
196 // stage process of forming the pool - first accumulate objects in the
197 // intermediary pool and then commit them into the global pool at the
198 // end of a successful compilation. Here [parent] is the pool into which
199 // we are going to commit objects.
200 // See PrecompileParsedFunctionHelper::Compile for more information.
201 explicit ObjectPoolBuilder(ObjectPoolBuilder* parent = nullptr)
202 : parent_(parent),
203 base_index_(parent != nullptr ? parent->CurrentLength() : 0),
204 zone_(nullptr) {}
205
207 if (zone_ != nullptr) {
208 Reset();
209 zone_ = nullptr;
210 }
211 }
212
213 // Clears all existing entries in this object pool builder.
214 //
215 // Note: Any code which has been compiled via this builder might use offsets
216 // into the pool which are not correct anymore.
217 void Reset();
218
219 // Initialize this object pool builder with a [zone].
220 //
221 // Any objects added later on will be referenced using handles from [zone].
223 ASSERT(object_pool_.length() == 0);
224 ASSERT(zone_ == nullptr && zone != nullptr);
225 zone_ = zone;
226 }
227
228 intptr_t AddObject(
229 const Object& obj,
234 intptr_t AddImmediate(
235 uword imm,
240 intptr_t AddImmediate64(uint64_t imm);
241 intptr_t AddImmediate128(simd128_value_t imm);
242
243 intptr_t FindObject(
244 const Object& obj,
249 intptr_t FindObject(const Object& obj, const Object& equivalence);
250 intptr_t FindImmediate(uword imm);
251 intptr_t FindImmediate64(uint64_t imm);
252 intptr_t FindImmediate128(simd128_value_t imm);
253 intptr_t FindNativeFunction(const ExternalLabel* label,
255
256 intptr_t CurrentLength() const {
257 return object_pool_.length() + used_from_parent_.length();
258 }
260 if (i < used_from_parent_.length()) {
261 return parent_->EntryAt(used_from_parent_[i]);
262 }
263 return object_pool_[i - used_from_parent_.length()];
264 }
265 const ObjectPoolBuilderEntry& EntryAt(intptr_t i) const {
266 if (i < used_from_parent_.length()) {
267 return parent_->EntryAt(used_from_parent_[i]);
268 }
269 return object_pool_[i - used_from_parent_.length()];
270 }
271
272 intptr_t AddObject(ObjectPoolBuilderEntry entry);
273
274 // Try appending all entries from this pool into the parent pool.
275 // This might fail if parent pool was modified invalidating indices which
276 // we produced. In this case this function will return false.
277 bool TryCommitToParent();
278
279 bool HasParent() const { return parent_ != nullptr; }
280
281 private:
282 intptr_t FindObject(ObjectPoolBuilderEntry entry);
283
284 // Parent pool into which all entries from this pool will be added at
285 // the end of the successful compilation.
286 ObjectPoolBuilder* const parent_;
287
288 // Base index at which entries will be inserted into the parent pool.
289 // Should be equal to parent_->CurrentLength() - but is cached here
290 // to detect cases when parent pool grows due to nested code generations.
291 const intptr_t base_index_;
292
293 GrowableArray<intptr_t> used_from_parent_;
294
295 // Objects and jump targets.
297
298 // Hashmap for fast lookup in object pool.
299 DirectChainedHashMap<ObjIndexPair> object_pool_index_table_;
300
301 // The zone used for allocating the handles we keep in the map and array (or
302 // nullptr, in which case allocations happen using the zone active at the
303 // point of insertion).
304 Zone* zone_;
305};
306
307} // namespace compiler
308
309} // namespace dart
310
311#endif // RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
TArray< uint32_t > Key
intptr_t length() const
static constexpr T decode(S value)
Definition bitfield.h:173
static constexpr S encode(T value)
Definition bitfield.h:167
static bool IsKeyEqual(Pair kv, Key key)
static constexpr intptr_t kNoIndex
static uword Hash(Key key)
ObjIndexPair(Key key, Value value)
intptr_t AddObject(const Object &obj, ObjectPoolBuilderEntry::Patchability patchable=ObjectPoolBuilderEntry::kNotPatchable, ObjectPoolBuilderEntry::SnapshotBehavior snapshot_behavior=ObjectPoolBuilderEntry::kSnapshotable)
intptr_t AddImmediate(uword imm, ObjectPoolBuilderEntry::Patchability patchable=ObjectPoolBuilderEntry::kNotPatchable, ObjectPoolBuilderEntry::SnapshotBehavior snapshotability=ObjectPoolBuilderEntry::kSnapshotable)
intptr_t AddImmediate64(uint64_t imm)
intptr_t FindImmediate128(simd128_value_t imm)
intptr_t FindObject(const Object &obj, ObjectPoolBuilderEntry::Patchability patchable=ObjectPoolBuilderEntry::kNotPatchable, ObjectPoolBuilderEntry::SnapshotBehavior snapshot_behavior=ObjectPoolBuilderEntry::kSnapshotable)
const ObjectPoolBuilderEntry & EntryAt(intptr_t i) const
intptr_t FindImmediate64(uint64_t imm)
ObjectPoolBuilderEntry & EntryAt(intptr_t i)
intptr_t FindNativeFunction(const ExternalLabel *label, ObjectPoolBuilderEntry::Patchability patchable)
ObjectPoolBuilder(ObjectPoolBuilder *parent=nullptr)
intptr_t AddImmediate128(simd128_value_t imm)
#define ASSERT(E)
static bool b
struct MyStruct a[10]
uint8_t value
bool IsSameObject(const Object &a, const Object &b)
uintptr_t uword
Definition globals.h:501
ObjectPoolBuilderEntry(uword value, EntryType info, Patchability patchable, SnapshotBehavior snapshot_behavior=SnapshotBehavior::kSnapshotable)
static uint8_t EncodeTraits(EntryType type, Patchability patchable, SnapshotBehavior snapshot_behavior=SnapshotBehavior::kSnapshotable)
ObjectPoolBuilderEntry(const Object *obj, Patchability patchable, SnapshotBehavior snapshot_behavior=kSnapshotable)
ObjectPoolBuilderEntry(const Object *obj, const Object *eqv, Patchability patchable, SnapshotBehavior snapshot_behavior=kSnapshotable)
ObjectPoolBuilderEntry(simd128_value_t value, EntryType info, Patchability patchable)
int32_t int_storage[4]
Definition globals.h:148