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 VM_ASSEMBLER_H_ | 5 #ifndef VM_ASSEMBLER_H_ |
6 #define VM_ASSEMBLER_H_ | 6 #define 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" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 private: | 42 private: |
43 const uword address_; | 43 const uword address_; |
44 }; | 44 }; |
45 | 45 |
46 | 46 |
47 // Assembler fixups are positions in generated code that hold relocation | 47 // Assembler fixups are positions in generated code that hold relocation |
48 // information that needs to be processed before finalizing the code | 48 // information that needs to be processed before finalizing the code |
49 // into executable memory. | 49 // into executable memory. |
50 class AssemblerFixup : public ZoneAllocated { | 50 class AssemblerFixup : public ZoneAllocated { |
51 public: | 51 public: |
52 virtual void Process(const MemoryRegion& region, intptr_t position) = 0; | 52 virtual void Process(const MemoryRegion& region, |
| 53 intptr_t position, |
| 54 Assembler* assembler) = 0; |
53 | 55 |
54 virtual bool IsPointerOffset() const = 0; | 56 virtual bool IsPointerOffset() const = 0; |
55 | 57 |
56 // It would be ideal if the destructor method could be made private, | 58 // It would be ideal if the destructor method could be made private, |
57 // but the g++ compiler complains when this is subclassed. | 59 // but the g++ compiler complains when this is subclassed. |
58 virtual ~AssemblerFixup() { UNREACHABLE(); } | 60 virtual ~AssemblerFixup() { UNREACHABLE(); } |
59 | 61 |
60 private: | 62 private: |
61 AssemblerFixup* previous_; | 63 AssemblerFixup* previous_; |
62 intptr_t position_; | 64 intptr_t position_; |
63 | 65 |
64 AssemblerFixup* previous() const { return previous_; } | 66 AssemblerFixup* previous() const { return previous_; } |
65 void set_previous(AssemblerFixup* previous) { previous_ = previous; } | 67 void set_previous(AssemblerFixup* previous) { previous_ = previous; } |
66 | 68 |
67 intptr_t position() const { return position_; } | 69 intptr_t position() const { return position_; } |
68 void set_position(intptr_t position) { position_ = position; } | 70 void set_position(intptr_t position) { position_ = position; } |
69 | 71 |
70 friend class AssemblerBuffer; | 72 friend class AssemblerBuffer; |
71 }; | 73 }; |
72 | 74 |
73 | 75 |
74 // Assembler buffers are used to emit binary code. They grow on demand. | 76 // Assembler buffers are used to emit binary code. They grow on demand. |
75 class AssemblerBuffer : public ValueObject { | 77 class AssemblerBuffer : public ValueObject { |
76 public: | 78 public: |
77 AssemblerBuffer(); | 79 explicit AssemblerBuffer(Assembler* assembler); |
78 ~AssemblerBuffer(); | 80 ~AssemblerBuffer(); |
79 | 81 |
80 // Basic support for emitting, loading, and storing. | 82 // Basic support for emitting, loading, and storing. |
81 template<typename T> void Emit(T value) { | 83 template<typename T> void Emit(T value) { |
82 ASSERT(HasEnsuredCapacity()); | 84 ASSERT(HasEnsuredCapacity()); |
83 *reinterpret_cast<T*>(cursor_) = value; | 85 *reinterpret_cast<T*>(cursor_) = value; |
84 cursor_ += sizeof(T); | 86 cursor_ += sizeof(T); |
85 } | 87 } |
86 | 88 |
87 template<typename T> void Remit() { | 89 template<typename T> void Remit() { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 private: | 175 private: |
174 // The limit is set to kMinimumGap bytes before the end of the data area. | 176 // The limit is set to kMinimumGap bytes before the end of the data area. |
175 // This leaves enough space for the longest possible instruction and allows | 177 // This leaves enough space for the longest possible instruction and allows |
176 // for a single, fast space check per instruction. | 178 // for a single, fast space check per instruction. |
177 static const intptr_t kMinimumGap = 32; | 179 static const intptr_t kMinimumGap = 32; |
178 | 180 |
179 uword contents_; | 181 uword contents_; |
180 uword cursor_; | 182 uword cursor_; |
181 uword limit_; | 183 uword limit_; |
182 AssemblerFixup* fixup_; | 184 AssemblerFixup* fixup_; |
| 185 Assembler* assembler_; |
183 ZoneGrowableArray<intptr_t>* pointer_offsets_; | 186 ZoneGrowableArray<intptr_t>* pointer_offsets_; |
184 #if defined(DEBUG) | 187 #if defined(DEBUG) |
185 bool fixups_processed_; | 188 bool fixups_processed_; |
186 #endif | 189 #endif |
187 | 190 |
188 uword cursor() const { return cursor_; } | 191 uword cursor() const { return cursor_; } |
189 uword limit() const { return limit_; } | 192 uword limit() const { return limit_; } |
190 intptr_t Capacity() const { | 193 intptr_t Capacity() const { |
191 ASSERT(limit_ >= contents_); | 194 ASSERT(limit_ >= contents_); |
192 return (limit_ - contents_) + kMinimumGap; | 195 return (limit_ - contents_) + kMinimumGap; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 static inline bool IsKeyEqual(Pair kv, Key key) { | 254 static inline bool IsKeyEqual(Pair kv, Key key) { |
252 return kv.key_->raw() == key->raw(); | 255 return kv.key_->raw() == key->raw(); |
253 } | 256 } |
254 | 257 |
255 private: | 258 private: |
256 Key key_; | 259 Key key_; |
257 Value value_; | 260 Value value_; |
258 }; | 261 }; |
259 | 262 |
260 | 263 |
| 264 class UntaggedIndexPair { |
| 265 public: |
| 266 // Typedefs needed for the DirectChainedHashMap template. |
| 267 typedef uword Key; |
| 268 typedef intptr_t Value; |
| 269 typedef UntaggedIndexPair Pair; |
| 270 |
| 271 static const intptr_t kNoIndex = -1; |
| 272 |
| 273 UntaggedIndexPair() : key_(), value_(kNoIndex) { } |
| 274 |
| 275 UntaggedIndexPair(Key key, Value value) : key_(key), value_(value) { } |
| 276 |
| 277 static Key KeyOf(Pair kv) { return kv.key_; } |
| 278 |
| 279 static Value ValueOf(Pair kv) { return kv.value_; } |
| 280 |
| 281 static intptr_t Hashcode(Key key) { |
| 282 return static_cast<intptr_t>(key); |
| 283 } |
| 284 |
| 285 static inline bool IsKeyEqual(Pair kv, Key key) { |
| 286 return kv.key_ == key; |
| 287 } |
| 288 |
| 289 private: |
| 290 Key key_; |
| 291 Value value_; |
| 292 }; |
| 293 |
| 294 |
261 enum Patchability { | 295 enum Patchability { |
262 kPatchable, | 296 kPatchable, |
263 kNotPatchable, | 297 kNotPatchable, |
264 }; | 298 }; |
265 | 299 |
266 | 300 |
267 class ObjectPool : public ValueObject { | 301 class ObjectPoolHelper : public ValueObject { |
268 public: | 302 public: |
269 ObjectPool() : object_pool_(GrowableObjectArray::Handle()) { } | 303 intptr_t AddObject(const Object& obj); |
270 | 304 intptr_t AddImmediate(uword imm); |
271 intptr_t AddObject(const Object& obj, Patchability patchable); | |
272 intptr_t AddExternalLabel(const ExternalLabel* label, | 305 intptr_t AddExternalLabel(const ExternalLabel* label, |
273 Patchability patchable); | 306 Patchability patchable); |
274 | 307 |
275 intptr_t FindObject(const Object& obj, Patchability patchable); | 308 intptr_t AddFixedObject(const Object& obj); |
| 309 intptr_t AddFixedExternalLabel(const ExternalLabel* label); |
| 310 |
| 311 intptr_t FindObject(const Object& obj); |
| 312 intptr_t FindImmediate(uword imm); |
276 intptr_t FindExternalLabel(const ExternalLabel* label, | 313 intptr_t FindExternalLabel(const ExternalLabel* label, |
277 Patchability patchable); | 314 Patchability patchable); |
278 const GrowableObjectArray& data() const { return object_pool_; } | 315 |
| 316 RawObjectPool* MakeObjectPool(); |
| 317 |
| 318 intptr_t UntaggedEntryStart() { return tagged_entries_.length(); } |
279 | 319 |
280 private: | 320 private: |
281 // Objects and jump targets. | 321 intptr_t AddUntagged(uword value, Patchability patchable); |
282 GrowableObjectArray& object_pool_; | 322 intptr_t FindUntagged(uword value, Patchability patchable); |
283 | 323 |
284 // Patchability of pool entries. | 324 GrowableArray<ObjectPool::Entry> fixed_entries_; |
285 GrowableArray<Patchability> patchable_pool_entries_; | |
286 | 325 |
287 // Hashmap for fast lookup in object pool. | 326 GrowableArray<const Object*> tagged_entries_; |
288 DirectChainedHashMap<ObjIndexPair> object_pool_index_table_; | 327 DirectChainedHashMap<ObjIndexPair> object_index_table_; |
| 328 |
| 329 GrowableArray<uword> untagged_entries_; |
| 330 DirectChainedHashMap<UntaggedIndexPair> untagged_index_table_; |
289 }; | 331 }; |
290 | 332 |
| 333 |
| 334 class ObjectPoolIndexFixup : public AssemblerFixup { |
| 335 public: |
| 336 virtual void Process(const MemoryRegion& region, |
| 337 intptr_t position, |
| 338 Assembler* assembler); |
| 339 |
| 340 virtual bool IsPointerOffset() const { return false; } |
| 341 }; |
| 342 |
| 343 |
291 } // namespace dart | 344 } // namespace dart |
292 | 345 |
293 | 346 |
294 #if defined(TARGET_ARCH_IA32) | 347 #if defined(TARGET_ARCH_IA32) |
295 #include "vm/assembler_ia32.h" | 348 #include "vm/assembler_ia32.h" |
296 #elif defined(TARGET_ARCH_X64) | 349 #elif defined(TARGET_ARCH_X64) |
297 #include "vm/assembler_x64.h" | 350 #include "vm/assembler_x64.h" |
298 #elif defined(TARGET_ARCH_ARM) | 351 #elif defined(TARGET_ARCH_ARM) |
299 #include "vm/assembler_arm.h" | 352 #include "vm/assembler_arm.h" |
300 #elif defined(TARGET_ARCH_ARM64) | 353 #elif defined(TARGET_ARCH_ARM64) |
301 #include "vm/assembler_arm64.h" | 354 #include "vm/assembler_arm64.h" |
302 #elif defined(TARGET_ARCH_MIPS) | 355 #elif defined(TARGET_ARCH_MIPS) |
303 #include "vm/assembler_mips.h" | 356 #include "vm/assembler_mips.h" |
304 #else | 357 #else |
305 #error Unknown architecture. | 358 #error Unknown architecture. |
306 #endif | 359 #endif |
307 | 360 |
308 #endif // VM_ASSEMBLER_H_ | 361 #endif // VM_ASSEMBLER_H_ |
OLD | NEW |