| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 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 | 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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. |
| 6 #if defined(TARGET_ARCH_DBC) | 6 #if defined(TARGET_ARCH_DBC) |
| 7 | 7 |
| 8 #include "vm/instructions.h" | 8 #include "vm/instructions.h" |
| 9 #include "vm/instructions_dbc.h" | 9 #include "vm/instructions_dbc.h" |
| 10 | 10 |
| 11 #include "vm/assembler.h" | 11 #include "vm/assembler.h" |
| 12 #include "vm/constants_dbc.h" | 12 #include "vm/constants_dbc.h" |
| 13 #include "vm/cpu.h" | 13 #include "vm/cpu.h" |
| 14 #include "vm/object.h" | 14 #include "vm/object.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 static bool HasLoadFromPool(Instr instr) { |
| 19 switch (Bytecode::DecodeOpcode(instr)) { |
| 20 case Bytecode::kLoadConstant: |
| 21 case Bytecode::kPushConstant: |
| 22 case Bytecode::kStaticCall: |
| 23 case Bytecode::kInstanceCall1: |
| 24 case Bytecode::kInstanceCall2: |
| 25 case Bytecode::kInstanceCall1Opt: |
| 26 case Bytecode::kInstanceCall2Opt: |
| 27 case Bytecode::kStoreStaticTOS: |
| 28 case Bytecode::kPushStatic: |
| 29 case Bytecode::kAllocate: |
| 30 case Bytecode::kInstantiateType: |
| 31 case Bytecode::kInstantiateTypeArgumentsTOS: |
| 32 case Bytecode::kAssertAssignable: |
| 33 return true; |
| 34 default: |
| 35 return false; |
| 36 } |
| 37 } |
| 38 |
| 39 |
| 40 static bool GetLoadedObjectAt( |
| 41 uword pc, const ObjectPool& object_pool, Object* obj) { |
| 42 Instr instr = Bytecode::At(pc); |
| 43 if (HasLoadFromPool(instr)) { |
| 44 uint16_t index = Bytecode::DecodeD(instr); |
| 45 if (object_pool.InfoAt(index) == ObjectPool::kTaggedObject) { |
| 46 *obj = object_pool.ObjectAt(index); |
| 47 return true; |
| 48 } |
| 49 } |
| 50 return false; |
| 51 } |
| 52 |
| 53 |
| 18 CallPattern::CallPattern(uword pc, const Code& code) | 54 CallPattern::CallPattern(uword pc, const Code& code) |
| 19 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), | 55 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
| 20 end_(pc), | 56 end_(pc), |
| 21 ic_data_load_end_(0), | 57 ic_data_load_end_(0), |
| 22 target_code_pool_index_(-1), | 58 target_code_pool_index_(-1), |
| 23 ic_data_(ICData::Handle()) { | 59 ic_data_(ICData::Handle()) { |
| 24 UNIMPLEMENTED(); | 60 ASSERT(code.ContainsInstructionAt(end_)); |
| 61 const uword call_pc = end_ - sizeof(Instr); |
| 62 Instr call_instr = Bytecode::At(call_pc); |
| 63 ASSERT(Bytecode::IsCallOpcode(call_instr)); |
| 64 ic_data_load_end_ = call_pc; |
| 65 target_code_pool_index_ = Bytecode::DecodeD(call_instr); |
| 25 } | 66 } |
| 26 | 67 |
| 27 | 68 |
| 28 int CallPattern::DeoptCallPatternLengthInInstructions() { | 69 int CallPattern::DeoptCallPatternLengthInInstructions() { |
| 29 UNIMPLEMENTED(); | 70 UNIMPLEMENTED(); |
| 30 return 0; | 71 return 0; |
| 31 } | 72 } |
| 32 | 73 |
| 74 |
| 33 int CallPattern::DeoptCallPatternLengthInBytes() { | 75 int CallPattern::DeoptCallPatternLengthInBytes() { |
| 34 UNIMPLEMENTED(); | 76 UNIMPLEMENTED(); |
| 35 return 0; | 77 return 0; |
| 36 } | 78 } |
| 37 | 79 |
| 38 | 80 |
| 39 NativeCallPattern::NativeCallPattern(uword pc, const Code& code) | 81 NativeCallPattern::NativeCallPattern(uword pc, const Code& code) |
| 40 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), | 82 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
| 41 end_(pc), | 83 end_(pc), |
| 42 native_function_pool_index_(-1), | 84 native_function_pool_index_(-1), |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 // and the index in the pool being read from in the output parameters 'reg' | 144 // and the index in the pool being read from in the output parameters 'reg' |
| 103 // and 'index' respectively. | 145 // and 'index' respectively. |
| 104 uword InstructionPattern::DecodeLoadWordFromPool(uword end, | 146 uword InstructionPattern::DecodeLoadWordFromPool(uword end, |
| 105 Register* reg, | 147 Register* reg, |
| 106 intptr_t* index) { | 148 intptr_t* index) { |
| 107 UNIMPLEMENTED(); | 149 UNIMPLEMENTED(); |
| 108 return 0; | 150 return 0; |
| 109 } | 151 } |
| 110 | 152 |
| 111 | 153 |
| 112 static bool HasLoadFromPool(Instr instr) { | |
| 113 switch (Bytecode::DecodeOpcode(instr)) { | |
| 114 case Bytecode::kLoadConstant: | |
| 115 case Bytecode::kPushConstant: | |
| 116 case Bytecode::kStaticCall: | |
| 117 case Bytecode::kInstanceCall1: | |
| 118 case Bytecode::kInstanceCall2: | |
| 119 case Bytecode::kInstanceCall1Opt: | |
| 120 case Bytecode::kInstanceCall2Opt: | |
| 121 case Bytecode::kStoreStaticTOS: | |
| 122 case Bytecode::kPushStatic: | |
| 123 case Bytecode::kAllocate: | |
| 124 case Bytecode::kInstantiateType: | |
| 125 case Bytecode::kInstantiateTypeArgumentsTOS: | |
| 126 case Bytecode::kAssertAssignable: | |
| 127 return true; | |
| 128 default: | |
| 129 return false; | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 | |
| 134 bool DecodeLoadObjectFromPoolOrThread(uword pc, | 154 bool DecodeLoadObjectFromPoolOrThread(uword pc, |
| 135 const Code& code, | 155 const Code& code, |
| 136 Object* obj) { | 156 Object* obj) { |
| 137 ASSERT(code.ContainsInstructionAt(pc)); | 157 ASSERT(code.ContainsInstructionAt(pc)); |
| 138 Instr instr = Bytecode::At(pc); | 158 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); |
| 139 if (HasLoadFromPool(instr)) { | 159 return GetLoadedObjectAt(pc, pool, obj); |
| 140 uint16_t index = Bytecode::DecodeD(instr); | |
| 141 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); | |
| 142 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { | |
| 143 *obj = pool.ObjectAt(index); | |
| 144 return true; | |
| 145 } | |
| 146 } | |
| 147 return false; | |
| 148 } | 160 } |
| 149 | 161 |
| 150 | 162 |
| 151 RawICData* CallPattern::IcData() { | 163 RawICData* CallPattern::IcData() { |
| 152 UNIMPLEMENTED(); | 164 if (ic_data_.IsNull()) { |
| 153 return ICData::null(); | 165 bool found = GetLoadedObjectAt(ic_data_load_end_, object_pool_, &ic_data_); |
| 166 ASSERT(found); |
| 167 } |
| 168 return ic_data_.raw(); |
| 154 } | 169 } |
| 155 | 170 |
| 156 | 171 |
| 157 RawCode* CallPattern::TargetCode() const { | 172 RawCode* CallPattern::TargetCode() const { |
| 158 return reinterpret_cast<RawCode*>( | 173 return reinterpret_cast<RawCode*>( |
| 159 object_pool_.ObjectAt(target_code_pool_index_)); | 174 object_pool_.ObjectAt(target_code_pool_index_)); |
| 160 } | 175 } |
| 161 | 176 |
| 162 | 177 |
| 163 void CallPattern::SetTargetCode(const Code& target_code) const { | 178 void CallPattern::SetTargetCode(const Code& target_code) const { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 | 219 |
| 205 | 220 |
| 206 bool ReturnPattern::IsValid() const { | 221 bool ReturnPattern::IsValid() const { |
| 207 UNIMPLEMENTED(); | 222 UNIMPLEMENTED(); |
| 208 return false; | 223 return false; |
| 209 } | 224 } |
| 210 | 225 |
| 211 } // namespace dart | 226 } // namespace dart |
| 212 | 227 |
| 213 #endif // defined TARGET_ARCH_DBC | 228 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |