OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, 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 VM_ASSEMBLER_DBC_H_ |
| 6 #define VM_ASSEMBLER_DBC_H_ |
| 7 |
| 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_dbc.h directly; use assembler.h instead. |
| 10 #endif |
| 11 |
| 12 #include "platform/assert.h" |
| 13 #include "platform/utils.h" |
| 14 #include "vm/constants_dbc.h" |
| 15 #include "vm/cpu.h" |
| 16 #include "vm/hash_map.h" |
| 17 #include "vm/object.h" |
| 18 #include "vm/simulator.h" |
| 19 |
| 20 namespace dart { |
| 21 |
| 22 |
| 23 // Dummy declaration to make things compile. |
| 24 class Address : public ValueObject { |
| 25 private: |
| 26 Address(); |
| 27 }; |
| 28 |
| 29 |
| 30 class Label : public ValueObject { |
| 31 public: |
| 32 Label() : position_(0) { } |
| 33 |
| 34 ~Label() { |
| 35 // Assert if label is being destroyed with unresolved branches pending. |
| 36 ASSERT(!IsLinked()); |
| 37 } |
| 38 |
| 39 // Returns the position for bound and linked labels. Cannot be used |
| 40 // for unused labels. |
| 41 intptr_t Position() const { |
| 42 ASSERT(!IsUnused()); |
| 43 return IsBound() ? -position_ - kWordSize : position_ - kWordSize; |
| 44 } |
| 45 |
| 46 bool IsBound() const { return position_ < 0; } |
| 47 bool IsUnused() const { return position_ == 0; } |
| 48 bool IsLinked() const { return position_ > 0; } |
| 49 |
| 50 private: |
| 51 intptr_t position_; |
| 52 |
| 53 void Reinitialize() { |
| 54 position_ = 0; |
| 55 } |
| 56 |
| 57 void BindTo(intptr_t position) { |
| 58 ASSERT(!IsBound()); |
| 59 position_ = -position - kWordSize; |
| 60 ASSERT(IsBound()); |
| 61 } |
| 62 |
| 63 void LinkTo(intptr_t position) { |
| 64 ASSERT(!IsBound()); |
| 65 position_ = position + kWordSize; |
| 66 ASSERT(IsLinked()); |
| 67 } |
| 68 |
| 69 friend class Assembler; |
| 70 DISALLOW_COPY_AND_ASSIGN(Label); |
| 71 }; |
| 72 |
| 73 |
| 74 class Assembler : public ValueObject { |
| 75 public: |
| 76 explicit Assembler(bool use_far_branches = false) |
| 77 : buffer_(), |
| 78 comments_() { |
| 79 } |
| 80 |
| 81 ~Assembler() { } |
| 82 |
| 83 void Bind(Label* label); |
| 84 void Jump(Label* label); |
| 85 |
| 86 // Misc. functionality |
| 87 intptr_t CodeSize() const { return buffer_.Size(); } |
| 88 intptr_t prologue_offset() const { return 0; } |
| 89 |
| 90 // Count the fixups that produce a pointer offset, without processing |
| 91 // the fixups. |
| 92 intptr_t CountPointerOffsets() const { return 0; } |
| 93 |
| 94 const ZoneGrowableArray<intptr_t>& GetPointerOffsets() const { |
| 95 ASSERT(buffer_.pointer_offsets().length() == 0); // No pointers in code. |
| 96 return buffer_.pointer_offsets(); |
| 97 } |
| 98 |
| 99 ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; } |
| 100 |
| 101 RawObjectPool* MakeObjectPool() { |
| 102 return object_pool_wrapper_.MakeObjectPool(); |
| 103 } |
| 104 |
| 105 void FinalizeInstructions(const MemoryRegion& region) { |
| 106 buffer_.FinalizeInstructions(region); |
| 107 } |
| 108 |
| 109 // Debugging and bringup support. |
| 110 void Stop(const char* message); |
| 111 void Unimplemented(const char* message); |
| 112 void Untested(const char* message); |
| 113 void Unreachable(const char* message); |
| 114 |
| 115 static void InitializeMemoryWithBreakpoints(uword data, intptr_t length); |
| 116 |
| 117 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
| 118 static bool EmittingComments(); |
| 119 |
| 120 const Code::Comments& GetCodeComments() const; |
| 121 |
| 122 static const char* RegisterName(Register reg); |
| 123 |
| 124 static const char* FpuRegisterName(FpuRegister reg) { |
| 125 return "?"; |
| 126 } |
| 127 |
| 128 static uword GetBreakInstructionFiller() { |
| 129 return Bytecode::kTrap; |
| 130 } |
| 131 |
| 132 static bool IsSafe(const Object& value) { return true; } |
| 133 static bool IsSafeSmi(const Object& value) { return false; } |
| 134 |
| 135 // Bytecodes. |
| 136 |
| 137 #define DECLARE_EMIT(Name, Signature, Fmt0, Fmt1, Fmt2) \ |
| 138 void Name(PARAMS_##Signature); |
| 139 |
| 140 #define PARAMS_0 |
| 141 #define PARAMS_A_D uintptr_t ra, uintptr_t rd |
| 142 #define PARAMS_D uintptr_t rd |
| 143 #define PARAMS_A_B_C uintptr_t ra, uintptr_t rb, uintptr_t rc |
| 144 #define PARAMS_A uintptr_t ra |
| 145 #define PARAMS_X intptr_t x |
| 146 #define PARAMS_T intptr_t x |
| 147 #define PARAMS_A_X uintptr_t ra, intptr_t x |
| 148 |
| 149 |
| 150 BYTECODES_LIST(DECLARE_EMIT) |
| 151 |
| 152 #undef PARAMS_0 |
| 153 #undef PARAMS_A_D |
| 154 #undef PARAMS_D |
| 155 #undef PARAMS_A_B_C |
| 156 #undef PARAMS_A |
| 157 #undef PARAMS_X |
| 158 #undef PARAMS_T |
| 159 #undef PARAMS_A_X |
| 160 #undef DECLARE_EMIT |
| 161 |
| 162 void Emit(int32_t value); |
| 163 |
| 164 void PushConstant(const Object& obj); |
| 165 void LoadConstant(uintptr_t ra, const Object& obj); |
| 166 |
| 167 intptr_t AddConstant(const Object& obj); |
| 168 |
| 169 private: |
| 170 AssemblerBuffer buffer_; // Contains position independent code. |
| 171 ObjectPoolWrapper object_pool_wrapper_; |
| 172 |
| 173 class CodeComment : public ZoneAllocated { |
| 174 public: |
| 175 CodeComment(intptr_t pc_offset, const String& comment) |
| 176 : pc_offset_(pc_offset), comment_(comment) { } |
| 177 |
| 178 intptr_t pc_offset() const { return pc_offset_; } |
| 179 const String& comment() const { return comment_; } |
| 180 |
| 181 private: |
| 182 intptr_t pc_offset_; |
| 183 const String& comment_; |
| 184 |
| 185 DISALLOW_COPY_AND_ASSIGN(CodeComment); |
| 186 }; |
| 187 |
| 188 GrowableArray<CodeComment*> comments_; |
| 189 |
| 190 DISALLOW_ALLOCATION(); |
| 191 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 192 }; |
| 193 |
| 194 |
| 195 } // namespace dart |
| 196 |
| 197 #endif // VM_ASSEMBLER_DBC_H_ |
OLD | NEW |