| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
| 6 #include <setjmp.h> | 6 #include <setjmp.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #if defined(TARGET_ARCH_ARM) | 10 #if defined(TARGET_ARCH_ARM) |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 SimulatorDebugger::~SimulatorDebugger() { | 128 SimulatorDebugger::~SimulatorDebugger() { |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 void SimulatorDebugger::Stop(Instr* instr, const char* message) { | 132 void SimulatorDebugger::Stop(Instr* instr, const char* message) { |
| 133 OS::Print("Simulator hit %s\n", message); | 133 OS::Print("Simulator hit %s\n", message); |
| 134 Debug(); | 134 Debug(); |
| 135 } | 135 } |
| 136 | 136 |
| 137 | 137 |
| 138 static Register LookupCoreRegisterByName(const char* name) { | 138 static Register LookupCpuRegisterByName(const char* name) { |
| 139 static const char* kNames[] = { | 139 static const char* kNames[] = { |
| 140 "r0", "r1", "r2", "r3", | 140 "r0", "r1", "r2", "r3", |
| 141 "r4", "r5", "r6", "r7", | 141 "r4", "r5", "r6", "r7", |
| 142 "r8", "r9", "r10", "r11", | 142 "r8", "r9", "r10", "r11", |
| 143 "r12", "r13", "r14", "r15", | 143 "r12", "r13", "r14", "r15", |
| 144 "pc", "lr", "sp", "ip", | 144 "pc", "lr", "sp", "ip", |
| 145 "fp", "sl" | 145 "fp", "pp", "ctx" |
| 146 }; | 146 }; |
| 147 static const Register kRegisters[] = { | 147 static const Register kRegisters[] = { |
| 148 R0, R1, R2, R3, | 148 R0, R1, R2, R3, |
| 149 R4, R5, R6, R7, | 149 R4, R5, R6, R7, |
| 150 R8, R9, R10, R11, | 150 R8, R9, R10, R11, |
| 151 R12, R13, R14, R15, | 151 R12, R13, R14, R15, |
| 152 PC, LR, SP, IP, | 152 PC, LR, SP, IP, |
| 153 FP, R10 | 153 FP, R10, R9 |
| 154 }; | 154 }; |
| 155 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); | 155 ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters)); |
| 156 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { | 156 for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) { |
| 157 if (strcmp(kNames[i], name) == 0) { | 157 if (strcmp(kNames[i], name) == 0) { |
| 158 return kRegisters[i]; | 158 return kRegisters[i]; |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 return kNoRegister; | 161 return kNoRegister; |
| 162 } | 162 } |
| 163 | 163 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 176 int reg_nr = -1; | 176 int reg_nr = -1; |
| 177 bool ok = SScanF(name, "d%d", ®_nr); | 177 bool ok = SScanF(name, "d%d", ®_nr); |
| 178 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfDRegisters)) { | 178 if (ok && (0 <= reg_nr) && (reg_nr < kNumberOfDRegisters)) { |
| 179 return static_cast<DRegister>(reg_nr); | 179 return static_cast<DRegister>(reg_nr); |
| 180 } | 180 } |
| 181 return kNoDRegister; | 181 return kNoDRegister; |
| 182 } | 182 } |
| 183 | 183 |
| 184 | 184 |
| 185 bool SimulatorDebugger::GetValue(char* desc, uint32_t* value) { | 185 bool SimulatorDebugger::GetValue(char* desc, uint32_t* value) { |
| 186 Register reg = LookupCoreRegisterByName(desc); | 186 Register reg = LookupCpuRegisterByName(desc); |
| 187 if (reg != kNoRegister) { | 187 if (reg != kNoRegister) { |
| 188 if (reg == PC) { | 188 if (reg == PC) { |
| 189 *value = sim_->get_pc(); | 189 *value = sim_->get_pc(); |
| 190 } else { | 190 } else { |
| 191 *value = sim_->get_register(reg); | 191 *value = sim_->get_register(reg); |
| 192 } | 192 } |
| 193 return true; | 193 return true; |
| 194 } | 194 } |
| 195 if ((desc[0] == '*')) { | 195 if ((desc[0] == '*')) { |
| 196 uint32_t addr; | 196 uint32_t addr; |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 // execute it with the simulator. We do that by redirecting the external | 664 // execute it with the simulator. We do that by redirecting the external |
| 665 // reference to a svc (supervisor call) instruction that is handled by | 665 // reference to a svc (supervisor call) instruction that is handled by |
| 666 // the simulator. We write the original destination of the jump just at a known | 666 // the simulator. We write the original destination of the jump just at a known |
| 667 // offset from the svc instruction so the simulator knows what to call. | 667 // offset from the svc instruction so the simulator knows what to call. |
| 668 class Redirection { | 668 class Redirection { |
| 669 public: | 669 public: |
| 670 uword address_of_svc_instruction() { | 670 uword address_of_svc_instruction() { |
| 671 return reinterpret_cast<uword>(&svc_instruction_); | 671 return reinterpret_cast<uword>(&svc_instruction_); |
| 672 } | 672 } |
| 673 | 673 |
| 674 void* external_function() const { return external_function_; } | 674 uword external_function() const { return external_function_; } |
| 675 | 675 |
| 676 uint32_t argument_count() const { return argument_count_; } | 676 uint32_t argument_count() const { return argument_count_; } |
| 677 | 677 |
| 678 static Redirection* Get(void* external_function, uint32_t argument_count) { | 678 static Redirection* Get(uword external_function, uint32_t argument_count) { |
| 679 Redirection* current; | 679 Redirection* current; |
| 680 for (current = list_; current != NULL; current = current->next_) { | 680 for (current = list_; current != NULL; current = current->next_) { |
| 681 if (current->external_function_ == external_function) return current; | 681 if (current->external_function_ == external_function) return current; |
| 682 } | 682 } |
| 683 return new Redirection(external_function, argument_count); | 683 return new Redirection(external_function, argument_count); |
| 684 } | 684 } |
| 685 | 685 |
| 686 static Redirection* FromSvcInstruction(Instr* svc_instruction) { | 686 static Redirection* FromSvcInstruction(Instr* svc_instruction) { |
| 687 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction); | 687 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction); |
| 688 char* addr_of_redirection = | 688 char* addr_of_redirection = |
| 689 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_); | 689 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_); |
| 690 return reinterpret_cast<Redirection*>(addr_of_redirection); | 690 return reinterpret_cast<Redirection*>(addr_of_redirection); |
| 691 } | 691 } |
| 692 | 692 |
| 693 private: | 693 private: |
| 694 static const int32_t kRedirectSvcInstruction = | 694 static const int32_t kRedirectSvcInstruction = |
| 695 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); | 695 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); |
| 696 Redirection(void* external_function, uint32_t argument_count) | 696 Redirection(uword external_function, uint32_t argument_count) |
| 697 : external_function_(external_function), | 697 : external_function_(external_function), |
| 698 argument_count_(argument_count), | 698 argument_count_(argument_count), |
| 699 svc_instruction_(kRedirectSvcInstruction), | 699 svc_instruction_(kRedirectSvcInstruction), |
| 700 next_(list_) { | 700 next_(list_) { |
| 701 list_ = this; | 701 list_ = this; |
| 702 } | 702 } |
| 703 | 703 |
| 704 void* external_function_; | 704 uword external_function_; |
| 705 const uint32_t argument_count_; | 705 const uint32_t argument_count_; |
| 706 uint32_t svc_instruction_; | 706 uint32_t svc_instruction_; |
| 707 Redirection* next_; | 707 Redirection* next_; |
| 708 static Redirection* list_; | 708 static Redirection* list_; |
| 709 }; | 709 }; |
| 710 | 710 |
| 711 | 711 |
| 712 Redirection* Redirection::list_ = NULL; | 712 Redirection* Redirection::list_ = NULL; |
| 713 | 713 |
| 714 | 714 |
| 715 uword Simulator::RedirectExternalReference(void* function, | 715 uword Simulator::RedirectExternalReference(uword function, |
| 716 uint32_t argument_count) { | 716 uint32_t argument_count) { |
| 717 Redirection* redirection = Redirection::Get(function, argument_count); | 717 Redirection* redirection = Redirection::Get(function, argument_count); |
| 718 return redirection->address_of_svc_instruction(); | 718 return redirection->address_of_svc_instruction(); |
| 719 } | 719 } |
| 720 | 720 |
| 721 | 721 |
| 722 // Get the active Simulator for the current isolate. | 722 // Get the active Simulator for the current isolate. |
| 723 Simulator* Simulator::Current() { | 723 Simulator* Simulator::Current() { |
| 724 Simulator* simulator = Isolate::Current()->simulator(); | 724 Simulator* simulator = Isolate::Current()->simulator(); |
| 725 if (simulator == NULL) { | 725 if (simulator == NULL) { |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 if (!setjmp(buffer.buffer_)) { | 1309 if (!setjmp(buffer.buffer_)) { |
| 1310 NativeArguments arguments; | 1310 NativeArguments arguments; |
| 1311 ASSERT(sizeof(NativeArguments) == 4*kWordSize); | 1311 ASSERT(sizeof(NativeArguments) == 4*kWordSize); |
| 1312 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0)); | 1312 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0)); |
| 1313 arguments.argc_tag_ = get_register(R1); | 1313 arguments.argc_tag_ = get_register(R1); |
| 1314 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2)); | 1314 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2)); |
| 1315 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3)); | 1315 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3)); |
| 1316 | 1316 |
| 1317 int32_t saved_lr = get_register(LR); | 1317 int32_t saved_lr = get_register(LR); |
| 1318 Redirection* redirection = Redirection::FromSvcInstruction(instr); | 1318 Redirection* redirection = Redirection::FromSvcInstruction(instr); |
| 1319 intptr_t external = | 1319 uword external = redirection->external_function(); |
| 1320 reinterpret_cast<intptr_t>(redirection->external_function()); | |
| 1321 SimulatorRuntimeCall target = | 1320 SimulatorRuntimeCall target = |
| 1322 reinterpret_cast<SimulatorRuntimeCall>(external); | 1321 reinterpret_cast<SimulatorRuntimeCall>(external); |
| 1323 if (FLAG_trace_sim) { | 1322 if (FLAG_trace_sim) { |
| 1324 PrintExternalCallTrace(external, arguments); | 1323 PrintExternalCallTrace(external, arguments); |
| 1325 } | 1324 } |
| 1326 target(arguments); | 1325 target(arguments); |
| 1327 | 1326 |
| 1328 // Zap caller-saved registers, since the actual runtime call could have | 1327 // Zap caller-saved registers, since the actual runtime call could have |
| 1329 // used them. | 1328 // used them. |
| 1330 set_register(R2, icount_); | 1329 set_register(R2, icount_); |
| (...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2740 // isolate->ChangeStateToGeneratedCode(); | 2739 // isolate->ChangeStateToGeneratedCode(); |
| 2741 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); | 2740 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); |
| 2742 buf->Longjmp(); | 2741 buf->Longjmp(); |
| 2743 } | 2742 } |
| 2744 | 2743 |
| 2745 } // namespace dart | 2744 } // namespace dart |
| 2746 | 2745 |
| 2747 #endif // !defined(HOST_ARCH_ARM) | 2746 #endif // !defined(HOST_ARCH_ARM) |
| 2748 | 2747 |
| 2749 #endif // defined TARGET_ARCH_ARM | 2748 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |