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

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, 10 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 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 737
738 // When the generated code calls an external reference we need to catch that in 738 // When the generated code calls an external reference we need to catch that in
739 // the simulator. The external reference will be a function compiled for the 739 // the simulator. The external reference will be a function compiled for the
740 // host architecture. We need to call that function instead of trying to 740 // host architecture. We need to call that function instead of trying to
741 // execute it with the simulator. We do that by redirecting the external 741 // execute it with the simulator. We do that by redirecting the external
742 // reference to a svc (Supervisor Call) instruction that is handled by 742 // reference to a svc (Supervisor Call) instruction that is handled by
743 // the simulator. We write the original destination of the jump just at a known 743 // the simulator. We write the original destination of the jump just at a known
744 // offset from the svc instruction so the simulator knows what to call. 744 // offset from the svc instruction so the simulator knows what to call.
745 class Redirection { 745 class Redirection {
746 public: 746 public:
747 Redirection(void* external_function, bool fp_return) 747 Redirection(void* external_function, ExternalReference::Type type)
748 : external_function_(external_function), 748 : external_function_(external_function),
749 swi_instruction_(al | (0xf*B24) | kCallRtRedirected), 749 swi_instruction_(al | (0xf*B24) | kCallRtRedirected),
750 fp_return_(fp_return), 750 type_(type),
751 next_(list_) { 751 next_(list_) {
752 Simulator::current()-> 752 Simulator::current()->
753 FlushICache(reinterpret_cast<void*>(&swi_instruction_), 753 FlushICache(reinterpret_cast<void*>(&swi_instruction_),
754 Instruction::kInstrSize); 754 Instruction::kInstrSize);
755 list_ = this; 755 list_ = this;
756 } 756 }
757 757
758 void* address_of_swi_instruction() { 758 void* address_of_swi_instruction() {
759 return reinterpret_cast<void*>(&swi_instruction_); 759 return reinterpret_cast<void*>(&swi_instruction_);
760 } 760 }
761 761
762 void* external_function() { return external_function_; } 762 void* external_function() { return external_function_; }
763 bool fp_return() { return fp_return_; } 763 ExternalReference::Type type() { return type_; }
764 764
765 static Redirection* Get(void* external_function, bool fp_return) { 765 static Redirection* Get(void* external_function,
766 ExternalReference::Type type) {
766 Redirection* current; 767 Redirection* current;
767 for (current = list_; current != NULL; current = current->next_) { 768 for (current = list_; current != NULL; current = current->next_) {
768 if (current->external_function_ == external_function) return current; 769 if (current->external_function_ == external_function) return current;
769 } 770 }
770 return new Redirection(external_function, fp_return); 771 return new Redirection(external_function, type);
771 } 772 }
772 773
773 static Redirection* FromSwiInstruction(Instruction* swi_instruction) { 774 static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
774 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); 775 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
775 char* addr_of_redirection = 776 char* addr_of_redirection =
776 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_); 777 addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
777 return reinterpret_cast<Redirection*>(addr_of_redirection); 778 return reinterpret_cast<Redirection*>(addr_of_redirection);
778 } 779 }
779 780
780 private: 781 private:
781 void* external_function_; 782 void* external_function_;
782 uint32_t swi_instruction_; 783 uint32_t swi_instruction_;
783 bool fp_return_; 784 ExternalReference::Type type_;
784 Redirection* next_; 785 Redirection* next_;
785 static Redirection* list_; 786 static Redirection* list_;
786 }; 787 };
787 788
788 789
789 Redirection* Redirection::list_ = NULL; 790 Redirection* Redirection::list_ = NULL;
790 791
791 792
792 void* Simulator::RedirectExternalReference(void* external_function, 793 void* Simulator::RedirectExternalReference(void* external_function,
793 bool fp_return) { 794 ExternalReference::Type type) {
794 Redirection* redirection = Redirection::Get(external_function, fp_return); 795 Redirection* redirection = Redirection::Get(external_function, type);
795 return redirection->address_of_swi_instruction(); 796 return redirection->address_of_swi_instruction();
796 } 797 }
797 798
798 799
799 // Get the active Simulator for the current thread. 800 // Get the active Simulator for the current thread.
800 Simulator* Simulator::current() { 801 Simulator* Simulator::current() {
801 Initialize(); 802 Initialize();
802 Simulator* sim = reinterpret_cast<Simulator*>( 803 Simulator* sim = reinterpret_cast<Simulator*>(
803 v8::internal::Thread::GetThreadLocal(simulator_key)); 804 v8::internal::Thread::GetThreadLocal(simulator_key));
804 if (sim == NULL) { 805 if (sim == NULL) {
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, 1522 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0,
1522 int32_t arg1, 1523 int32_t arg1,
1523 int32_t arg2, 1524 int32_t arg2,
1524 int32_t arg3, 1525 int32_t arg3,
1525 int32_t arg4); 1526 int32_t arg4);
1526 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, 1527 typedef double (*SimulatorRuntimeFPCall)(int32_t arg0,
1527 int32_t arg1, 1528 int32_t arg1,
1528 int32_t arg2, 1529 int32_t arg2,
1529 int32_t arg3); 1530 int32_t arg3);
1530 1531
1532 // This signature supports direct call in to API function native callback
1533 // (refer to InvocationCallback in v8.h).
1534 typedef v8::Handle<v8::Value> (*SimulatorRuntimeApiCall)(int32_t arg0);
1531 1535
1532 // Software interrupt instructions are used by the simulator to call into the 1536 // Software interrupt instructions are used by the simulator to call into the
1533 // C-based V8 runtime. 1537 // C-based V8 runtime.
1534 void Simulator::SoftwareInterrupt(Instruction* instr) { 1538 void Simulator::SoftwareInterrupt(Instruction* instr) {
1535 int svc = instr->SvcValue(); 1539 int svc = instr->SvcValue();
1536 switch (svc) { 1540 switch (svc) {
1537 case kCallRtRedirected: { 1541 case kCallRtRedirected: {
1538 // Check if stack is aligned. Error if not aligned is reported below to 1542 // Check if stack is aligned. Error if not aligned is reported below to
1539 // include information on the function called. 1543 // include information on the function called.
1540 bool stack_aligned = 1544 bool stack_aligned =
1541 (get_register(sp) 1545 (get_register(sp)
1542 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0; 1546 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;
1543 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1547 Redirection* redirection = Redirection::FromSwiInstruction(instr);
1544 int32_t arg0 = get_register(r0); 1548 int32_t arg0 = get_register(r0);
1545 int32_t arg1 = get_register(r1); 1549 int32_t arg1 = get_register(r1);
1546 int32_t arg2 = get_register(r2); 1550 int32_t arg2 = get_register(r2);
1547 int32_t arg3 = get_register(r3); 1551 int32_t arg3 = get_register(r3);
1548 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); 1552 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
1549 int32_t arg4 = *stack_pointer; 1553 int32_t arg4 = *stack_pointer;
1550 // This is dodgy but it works because the C entry stubs are never moved. 1554 // This is dodgy but it works because the C entry stubs are never moved.
1551 // See comment in codegen-arm.cc and bug 1242173. 1555 // See comment in codegen-arm.cc and bug 1242173.
1552 int32_t saved_lr = get_register(lr); 1556 int32_t saved_lr = get_register(lr);
1553 if (redirection->fp_return()) { 1557 intptr_t external =
1554 intptr_t external = 1558 reinterpret_cast<intptr_t>(redirection->external_function());
1555 reinterpret_cast<intptr_t>(redirection->external_function()); 1559 if (redirection->type() == ExternalReference::FP_RETURN_CALL) {
1556 SimulatorRuntimeFPCall target = 1560 SimulatorRuntimeFPCall target =
1557 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1561 reinterpret_cast<SimulatorRuntimeFPCall>(external);
1558 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1562 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1559 double x, y; 1563 double x, y;
1560 GetFpArgs(&x, &y); 1564 GetFpArgs(&x, &y);
1561 PrintF("Call to host function at %p with args %f, %f", 1565 PrintF("Call to host function at %p with args %f, %f",
1562 FUNCTION_ADDR(target), x, y); 1566 FUNCTION_ADDR(target), x, y);
1563 if (!stack_aligned) { 1567 if (!stack_aligned) {
1564 PrintF(" with unaligned stack %08x\n", get_register(sp)); 1568 PrintF(" with unaligned stack %08x\n", get_register(sp));
1565 } 1569 }
1566 PrintF("\n"); 1570 PrintF("\n");
1567 } 1571 }
1568 CHECK(stack_aligned); 1572 CHECK(stack_aligned);
1569 double result = target(arg0, arg1, arg2, arg3); 1573 double result = target(arg0, arg1, arg2, arg3);
1570 SetFpResult(result); 1574 SetFpResult(result);
1575 } else if (redirection->type() == ExternalReference::DIRECT_CALL) {
1576 SimulatorRuntimeApiCall target =
1577 reinterpret_cast<SimulatorRuntimeApiCall>(external);
1578 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1579 PrintF(
1580 "Call to host function at %p args %08x",
1581 FUNCTION_ADDR(target),
1582 arg0);
1583 if (!stack_aligned) {
1584 PrintF(" with unaligned stack %08x\n", get_register(sp));
1585 }
1586 PrintF("\n");
1587 }
1588 CHECK(stack_aligned);
1589 v8::Handle<v8::Value> result = target(arg0);
1590 if (::v8::internal::FLAG_trace_sim) {
1591 PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
1592 }
1593 set_register(r0, (int32_t) *result);
1571 } else { 1594 } else {
1572 intptr_t external = 1595 // builtin call.
1573 reinterpret_cast<int32_t>(redirection->external_function()); 1596 ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
1574 SimulatorRuntimeCall target = 1597 SimulatorRuntimeCall target =
1575 reinterpret_cast<SimulatorRuntimeCall>(external); 1598 reinterpret_cast<SimulatorRuntimeCall>(external);
1576 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1599 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1577 PrintF( 1600 PrintF(
1578 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc", 1601 "Call to host function at %p args %08x, %08x, %08x, %08x, %0xc",
1579 FUNCTION_ADDR(target), 1602 FUNCTION_ADDR(target),
1580 arg0, 1603 arg0,
1581 arg1, 1604 arg1,
1582 arg2, 1605 arg2,
1583 arg3, 1606 arg3,
(...skipping 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after
3052 uintptr_t address = *stack_slot; 3075 uintptr_t address = *stack_slot;
3053 set_register(sp, current_sp + sizeof(uintptr_t)); 3076 set_register(sp, current_sp + sizeof(uintptr_t));
3054 return address; 3077 return address;
3055 } 3078 }
3056 3079
3057 } } // namespace v8::internal 3080 } } // namespace v8::internal
3058 3081
3059 #endif // USE_SIMULATOR 3082 #endif // USE_SIMULATOR
3060 3083
3061 #endif // V8_TARGET_ARCH_ARM 3084 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698