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

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
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/stub_code_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
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
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
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/stub_code_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698