| 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 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 uword 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 Simulator::CallKind call_kind() const { return call_kind_; } |
| 686 | 686 |
| 687 static Redirection* Get(uword external_function, uint32_t argument_count) { | 687 static Redirection* Get(uword external_function, |
| 688 Simulator::CallKind call_kind) { |
| 688 Redirection* current; | 689 Redirection* current; |
| 689 for (current = list_; current != NULL; current = current->next_) { | 690 for (current = list_; current != NULL; current = current->next_) { |
| 690 if (current->external_function_ == external_function) return current; | 691 if (current->external_function_ == external_function) return current; |
| 691 } | 692 } |
| 692 return new Redirection(external_function, argument_count); | 693 return new Redirection(external_function, call_kind); |
| 693 } | 694 } |
| 694 | 695 |
| 695 static Redirection* FromSvcInstruction(Instr* svc_instruction) { | 696 static Redirection* FromSvcInstruction(Instr* svc_instruction) { |
| 696 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction); | 697 char* addr_of_svc = reinterpret_cast<char*>(svc_instruction); |
| 697 char* addr_of_redirection = | 698 char* addr_of_redirection = |
| 698 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_); | 699 addr_of_svc - OFFSET_OF(Redirection, svc_instruction_); |
| 699 return reinterpret_cast<Redirection*>(addr_of_redirection); | 700 return reinterpret_cast<Redirection*>(addr_of_redirection); |
| 700 } | 701 } |
| 701 | 702 |
| 702 private: | 703 private: |
| 703 static const int32_t kRedirectSvcInstruction = | 704 static const int32_t kRedirectSvcInstruction = |
| 704 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); | 705 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); |
| 705 Redirection(uword external_function, uint32_t argument_count) | 706 Redirection(uword external_function, Simulator::CallKind call_kind) |
| 706 : external_function_(external_function), | 707 : external_function_(external_function), |
| 707 argument_count_(argument_count), | 708 call_kind_(call_kind), |
| 708 svc_instruction_(kRedirectSvcInstruction), | 709 svc_instruction_(kRedirectSvcInstruction), |
| 709 next_(list_) { | 710 next_(list_) { |
| 710 list_ = this; | 711 list_ = this; |
| 711 } | 712 } |
| 712 | 713 |
| 713 uword external_function_; | 714 uword external_function_; |
| 714 const uint32_t argument_count_; | 715 Simulator::CallKind call_kind_; |
| 715 uint32_t svc_instruction_; | 716 uint32_t svc_instruction_; |
| 716 Redirection* next_; | 717 Redirection* next_; |
| 717 static Redirection* list_; | 718 static Redirection* list_; |
| 718 }; | 719 }; |
| 719 | 720 |
| 720 | 721 |
| 721 Redirection* Redirection::list_ = NULL; | 722 Redirection* Redirection::list_ = NULL; |
| 722 | 723 |
| 723 | 724 |
| 724 uword Simulator::RedirectExternalReference(uword function, | 725 uword Simulator::RedirectExternalReference(uword function, CallKind call_kind) { |
| 725 uint32_t argument_count) { | 726 Redirection* redirection = Redirection::Get(function, call_kind); |
| 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) { |
| 735 simulator = new Simulator(); | 735 simulator = new Simulator(); |
| 736 Isolate::Current()->set_simulator(simulator); | 736 Isolate::Current()->set_simulator(simulator); |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 address += 4; | 1291 address += 4; |
| 1292 } | 1292 } |
| 1293 reg++; | 1293 reg++; |
| 1294 rlist >>= 1; | 1294 rlist >>= 1; |
| 1295 } | 1295 } |
| 1296 ASSERT(end_address == address); | 1296 ASSERT(end_address == address); |
| 1297 } | 1297 } |
| 1298 } | 1298 } |
| 1299 | 1299 |
| 1300 | 1300 |
| 1301 // Calls into the Dart runtime are based on this simple interface. | 1301 // Calls into the Dart runtime are based on this interface. |
| 1302 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); | 1302 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); |
| 1303 | 1303 |
| 1304 | 1304 |
| 1305 static void PrintExternalCallTrace(intptr_t external, | 1305 // Calls to native Dart functions are based on this interface. |
| 1306 NativeArguments arguments) { | 1306 typedef void (*SimulatorNativeCall)(NativeArguments* arguments); |
| 1307 // TODO(regis): Do a reverse lookup on this address and print the symbol. | |
| 1308 UNIMPLEMENTED(); | |
| 1309 } | |
| 1310 | 1307 |
| 1311 | 1308 |
| 1312 void Simulator::SupervisorCall(Instr* instr) { | 1309 void Simulator::SupervisorCall(Instr* instr) { |
| 1313 int svc = instr->SvcField(); | 1310 int svc = instr->SvcField(); |
| 1314 switch (svc) { | 1311 switch (svc) { |
| 1315 case kRedirectionSvcCode: { | 1312 case kRedirectionSvcCode: { |
| 1316 SimulatorSetjmpBuffer buffer(this); | 1313 SimulatorSetjmpBuffer buffer(this); |
| 1317 | 1314 |
| 1318 if (!setjmp(buffer.buffer_)) { | 1315 if (!setjmp(buffer.buffer_)) { |
| 1319 NativeArguments arguments; | |
| 1320 ASSERT(sizeof(NativeArguments) == 4*kWordSize); | |
| 1321 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0)); | |
| 1322 arguments.argc_tag_ = get_register(R1); | |
| 1323 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2)); | |
| 1324 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3)); | |
| 1325 | |
| 1326 int32_t saved_lr = get_register(LR); | 1316 int32_t saved_lr = get_register(LR); |
| 1327 Redirection* redirection = Redirection::FromSvcInstruction(instr); | 1317 Redirection* redirection = Redirection::FromSvcInstruction(instr); |
| 1328 uword external = redirection->external_function(); | 1318 uword external = redirection->external_function(); |
| 1329 SimulatorRuntimeCall target = | |
| 1330 reinterpret_cast<SimulatorRuntimeCall>(external); | |
| 1331 if (FLAG_trace_sim) { | 1319 if (FLAG_trace_sim) { |
| 1332 PrintExternalCallTrace(external, arguments); | 1320 OS::Print("Call to host function at 0x%d\n", external); |
| 1333 } | 1321 } |
| 1334 target(arguments); | 1322 if (redirection->call_kind() == kRuntimeCall) { |
| 1323 NativeArguments arguments; |
| 1324 ASSERT(sizeof(NativeArguments) == 4*kWordSize); |
| 1325 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0)); |
| 1326 arguments.argc_tag_ = get_register(R1); |
| 1327 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2)); |
| 1328 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3)); |
| 1329 SimulatorRuntimeCall target = |
| 1330 reinterpret_cast<SimulatorRuntimeCall>(external); |
| 1331 target(arguments); |
| 1332 } else { |
| 1333 ASSERT(redirection->call_kind() == kNativeCall); |
| 1334 NativeArguments* arguments; |
| 1335 arguments = reinterpret_cast<NativeArguments*>(get_register(R0)); |
| 1336 SimulatorNativeCall target = |
| 1337 reinterpret_cast<SimulatorNativeCall>(external); |
| 1338 target(arguments); |
| 1339 } |
| 1335 | 1340 |
| 1336 // Zap caller-saved registers, since the actual runtime call could have | 1341 // Zap caller-saved registers, since the actual runtime call could have |
| 1337 // used them. | 1342 // used them. |
| 1338 set_register(R2, icount_); | 1343 set_register(R2, icount_); |
| 1339 set_register(R3, icount_); | 1344 set_register(R3, icount_); |
| 1340 set_register(IP, icount_); | 1345 set_register(IP, icount_); |
| 1341 set_register(LR, icount_); | 1346 set_register(LR, icount_); |
| 1342 float zap_fvalue = static_cast<float>(icount_); | 1347 float zap_fvalue = static_cast<float>(icount_); |
| 1343 for (int i = S0; i <= S15; i++) { | 1348 for (int i = S0; i <= S15; i++) { |
| 1344 set_sregister(static_cast<SRegister>(i), zap_fvalue); | 1349 set_sregister(static_cast<SRegister>(i), zap_fvalue); |
| (...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2839 // isolate->ChangeStateToGeneratedCode(); | 2844 // isolate->ChangeStateToGeneratedCode(); |
| 2840 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); | 2845 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); |
| 2841 buf->Longjmp(); | 2846 buf->Longjmp(); |
| 2842 } | 2847 } |
| 2843 | 2848 |
| 2844 } // namespace dart | 2849 } // namespace dart |
| 2845 | 2850 |
| 2846 #endif // !defined(HOST_ARCH_ARM) | 2851 #endif // !defined(HOST_ARCH_ARM) |
| 2847 | 2852 |
| 2848 #endif // defined TARGET_ARCH_ARM | 2853 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |