| 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 |