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

Side by Side Diff: src/arm/simulator-arm.cc

Issue 6170001: Direct call api functions (arm implementation) (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 30 matching lines...) Expand all
41 41
42 // Only build the simulator if not compiling for real ARM hardware. 42 // Only build the simulator if not compiling for real ARM hardware.
43 namespace assembler { 43 namespace assembler {
44 namespace arm { 44 namespace arm {
45 45
46 using ::v8::internal::Object; 46 using ::v8::internal::Object;
47 using ::v8::internal::PrintF; 47 using ::v8::internal::PrintF;
48 using ::v8::internal::OS; 48 using ::v8::internal::OS;
49 using ::v8::internal::ReadLine; 49 using ::v8::internal::ReadLine;
50 using ::v8::internal::DeleteArray; 50 using ::v8::internal::DeleteArray;
51 using ::v8::internal::ExternalReference;
51 52
52 // This macro provides a platform independent use of sscanf. The reason for 53 // This macro provides a platform independent use of sscanf. The reason for
53 // SScanF not being implemented in a platform independent way through 54 // SScanF not being implemented in a platform independent way through
54 // ::v8::internal::OS in the same way as SNPrintF is that the 55 // ::v8::internal::OS in the same way as SNPrintF is that the
55 // Windows C Run-Time Library does not provide vsscanf. 56 // Windows C Run-Time Library does not provide vsscanf.
56 #define SScanF sscanf // NOLINT 57 #define SScanF sscanf // NOLINT
57 58
58 // The Debugger class is used by the simulator while debugging simulated ARM 59 // The Debugger class is used by the simulator while debugging simulated ARM
59 // code. 60 // code.
60 class Debugger { 61 class Debugger {
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 739
739 // When the generated code calls an external reference we need to catch that in 740 // When the generated code calls an external reference we need to catch that in
740 // the simulator. The external reference will be a function compiled for the 741 // the simulator. The external reference will be a function compiled for the
741 // host architecture. We need to call that function instead of trying to 742 // host architecture. We need to call that function instead of trying to
742 // execute it with the simulator. We do that by redirecting the external 743 // execute it with the simulator. We do that by redirecting the external
743 // reference to a svc (Supervisor Call) instruction that is handled by 744 // reference to a svc (Supervisor Call) instruction that is handled by
744 // the simulator. We write the original destination of the jump just at a known 745 // the simulator. We write the original destination of the jump just at a known
745 // offset from the svc instruction so the simulator knows what to call. 746 // offset from the svc instruction so the simulator knows what to call.
746 class Redirection { 747 class Redirection {
747 public: 748 public:
748 Redirection(void* external_function, bool fp_return) 749 Redirection(void* external_function, ExternalReference::Type type)
749 : external_function_(external_function), 750 : external_function_(external_function),
750 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected), 751 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
751 fp_return_(fp_return), 752 type_(type),
752 next_(list_) { 753 next_(list_) {
753 Simulator::current()-> 754 Simulator::current()->
754 FlushICache(reinterpret_cast<void*>(&swi_instruction_), 755 FlushICache(reinterpret_cast<void*>(&swi_instruction_),
755 Instr::kInstrSize); 756 Instr::kInstrSize);
756 list_ = this; 757 list_ = this;
757 } 758 }
758 759
759 void* address_of_swi_instruction() { 760 void* address_of_swi_instruction() {
760 return reinterpret_cast<void*>(&swi_instruction_); 761 return reinterpret_cast<void*>(&swi_instruction_);
761 } 762 }
762 763
763 void* external_function() { return external_function_; } 764 void* external_function() { return external_function_; }
764 bool fp_return() { return fp_return_; } 765 ExternalReference::Type type() { return type_; }
765 766
766 static Redirection* Get(void* external_function, bool fp_return) { 767 static Redirection* Get(void* external_function,
768 ExternalReference::Type type) {
767 Redirection* current; 769 Redirection* current;
768 for (current = list_; current != NULL; current = current->next_) { 770 for (current = list_; current != NULL; current = current->next_) {
769 if (current->external_function_ == external_function) return current; 771 if (current->external_function_ == external_function) return current;
770 } 772 }
771 return new Redirection(external_function, fp_return); 773 return new Redirection(external_function, type);
772 } 774 }
773 775
774 static Redirection* FromSwiInstruction(Instr* swi_instruction) { 776 static Redirection* FromSwiInstruction(Instr* swi_instruction) {
775 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); 777 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
776 char* addr_of_redirection = 778 char* addr_of_redirection =
777 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_); 779 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
778 return reinterpret_cast<Redirection*>(addr_of_redirection); 780 return reinterpret_cast<Redirection*>(addr_of_redirection);
779 } 781 }
780 782
781 private: 783 private:
782 void* external_function_; 784 void* external_function_;
783 uint32_t swi_instruction_; 785 uint32_t swi_instruction_;
784 bool fp_return_; 786 ExternalReference::Type type_;
785 Redirection* next_; 787 Redirection* next_;
786 static Redirection* list_; 788 static Redirection* list_;
787 }; 789 };
788 790
789 791
790 Redirection* Redirection::list_ = NULL; 792 Redirection* Redirection::list_ = NULL;
791 793
792 794
793 void* Simulator::RedirectExternalReference(void* external_function, 795 void* Simulator::RedirectExternalReference(void* external_function,
794 bool fp_return) { 796 ExternalReference::Type type) {
795 Redirection* redirection = Redirection::Get(external_function, fp_return); 797 Redirection* redirection = Redirection::Get(external_function, type);
796 return redirection->address_of_swi_instruction(); 798 return redirection->address_of_swi_instruction();
797 } 799 }
798 800
799 801
800 // Get the active Simulator for the current thread. 802 // Get the active Simulator for the current thread.
801 Simulator* Simulator::current() { 803 Simulator* Simulator::current() {
802 Initialize(); 804 Initialize();
803 Simulator* sim = reinterpret_cast<Simulator*>( 805 Simulator* sim = reinterpret_cast<Simulator*>(
804 v8::internal::Thread::GetThreadLocal(simulator_key)); 806 v8::internal::Thread::GetThreadLocal(simulator_key));
805 if (sim == NULL) { 807 if (sim == NULL) {
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, 1528 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
1527 int32_t arg1, 1529 int32_t arg1,
1528 int32_t arg2, 1530 int32_t arg2,
1529 int32_t arg3, 1531 int32_t arg3,
1530 int32_t arg4); 1532 int32_t arg4);
1531 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, 1533 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
1532 int32_t arg1, 1534 int32_t arg1,
1533 int32_t arg2, 1535 int32_t arg2,
1534 int32_t arg3); 1536 int32_t arg3);
1535 1537
1538 // This signature supports direct call in to API function native callback
1539 // (refer to InvocationCallback in v8.h).
1540 typedef v8::Handle<v8::Value> (*SimulatorRuntimeApiCall)(int32_t arg0);
1536 1541
1537 // Software interrupt instructions are used by the simulator to call into the 1542 // Software interrupt instructions are used by the simulator to call into the
1538 // C-based V8 runtime. 1543 // C-based V8 runtime.
1539 void Simulator::SoftwareInterrupt(Instr* instr) { 1544 void Simulator::SoftwareInterrupt(Instr* instr) {
1540 int svc = instr->SvcField(); 1545 int svc = instr->SvcField();
1541 switch (svc) { 1546 switch (svc) {
1542 case call_rt_redirected: { 1547 case call_rt_redirected: {
1543 // Check if stack is aligned. Error if not aligned is reported below to 1548 // Check if stack is aligned. Error if not aligned is reported below to
1544 // include information on the function called. 1549 // include information on the function called.
1545 bool stack_aligned = 1550 bool stack_aligned =
1546 (get_register(sp) 1551 (get_register(sp)
1547 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0; 1552 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;
1548 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1553 Redirection* redirection = Redirection::FromSwiInstruction(instr);
1549 int32_t arg0 = get_register(r0); 1554 int32_t arg0 = get_register(r0);
1550 int32_t arg1 = get_register(r1); 1555 int32_t arg1 = get_register(r1);
1551 int32_t arg2 = get_register(r2); 1556 int32_t arg2 = get_register(r2);
1552 int32_t arg3 = get_register(r3); 1557 int32_t arg3 = get_register(r3);
1553 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); 1558 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
1554 int32_t arg4 = *stack_pointer; 1559 int32_t arg4 = *stack_pointer;
1555 // This is dodgy but it works because the C entry stubs are never moved. 1560 // This is dodgy but it works because the C entry stubs are never moved.
1556 // See comment in codegen-arm.cc and bug 1242173. 1561 // See comment in codegen-arm.cc and bug 1242173.
1557 int32_t saved_lr = get_register(lr); 1562 int32_t saved_lr = get_register(lr);
1558 if (redirection->fp_return()) { 1563 intptr_t external =
1559 intptr_t external = 1564 reinterpret_cast<intptr_t>(redirection->external_function());
1560 reinterpret_cast<intptr_t>(redirection->external_function()); 1565 if (redirection->type() == ExternalReference::FP_RETURN_CALL) {
1561 SimulatorRuntimeFPCall target = 1566 SimulatorRuntimeFPCall target =
1562 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1567 reinterpret_cast<SimulatorRuntimeFPCall>(external);
1563 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1568 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1564 double x, y; 1569 double x, y;
1565 GetFpArgs(&x, &y); 1570 GetFpArgs(&x, &y);
1566 PrintF("Call to host function at %p with args %f, %f", 1571 PrintF("Call to host function at %p with args %f, %f",
1567 FUNCTION_ADDR(target), x, y); 1572 FUNCTION_ADDR(target), x, y);
1568 if (!stack_aligned) { 1573 if (!stack_aligned) {
1569 PrintF(" with unaligned stack %08x\n", get_register(sp)); 1574 PrintF(" with unaligned stack %08x\n", get_register(sp));
1570 } 1575 }
1571 PrintF("\n"); 1576 PrintF("\n");
1572 } 1577 }
1573 CHECK(stack_aligned); 1578 CHECK(stack_aligned);
1574 double result = target(arg0, arg1, arg2, arg3); 1579 double result = target(arg0, arg1, arg2, arg3);
1575 SetFpResult(result); 1580 SetFpResult(result);
1581 } else if (redirection->type() == ExternalReference::DIRECT_CALL) {
1582 SimulatorRuntimeApiCall target =
1583 reinterpret_cast<SimulatorRuntimeApiCall>(external);
1584 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1585 PrintF(
1586 "Call to host function at %p args %08x",
1587 FUNCTION_ADDR(target),
1588 arg0);
1589 if (!stack_aligned) {
1590 PrintF(" with unaligned stack %08x\n", get_register(sp));
1591 }
1592 PrintF("\n");
1593 }
1594 CHECK(stack_aligned);
1595 v8::Handle<v8::Value> result = target(arg0);
1596 if (::v8::internal::FLAG_trace_sim) {
1597 PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
1598 }
1599 set_register(r0, (int32_t) *result);
1576 } else { 1600 } else {
1577 intptr_t external = 1601 // builtin/runtime call
antonm 2011/01/26 11:36:38 nit: add a dot please. v8 style is to end comment
Zaheer 2011/02/02 10:05:59 Done.
1578 reinterpret_cast<int32_t>(redirection->external_function()); 1602 ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
1579 SimulatorRuntimeCall target = 1603 SimulatorRuntimeCall target =
1580 reinterpret_cast<SimulatorRuntimeCall>(external); 1604 reinterpret_cast<SimulatorRuntimeCall>(external);
1581 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1605 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1582 PrintF( 1606 PrintF(
1583 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc", 1607 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc",
1584 FUNCTION_ADDR(target), 1608 FUNCTION_ADDR(target),
1585 arg0, 1609 arg0,
1586 arg1, 1610 arg1,
1587 arg2, 1611 arg2,
1588 arg3, 1612 arg3,
(...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 uintptr_t address = *stack_slot; 3068 uintptr_t address = *stack_slot;
3045 set_register(sp, current_sp + sizeof(uintptr_t)); 3069 set_register(sp, current_sp + sizeof(uintptr_t));
3046 return address; 3070 return address;
3047 } 3071 }
3048 3072
3049 } } // namespace assembler::arm 3073 } } // namespace assembler::arm
3050 3074
3051 #endif // USE_SIMULATOR 3075 #endif // USE_SIMULATOR
3052 3076
3053 #endif // V8_TARGET_ARCH_ARM 3077 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/arm/stub-cache-arm.cc » ('j') | src/arm/stub-cache-arm.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698