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

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, bool fp_return,
750 ExternalReference::Type type)
749 : external_function_(external_function), 751 : external_function_(external_function),
750 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected), 752 swi_instruction_((AL << 28) | (0xf << 24) | call_rt_redirected),
751 fp_return_(fp_return), 753 fp_return_(fp_return),
754 type_(type),
752 next_(list_) { 755 next_(list_) {
753 Simulator::current()-> 756 Simulator::current()->
754 FlushICache(reinterpret_cast<void*>(&swi_instruction_), 757 FlushICache(reinterpret_cast<void*>(&swi_instruction_),
755 Instr::kInstrSize); 758 Instr::kInstrSize);
756 list_ = this; 759 list_ = this;
757 } 760 }
758 761
759 void* address_of_swi_instruction() { 762 void* address_of_swi_instruction() {
760 return reinterpret_cast<void*>(&swi_instruction_); 763 return reinterpret_cast<void*>(&swi_instruction_);
761 } 764 }
762 765
763 void* external_function() { return external_function_; } 766 void* external_function() { return external_function_; }
764 bool fp_return() { return fp_return_; } 767 bool fp_return() { return fp_return_; }
768 ExternalReference::Type type() { return type_; }
765 769
766 static Redirection* Get(void* external_function, bool fp_return) { 770 static Redirection* Get(void* external_function, bool fp_return,
771 ExternalReference::Type type) {
767 Redirection* current; 772 Redirection* current;
768 for (current = list_; current != NULL; current = current->next_) { 773 for (current = list_; current != NULL; current = current->next_) {
769 if (current->external_function_ == external_function) return current; 774 if (current->external_function_ == external_function) return current;
770 } 775 }
771 return new Redirection(external_function, fp_return); 776 return new Redirection(external_function, fp_return, type);
772 } 777 }
773 778
774 static Redirection* FromSwiInstruction(Instr* swi_instruction) { 779 static Redirection* FromSwiInstruction(Instr* swi_instruction) {
775 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); 780 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
776 char* addr_of_redirection = 781 char* addr_of_redirection =
777 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_); 782 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
778 return reinterpret_cast<Redirection*>(addr_of_redirection); 783 return reinterpret_cast<Redirection*>(addr_of_redirection);
779 } 784 }
780 785
781 private: 786 private:
782 void* external_function_; 787 void* external_function_;
783 uint32_t swi_instruction_; 788 uint32_t swi_instruction_;
784 bool fp_return_; 789 bool fp_return_;
790 ExternalReference::Type type_;
785 Redirection* next_; 791 Redirection* next_;
786 static Redirection* list_; 792 static Redirection* list_;
787 }; 793 };
788 794
789 795
790 Redirection* Redirection::list_ = NULL; 796 Redirection* Redirection::list_ = NULL;
791 797
792 798
793 void* Simulator::RedirectExternalReference(void* external_function, 799 void* Simulator::RedirectExternalReference(
794 bool fp_return) { 800 void* external_function, bool fp_return, ExternalReference::Type type) {
Erik Corry 2011/01/21 14:28:40 You shouldn't need both the bool for the fp_return
Zaheer 2011/01/24 09:43:31 Done.
795 Redirection* redirection = Redirection::Get(external_function, fp_return); 801 Redirection* redirection = Redirection::Get(
802 external_function, fp_return, type);
796 return redirection->address_of_swi_instruction(); 803 return redirection->address_of_swi_instruction();
797 } 804 }
798 805
799 806
800 // Get the active Simulator for the current thread. 807 // Get the active Simulator for the current thread.
801 Simulator* Simulator::current() { 808 Simulator* Simulator::current() {
802 Initialize(); 809 Initialize();
803 Simulator* sim = reinterpret_cast<Simulator*>( 810 Simulator* sim = reinterpret_cast<Simulator*>(
804 v8::internal::Thread::GetThreadLocal(simulator_key)); 811 v8::internal::Thread::GetThreadLocal(simulator_key));
805 if (sim == NULL) { 812 if (sim == NULL) {
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, 1533 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
1527 int32_t arg1, 1534 int32_t arg1,
1528 int32_t arg2, 1535 int32_t arg2,
1529 int32_t arg3, 1536 int32_t arg3,
1530 int32_t arg4); 1537 int32_t arg4);
1531 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, 1538 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
1532 int32_t arg1, 1539 int32_t arg1,
1533 int32_t arg2, 1540 int32_t arg2,
1534 int32_t arg3); 1541 int32_t arg3);
1535 1542
1543 // This signature supports direct call in to js function native callback
antonm 2011/01/21 17:56:36 I'd use API function instead of js function here
Zaheer 2011/01/24 09:43:31 Done.
1544 // (refer to InvocationCallback in v8.h).
1545 typedef v8::Handle<v8::Value> (*SimulatorRuntimeApiCall)(int32_t arg0);
1536 1546
1537 // Software interrupt instructions are used by the simulator to call into the 1547 // Software interrupt instructions are used by the simulator to call into the
1538 // C-based V8 runtime. 1548 // C-based V8 runtime.
1539 void Simulator::SoftwareInterrupt(Instr* instr) { 1549 void Simulator::SoftwareInterrupt(Instr* instr) {
1540 int svc = instr->SvcField(); 1550 int svc = instr->SvcField();
1541 switch (svc) { 1551 switch (svc) {
1542 case call_rt_redirected: { 1552 case call_rt_redirected: {
1543 // Check if stack is aligned. Error if not aligned is reported below to 1553 // Check if stack is aligned. Error if not aligned is reported below to
1544 // include information on the function called. 1554 // include information on the function called.
1545 bool stack_aligned = 1555 bool stack_aligned =
(...skipping 21 matching lines...) Expand all
1567 FUNCTION_ADDR(target), x, y); 1577 FUNCTION_ADDR(target), x, y);
1568 if (!stack_aligned) { 1578 if (!stack_aligned) {
1569 PrintF(" with unaligned stack %08x\n", get_register(sp)); 1579 PrintF(" with unaligned stack %08x\n", get_register(sp));
1570 } 1580 }
1571 PrintF("\n"); 1581 PrintF("\n");
1572 } 1582 }
1573 CHECK(stack_aligned); 1583 CHECK(stack_aligned);
1574 double result = target(arg0, arg1, arg2, arg3); 1584 double result = target(arg0, arg1, arg2, arg3);
1575 SetFpResult(result); 1585 SetFpResult(result);
1576 } else { 1586 } else {
1577 intptr_t external = 1587 if (redirection->type() == ExternalReference::DIRECT_CALL) {
1578 reinterpret_cast<int32_t>(redirection->external_function()); 1588 intptr_t external =
1579 SimulatorRuntimeCall target = 1589 reinterpret_cast<int32_t>(redirection->external_function());
1580 reinterpret_cast<SimulatorRuntimeCall>(external); 1590 SimulatorRuntimeApiCall target =
antonm 2011/01/21 17:56:36 please, consider refactoring the common logic of l
Zaheer 2011/01/24 09:43:31 The log is unique to each case, the stack alignmen
antonm 2011/01/26 11:36:37 Ok, let's leave it as you have it now.
1581 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1591 reinterpret_cast<SimulatorRuntimeApiCall>(external);
1582 PrintF( 1592 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1583 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc", 1593 PrintF(
1584 FUNCTION_ADDR(target), 1594 "Call to host function at %p args %08x",
1585 arg0, 1595 FUNCTION_ADDR(target),
1586 arg1, 1596 arg0);
1587 arg2, 1597 if (!stack_aligned) {
1588 arg3, 1598 PrintF(" with unaligned stack %08x\n", get_register(sp));
1589 arg4); 1599 }
1590 if (!stack_aligned) { 1600 PrintF("\n");
1591 PrintF(" with unaligned stack %08x\n", get_register(sp));
1592 } 1601 }
1593 PrintF("\n"); 1602 CHECK(stack_aligned);
1603 v8::Handle<v8::Value> result = target(arg0);
1604 if (::v8::internal::FLAG_trace_sim) {
1605 PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
1606 }
1607 set_register(r0, (int32_t) *result);
1608 } else {
1609 intptr_t external =
1610 reinterpret_cast<int32_t>(redirection->external_function());
1611 SimulatorRuntimeCall target =
1612 reinterpret_cast<SimulatorRuntimeCall>(external);
1613 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1614 PrintF(
1615 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc",
1616 FUNCTION_ADDR(target),
1617 arg0,
1618 arg1,
1619 arg2,
1620 arg3,
1621 arg4);
1622 if (!stack_aligned) {
1623 PrintF(" with unaligned stack %08x\n", get_register(sp));
1624 }
1625 PrintF("\n");
1626 }
1627 CHECK(stack_aligned);
1628 int64_t result = target(arg0, arg1, arg2, arg3, arg4);
1629 int32_t lo_res = static_cast<int32_t>(result);
1630 int32_t hi_res = static_cast<int32_t>(result >> 32);
1631 if (::v8::internal::FLAG_trace_sim) {
1632 PrintF("Returned %08x\n", lo_res);
1633 }
1634 set_register(r0, lo_res);
1635 set_register(r1, hi_res);
1594 } 1636 }
1595 CHECK(stack_aligned);
1596 int64_t result = target(arg0, arg1, arg2, arg3, arg4);
1597 int32_t lo_res = static_cast<int32_t>(result);
1598 int32_t hi_res = static_cast<int32_t>(result >> 32);
1599 if (::v8::internal::FLAG_trace_sim) {
1600 PrintF("Returned %08x\n", lo_res);
1601 }
1602 set_register(r0, lo_res);
1603 set_register(r1, hi_res);
1604 } 1637 }
1605 set_register(lr, saved_lr); 1638 set_register(lr, saved_lr);
1606 set_pc(get_register(lr)); 1639 set_pc(get_register(lr));
1607 break; 1640 break;
1608 } 1641 }
1609 case break_point: { 1642 case break_point: {
1610 Debugger dbg(this); 1643 Debugger dbg(this);
1611 dbg.Debug(); 1644 dbg.Debug();
1612 break; 1645 break;
1613 } 1646 }
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 uintptr_t address = *stack_slot; 3077 uintptr_t address = *stack_slot;
3045 set_register(sp, current_sp + sizeof(uintptr_t)); 3078 set_register(sp, current_sp + sizeof(uintptr_t));
3046 return address; 3079 return address;
3047 } 3080 }
3048 3081
3049 } } // namespace assembler::arm 3082 } } // namespace assembler::arm
3050 3083
3051 #endif // USE_SIMULATOR 3084 #endif // USE_SIMULATOR
3052 3085
3053 #endif // V8_TARGET_ARCH_ARM 3086 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698