| 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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 // execute it with the simulator. We do that by redirecting the external | 673 // execute it with the simulator. We do that by redirecting the external |
| 674 // reference to a svc (supervisor call) instruction that is handled by | 674 // reference to a svc (supervisor call) instruction that is handled by |
| 675 // the simulator. We write the original destination of the jump just at a known | 675 // the simulator. We write the original destination of the jump just at a known |
| 676 // offset from the svc instruction so the simulator knows what to call. | 676 // offset from the svc instruction so the simulator knows what to call. |
| 677 class Redirection { | 677 class Redirection { |
| 678 public: | 678 public: |
| 679 uword address_of_svc_instruction() { | 679 uword address_of_svc_instruction() { |
| 680 return reinterpret_cast<uword>(&svc_instruction_); | 680 return reinterpret_cast<uword>(&svc_instruction_); |
| 681 } | 681 } |
| 682 | 682 |
| 683 void* external_function() const { return external_function_; } | 683 uword external_function() const { return external_function_; } |
| 684 | 684 |
| 685 uint32_t argument_count() const { return argument_count_; } | 685 uint32_t argument_count() const { return argument_count_; } |
| 686 | 686 |
| 687 static Redirection* Get(void* external_function, uint32_t argument_count) { | 687 static Redirection* Get(uword external_function, uint32_t argument_count) { |
| 688 Redirection* current; | 688 Redirection* current; |
| 689 for (current = list_; current != NULL; current = current->next_) { | 689 for (current = list_; current != NULL; current = current->next_) { |
| 690 if (current->external_function_ == external_function) return current; | 690 if (current->external_function_ == external_function) return current; |
| 691 } | 691 } |
| 692 return new Redirection(external_function, argument_count); | 692 return new Redirection(external_function, argument_count); |
| 693 } | 693 } |
| 694 | 694 |
| 695 static Redirection* FromSvcInstruction(Instr* svc_instruction) { | 695 static Redirection* FromSvcInstruction(Instr* svc_instruction) { |
| 696 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction); | 696 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction); |
| 697 char* addr_of_redirection = | 697 char* addr_of_redirection = |
| 698 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_); | 698 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_); |
| 699 return reinterpret_cast<Redirection*>(addr_of_redirection); | 699 return reinterpret_cast<Redirection*>(addr_of_redirection); |
| 700 } | 700 } |
| 701 | 701 |
| 702 private: | 702 private: |
| 703 static const int32_t kRedirectSvcInstruction = | 703 static const int32_t kRedirectSvcInstruction = |
| 704 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); | 704 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); |
| 705 Redirection(void* external_function, uint32_t argument_count) | 705 Redirection(uword external_function, uint32_t argument_count) |
| 706 : external_function_(external_function), | 706 : external_function_(external_function), |
| 707 argument_count_(argument_count), | 707 argument_count_(argument_count), |
| 708 svc_instruction_(kRedirectSvcInstruction), | 708 svc_instruction_(kRedirectSvcInstruction), |
| 709 next_(list_) { | 709 next_(list_) { |
| 710 list_ = this; | 710 list_ = this; |
| 711 } | 711 } |
| 712 | 712 |
| 713 void* external_function_; | 713 uword external_function_; |
| 714 const uint32_t argument_count_; | 714 const uint32_t argument_count_; |
| 715 uint32_t svc_instruction_; | 715 uint32_t svc_instruction_; |
| 716 Redirection* next_; | 716 Redirection* next_; |
| 717 static Redirection* list_; | 717 static Redirection* list_; |
| 718 }; | 718 }; |
| 719 | 719 |
| 720 | 720 |
| 721 Redirection* Redirection::list_ = NULL; | 721 Redirection* Redirection::list_ = NULL; |
| 722 | 722 |
| 723 | 723 |
| 724 uword Simulator::RedirectExternalReference(void* function, | 724 uword Simulator::RedirectExternalReference(uword function, |
| 725 uint32_t argument_count) { | 725 uint32_t argument_count) { |
| 726 Redirection* redirection = Redirection::Get(function, argument_count); | 726 Redirection* redirection = Redirection::Get(function, argument_count); |
| 727 return redirection->address_of_svc_instruction(); | 727 return redirection->address_of_svc_instruction(); |
| 728 } | 728 } |
| 729 | 729 |
| 730 | 730 |
| 731 // Get the active Simulator for the current isolate. | 731 // Get the active Simulator for the current isolate. |
| 732 Simulator* Simulator::Current() { | 732 Simulator* Simulator::Current() { |
| 733 Simulator* simulator = Isolate::Current()->simulator(); | 733 Simulator* simulator = Isolate::Current()->simulator(); |
| 734 if (simulator == NULL) { | 734 if (simulator == NULL) { |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 if (!setjmp(buffer.buffer_)) { | 1318 if (!setjmp(buffer.buffer_)) { |
| 1319 NativeArguments arguments; | 1319 NativeArguments arguments; |
| 1320 ASSERT(sizeof(NativeArguments) == 4*kWordSize); | 1320 ASSERT(sizeof(NativeArguments) == 4*kWordSize); |
| 1321 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0)); | 1321 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0)); |
| 1322 arguments.argc_tag_ = get_register(R1); | 1322 arguments.argc_tag_ = get_register(R1); |
| 1323 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2)); | 1323 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2)); |
| 1324 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3)); | 1324 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3)); |
| 1325 | 1325 |
| 1326 int32_t saved_lr = get_register(LR); | 1326 int32_t saved_lr = get_register(LR); |
| 1327 Redirection* redirection = Redirection::FromSvcInstruction(instr); | 1327 Redirection* redirection = Redirection::FromSvcInstruction(instr); |
| 1328 intptr_t external = | 1328 uword external = redirection->external_function(); |
| 1329 reinterpret_cast<intptr_t>(redirection->external_function()); | |
| 1330 SimulatorRuntimeCall target = | 1329 SimulatorRuntimeCall target = |
| 1331 reinterpret_cast<SimulatorRuntimeCall>(external); | 1330 reinterpret_cast<SimulatorRuntimeCall>(external); |
| 1332 if (FLAG_trace_sim) { | 1331 if (FLAG_trace_sim) { |
| 1333 PrintExternalCallTrace(external, arguments); | 1332 PrintExternalCallTrace(external, arguments); |
| 1334 } | 1333 } |
| 1335 target(arguments); | 1334 target(arguments); |
| 1336 | 1335 |
| 1337 // Zap caller-saved registers, since the actual runtime call could have | 1336 // Zap caller-saved registers, since the actual runtime call could have |
| 1338 // used them. | 1337 // used them. |
| 1339 set_register(R2, icount_); | 1338 set_register(R2, icount_); |
| (...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2800 // isolate->ChangeStateToGeneratedCode(); | 2799 // isolate->ChangeStateToGeneratedCode(); |
| 2801 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); | 2800 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); |
| 2802 buf->Longjmp(); | 2801 buf->Longjmp(); |
| 2803 } | 2802 } |
| 2804 | 2803 |
| 2805 } // namespace dart | 2804 } // namespace dart |
| 2806 | 2805 |
| 2807 #endif // !defined(HOST_ARCH_ARM) | 2806 #endif // !defined(HOST_ARCH_ARM) |
| 2808 | 2807 |
| 2809 #endif // defined TARGET_ARCH_ARM | 2808 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |