OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_ASSEMBLER_H_ | 5 #ifndef RUNTIME_VM_ASSEMBLER_H_ |
6 #define RUNTIME_VM_ASSEMBLER_H_ | 6 #define RUNTIME_VM_ASSEMBLER_H_ |
7 | 7 |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/allocation.h" | 9 #include "vm/allocation.h" |
10 #include "vm/globals.h" | 10 #include "vm/globals.h" |
11 #include "vm/growable_array.h" | 11 #include "vm/growable_array.h" |
12 #include "vm/hash_map.h" | 12 #include "vm/hash_map.h" |
13 #include "vm/object.h" | 13 #include "vm/object.h" |
14 | 14 |
15 namespace dart { | 15 namespace dart { |
16 | 16 |
17 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) | 17 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) |
18 DECLARE_FLAG(bool, use_far_branches); | 18 DECLARE_FLAG(bool, use_far_branches); |
19 #endif | 19 #endif |
20 | 20 |
21 // Forward declarations. | 21 // Forward declarations. |
22 class Assembler; | 22 class Assembler; |
23 class AssemblerFixup; | 23 class AssemblerFixup; |
24 class AssemblerBuffer; | 24 class AssemblerBuffer; |
25 class MemoryRegion; | 25 class MemoryRegion; |
26 | 26 |
27 | |
28 // External labels keep a function pointer to allow them | 27 // External labels keep a function pointer to allow them |
29 // to be called from code generated by the assembler. | 28 // to be called from code generated by the assembler. |
30 class ExternalLabel : public ValueObject { | 29 class ExternalLabel : public ValueObject { |
31 public: | 30 public: |
32 explicit ExternalLabel(uword address) : address_(address) {} | 31 explicit ExternalLabel(uword address) : address_(address) {} |
33 | 32 |
34 bool is_resolved() const { return address_ != 0; } | 33 bool is_resolved() const { return address_ != 0; } |
35 uword address() const { | 34 uword address() const { |
36 ASSERT(is_resolved()); | 35 ASSERT(is_resolved()); |
37 return address_; | 36 return address_; |
38 } | 37 } |
39 | 38 |
40 private: | 39 private: |
41 const uword address_; | 40 const uword address_; |
42 }; | 41 }; |
43 | 42 |
44 | |
45 // Assembler fixups are positions in generated code that hold relocation | 43 // Assembler fixups are positions in generated code that hold relocation |
46 // information that needs to be processed before finalizing the code | 44 // information that needs to be processed before finalizing the code |
47 // into executable memory. | 45 // into executable memory. |
48 class AssemblerFixup : public ZoneAllocated { | 46 class AssemblerFixup : public ZoneAllocated { |
49 public: | 47 public: |
50 virtual void Process(const MemoryRegion& region, intptr_t position) = 0; | 48 virtual void Process(const MemoryRegion& region, intptr_t position) = 0; |
51 | 49 |
52 virtual bool IsPointerOffset() const = 0; | 50 virtual bool IsPointerOffset() const = 0; |
53 | 51 |
54 // It would be ideal if the destructor method could be made private, | 52 // It would be ideal if the destructor method could be made private, |
55 // but the g++ compiler complains when this is subclassed. | 53 // but the g++ compiler complains when this is subclassed. |
56 virtual ~AssemblerFixup() { UNREACHABLE(); } | 54 virtual ~AssemblerFixup() { UNREACHABLE(); } |
57 | 55 |
58 private: | 56 private: |
59 AssemblerFixup* previous_; | 57 AssemblerFixup* previous_; |
60 intptr_t position_; | 58 intptr_t position_; |
61 | 59 |
62 AssemblerFixup* previous() const { return previous_; } | 60 AssemblerFixup* previous() const { return previous_; } |
63 void set_previous(AssemblerFixup* previous) { previous_ = previous; } | 61 void set_previous(AssemblerFixup* previous) { previous_ = previous; } |
64 | 62 |
65 intptr_t position() const { return position_; } | 63 intptr_t position() const { return position_; } |
66 void set_position(intptr_t position) { position_ = position; } | 64 void set_position(intptr_t position) { position_ = position; } |
67 | 65 |
68 friend class AssemblerBuffer; | 66 friend class AssemblerBuffer; |
69 }; | 67 }; |
70 | 68 |
71 | |
72 // Assembler buffers are used to emit binary code. They grow on demand. | 69 // Assembler buffers are used to emit binary code. They grow on demand. |
73 class AssemblerBuffer : public ValueObject { | 70 class AssemblerBuffer : public ValueObject { |
74 public: | 71 public: |
75 AssemblerBuffer(); | 72 AssemblerBuffer(); |
76 ~AssemblerBuffer(); | 73 ~AssemblerBuffer(); |
77 | 74 |
78 // Basic support for emitting, loading, and storing. | 75 // Basic support for emitting, loading, and storing. |
79 template <typename T> | 76 template <typename T> |
80 void Emit(T value) { | 77 void Emit(T value) { |
81 ASSERT(HasEnsuredCapacity()); | 78 ASSERT(HasEnsuredCapacity()); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 // description of kMinimumGap for the reasoning behind the value. | 203 // description of kMinimumGap for the reasoning behind the value. |
207 static uword ComputeLimit(uword data, intptr_t capacity) { | 204 static uword ComputeLimit(uword data, intptr_t capacity) { |
208 return data + capacity - kMinimumGap; | 205 return data + capacity - kMinimumGap; |
209 } | 206 } |
210 | 207 |
211 void ExtendCapacity(); | 208 void ExtendCapacity(); |
212 | 209 |
213 friend class AssemblerFixup; | 210 friend class AssemblerFixup; |
214 }; | 211 }; |
215 | 212 |
216 | |
217 struct ObjectPoolWrapperEntry { | 213 struct ObjectPoolWrapperEntry { |
218 ObjectPoolWrapperEntry() : raw_value_(), type_(), equivalence_() {} | 214 ObjectPoolWrapperEntry() : raw_value_(), type_(), equivalence_() {} |
219 explicit ObjectPoolWrapperEntry(const Object* obj) | 215 explicit ObjectPoolWrapperEntry(const Object* obj) |
220 : obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(obj) {} | 216 : obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(obj) {} |
221 explicit ObjectPoolWrapperEntry(const Object* obj, const Object* eqv) | 217 explicit ObjectPoolWrapperEntry(const Object* obj, const Object* eqv) |
222 : obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(eqv) {} | 218 : obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(eqv) {} |
223 ObjectPoolWrapperEntry(uword value, ObjectPool::EntryType info) | 219 ObjectPoolWrapperEntry(uword value, ObjectPool::EntryType info) |
224 : raw_value_(value), type_(info), equivalence_() {} | 220 : raw_value_(value), type_(info), equivalence_() {} |
225 | 221 |
226 union { | 222 union { |
227 const Object* obj_; | 223 const Object* obj_; |
228 uword raw_value_; | 224 uword raw_value_; |
229 }; | 225 }; |
230 ObjectPool::EntryType type_; | 226 ObjectPool::EntryType type_; |
231 const Object* equivalence_; | 227 const Object* equivalence_; |
232 }; | 228 }; |
233 | 229 |
234 | |
235 // Pair type parameter for DirectChainedHashMap used for the constant pool. | 230 // Pair type parameter for DirectChainedHashMap used for the constant pool. |
236 class ObjIndexPair { | 231 class ObjIndexPair { |
237 public: | 232 public: |
238 // Typedefs needed for the DirectChainedHashMap template. | 233 // Typedefs needed for the DirectChainedHashMap template. |
239 typedef ObjectPoolWrapperEntry Key; | 234 typedef ObjectPoolWrapperEntry Key; |
240 typedef intptr_t Value; | 235 typedef intptr_t Value; |
241 typedef ObjIndexPair Pair; | 236 typedef ObjIndexPair Pair; |
242 | 237 |
243 static const intptr_t kNoIndex = -1; | 238 static const intptr_t kNoIndex = -1; |
244 | 239 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 (kv.key_.equivalence_->raw() == key.equivalence_->raw()); | 277 (kv.key_.equivalence_->raw() == key.equivalence_->raw()); |
283 } | 278 } |
284 return kv.key_.raw_value_ == key.raw_value_; | 279 return kv.key_.raw_value_ == key.raw_value_; |
285 } | 280 } |
286 | 281 |
287 private: | 282 private: |
288 Key key_; | 283 Key key_; |
289 Value value_; | 284 Value value_; |
290 }; | 285 }; |
291 | 286 |
292 | |
293 enum Patchability { | 287 enum Patchability { |
294 kPatchable, | 288 kPatchable, |
295 kNotPatchable, | 289 kNotPatchable, |
296 }; | 290 }; |
297 | 291 |
298 | |
299 class ObjectPoolWrapper : public ValueObject { | 292 class ObjectPoolWrapper : public ValueObject { |
300 public: | 293 public: |
301 intptr_t AddObject(const Object& obj, Patchability patchable = kNotPatchable); | 294 intptr_t AddObject(const Object& obj, Patchability patchable = kNotPatchable); |
302 intptr_t AddImmediate(uword imm); | 295 intptr_t AddImmediate(uword imm); |
303 | 296 |
304 intptr_t FindObject(const Object& obj, | 297 intptr_t FindObject(const Object& obj, |
305 Patchability patchable = kNotPatchable); | 298 Patchability patchable = kNotPatchable); |
306 intptr_t FindObject(const Object& obj, const Object& equivalence); | 299 intptr_t FindObject(const Object& obj, const Object& equivalence); |
307 intptr_t FindImmediate(uword imm); | 300 intptr_t FindImmediate(uword imm); |
308 intptr_t FindNativeEntry(const ExternalLabel* label, Patchability patchable); | 301 intptr_t FindNativeEntry(const ExternalLabel* label, Patchability patchable); |
309 | 302 |
310 RawObjectPool* MakeObjectPool(); | 303 RawObjectPool* MakeObjectPool(); |
311 | 304 |
312 private: | 305 private: |
313 intptr_t AddObject(ObjectPoolWrapperEntry entry, Patchability patchable); | 306 intptr_t AddObject(ObjectPoolWrapperEntry entry, Patchability patchable); |
314 intptr_t FindObject(ObjectPoolWrapperEntry entry, Patchability patchable); | 307 intptr_t FindObject(ObjectPoolWrapperEntry entry, Patchability patchable); |
315 | 308 |
316 // Objects and jump targets. | 309 // Objects and jump targets. |
317 GrowableArray<ObjectPoolWrapperEntry> object_pool_; | 310 GrowableArray<ObjectPoolWrapperEntry> object_pool_; |
318 | 311 |
319 // Hashmap for fast lookup in object pool. | 312 // Hashmap for fast lookup in object pool. |
320 DirectChainedHashMap<ObjIndexPair> object_pool_index_table_; | 313 DirectChainedHashMap<ObjIndexPair> object_pool_index_table_; |
321 }; | 314 }; |
322 | 315 |
323 | |
324 enum RestorePP { kRestoreCallerPP, kKeepCalleePP }; | 316 enum RestorePP { kRestoreCallerPP, kKeepCalleePP }; |
325 | 317 |
326 } // namespace dart | 318 } // namespace dart |
327 | 319 |
328 | |
329 #if defined(TARGET_ARCH_IA32) | 320 #if defined(TARGET_ARCH_IA32) |
330 #include "vm/assembler_ia32.h" | 321 #include "vm/assembler_ia32.h" |
331 #elif defined(TARGET_ARCH_X64) | 322 #elif defined(TARGET_ARCH_X64) |
332 #include "vm/assembler_x64.h" | 323 #include "vm/assembler_x64.h" |
333 #elif defined(TARGET_ARCH_ARM) | 324 #elif defined(TARGET_ARCH_ARM) |
334 #include "vm/assembler_arm.h" | 325 #include "vm/assembler_arm.h" |
335 #elif defined(TARGET_ARCH_ARM64) | 326 #elif defined(TARGET_ARCH_ARM64) |
336 #include "vm/assembler_arm64.h" | 327 #include "vm/assembler_arm64.h" |
337 #elif defined(TARGET_ARCH_DBC) | 328 #elif defined(TARGET_ARCH_DBC) |
338 #include "vm/assembler_dbc.h" | 329 #include "vm/assembler_dbc.h" |
339 #else | 330 #else |
340 #error Unknown architecture. | 331 #error Unknown architecture. |
341 #endif | 332 #endif |
342 | 333 |
343 #endif // RUNTIME_VM_ASSEMBLER_H_ | 334 #endif // RUNTIME_VM_ASSEMBLER_H_ |
OLD | NEW |