Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: runtime/vm/simulator_arm.cc

Issue 12629004: Implement native call stub on ARM and native call redirection in ARM simulator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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. 1307
1308 UNIMPLEMENTED(); 1308
1309 static void PrintExternalCallTrace(uword external) {
1310 const char* external_symbol = OS::ReverseLookupSymbol(external);
1311 if (external_symbol != NULL) {
1312 OS::Print("Call to host function %s\n", external_symbol);
1313 } else {
1314 OS::Print("Call to host function at 0x%d\n", external);
1315 }
1309 } 1316 }
1310 1317
1311 1318
1312 void Simulator::SupervisorCall(Instr* instr) { 1319 void Simulator::SupervisorCall(Instr* instr) {
1313 int svc = instr->SvcField(); 1320 int svc = instr->SvcField();
1314 switch (svc) { 1321 switch (svc) {
1315 case kRedirectionSvcCode: { 1322 case kRedirectionSvcCode: {
1316 SimulatorSetjmpBuffer buffer(this); 1323 SimulatorSetjmpBuffer buffer(this);
1317 1324
1318 if (!setjmp(buffer.buffer_)) { 1325 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); 1326 int32_t saved_lr = get_register(LR);
1327 Redirection* redirection = Redirection::FromSvcInstruction(instr); 1327 Redirection* redirection = Redirection::FromSvcInstruction(instr);
1328 uword external = redirection->external_function(); 1328 uword external = redirection->external_function();
1329 SimulatorRuntimeCall target = 1329 if (redirection->call_kind() == kRuntimeCall) {
1330 reinterpret_cast<SimulatorRuntimeCall>(external); 1330 NativeArguments arguments;
1331 if (FLAG_trace_sim) { 1331 ASSERT(sizeof(NativeArguments) == 4*kWordSize);
1332 PrintExternalCallTrace(external, arguments); 1332 arguments.isolate_ = reinterpret_cast<Isolate*>(get_register(R0));
1333 arguments.argc_tag_ = get_register(R1);
1334 arguments.argv_ = reinterpret_cast<RawObject*(*)[]>(get_register(R2));
1335 arguments.retval_ = reinterpret_cast<RawObject**>(get_register(R3));
1336 SimulatorRuntimeCall target =
1337 reinterpret_cast<SimulatorRuntimeCall>(external);
1338 if (FLAG_trace_sim) {
1339 PrintExternalCallTrace(external);
1340 }
1341 target(arguments);
1342 } else {
1343 ASSERT(redirection->call_kind() == kNativeCall);
1344 NativeArguments* arguments;
1345 arguments = reinterpret_cast<NativeArguments*>(get_register(R0));
1346 SimulatorNativeCall target =
1347 reinterpret_cast<SimulatorNativeCall>(external);
1348 if (FLAG_trace_sim) {
1349 PrintExternalCallTrace(external);
1350 }
1351 target(arguments);
1333 } 1352 }
1334 target(arguments);
1335 1353
1336 // Zap caller-saved registers, since the actual runtime call could have 1354 // Zap caller-saved registers, since the actual runtime call could have
1337 // used them. 1355 // used them.
1338 set_register(R2, icount_); 1356 set_register(R2, icount_);
1339 set_register(R3, icount_); 1357 set_register(R3, icount_);
1340 set_register(IP, icount_); 1358 set_register(IP, icount_);
1341 set_register(LR, icount_); 1359 set_register(LR, icount_);
1342 float zap_fvalue = static_cast<float>(icount_); 1360 float zap_fvalue = static_cast<float>(icount_);
1343 for (int i = S0; i <= S15; i++) { 1361 for (int i = S0; i <= S15; i++) {
1344 set_sregister(static_cast<SRegister>(i), zap_fvalue); 1362 set_sregister(static_cast<SRegister>(i), zap_fvalue);
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after
2839 // isolate->ChangeStateToGeneratedCode(); 2857 // isolate->ChangeStateToGeneratedCode();
2840 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); 2858 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw()));
2841 buf->Longjmp(); 2859 buf->Longjmp();
2842 } 2860 }
2843 2861
2844 } // namespace dart 2862 } // namespace dart
2845 2863
2846 #endif // !defined(HOST_ARCH_ARM) 2864 #endif // !defined(HOST_ARCH_ARM)
2847 2865
2848 #endif // defined TARGET_ARCH_ARM 2866 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698