OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #if V8_TARGET_ARCH_PPC | 9 #if V8_TARGET_ARCH_PPC |
10 | 10 |
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 ExternalReference::Type type) | 849 ExternalReference::Type type) |
850 : external_function_(external_function), | 850 : external_function_(external_function), |
851 swi_instruction_(rtCallRedirInstr | kCallRtRedirected), | 851 swi_instruction_(rtCallRedirInstr | kCallRtRedirected), |
852 type_(type), | 852 type_(type), |
853 next_(NULL) { | 853 next_(NULL) { |
854 next_ = isolate->simulator_redirection(); | 854 next_ = isolate->simulator_redirection(); |
855 Simulator::current(isolate)->FlushICache( | 855 Simulator::current(isolate)->FlushICache( |
856 isolate->simulator_i_cache(), | 856 isolate->simulator_i_cache(), |
857 reinterpret_cast<void*>(&swi_instruction_), Instruction::kInstrSize); | 857 reinterpret_cast<void*>(&swi_instruction_), Instruction::kInstrSize); |
858 isolate->set_simulator_redirection(this); | 858 isolate->set_simulator_redirection(this); |
| 859 if (ABI_USES_FUNCTION_DESCRIPTORS) { |
| 860 function_descriptor_[0] = reinterpret_cast<intptr_t>(&swi_instruction_); |
| 861 function_descriptor_[1] = 0; |
| 862 function_descriptor_[2] = 0; |
| 863 } |
859 } | 864 } |
860 | 865 |
861 void* address_of_swi_instruction() { | 866 void* address() { |
862 return reinterpret_cast<void*>(&swi_instruction_); | 867 if (ABI_USES_FUNCTION_DESCRIPTORS) { |
| 868 return reinterpret_cast<void*>(function_descriptor_); |
| 869 } else { |
| 870 return reinterpret_cast<void*>(&swi_instruction_); |
| 871 } |
863 } | 872 } |
864 | 873 |
865 void* external_function() { return external_function_; } | 874 void* external_function() { return external_function_; } |
866 ExternalReference::Type type() { return type_; } | 875 ExternalReference::Type type() { return type_; } |
867 | 876 |
868 static Redirection* Get(Isolate* isolate, void* external_function, | 877 static Redirection* Get(Isolate* isolate, void* external_function, |
869 ExternalReference::Type type) { | 878 ExternalReference::Type type) { |
870 Redirection* current = isolate->simulator_redirection(); | 879 Redirection* current = isolate->simulator_redirection(); |
871 for (; current != NULL; current = current->next_) { | 880 for (; current != NULL; current = current->next_) { |
872 if (current->external_function_ == external_function) { | 881 if (current->external_function_ == external_function) { |
873 DCHECK_EQ(current->type(), type); | 882 DCHECK_EQ(current->type(), type); |
874 return current; | 883 return current; |
875 } | 884 } |
876 } | 885 } |
877 return new Redirection(isolate, external_function, type); | 886 return new Redirection(isolate, external_function, type); |
878 } | 887 } |
879 | 888 |
880 static Redirection* FromSwiInstruction(Instruction* swi_instruction) { | 889 static Redirection* FromSwiInstruction(Instruction* swi_instruction) { |
881 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); | 890 char* addr_of_swi = reinterpret_cast<char*>(swi_instruction); |
882 char* addr_of_redirection = | 891 char* addr_of_redirection = |
883 addr_of_swi - offsetof(Redirection, swi_instruction_); | 892 addr_of_swi - offsetof(Redirection, swi_instruction_); |
884 return reinterpret_cast<Redirection*>(addr_of_redirection); | 893 return reinterpret_cast<Redirection*>(addr_of_redirection); |
885 } | 894 } |
886 | 895 |
| 896 static Redirection* FromAddress(void* address) { |
| 897 int delta = ABI_USES_FUNCTION_DESCRIPTORS |
| 898 ? offsetof(Redirection, function_descriptor_) |
| 899 : offsetof(Redirection, swi_instruction_); |
| 900 char* addr_of_redirection = reinterpret_cast<char*>(address) - delta; |
| 901 return reinterpret_cast<Redirection*>(addr_of_redirection); |
| 902 } |
| 903 |
887 static void* ReverseRedirection(intptr_t reg) { | 904 static void* ReverseRedirection(intptr_t reg) { |
888 Redirection* redirection = FromSwiInstruction( | 905 Redirection* redirection = FromAddress(reinterpret_cast<void*>(reg)); |
889 reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg))); | |
890 return redirection->external_function(); | 906 return redirection->external_function(); |
891 } | 907 } |
892 | 908 |
893 static void DeleteChain(Redirection* redirection) { | 909 static void DeleteChain(Redirection* redirection) { |
894 while (redirection != nullptr) { | 910 while (redirection != nullptr) { |
895 Redirection* next = redirection->next_; | 911 Redirection* next = redirection->next_; |
896 delete redirection; | 912 delete redirection; |
897 redirection = next; | 913 redirection = next; |
898 } | 914 } |
899 } | 915 } |
900 | 916 |
901 private: | 917 private: |
902 void* external_function_; | 918 void* external_function_; |
903 uint32_t swi_instruction_; | 919 uint32_t swi_instruction_; |
904 ExternalReference::Type type_; | 920 ExternalReference::Type type_; |
905 Redirection* next_; | 921 Redirection* next_; |
| 922 intptr_t function_descriptor_[3]; |
906 }; | 923 }; |
907 | 924 |
908 | 925 |
909 // static | 926 // static |
910 void Simulator::TearDown(HashMap* i_cache, Redirection* first) { | 927 void Simulator::TearDown(HashMap* i_cache, Redirection* first) { |
911 Redirection::DeleteChain(first); | 928 Redirection::DeleteChain(first); |
912 if (i_cache != nullptr) { | 929 if (i_cache != nullptr) { |
913 for (HashMap::Entry* entry = i_cache->Start(); entry != nullptr; | 930 for (HashMap::Entry* entry = i_cache->Start(); entry != nullptr; |
914 entry = i_cache->Next(entry)) { | 931 entry = i_cache->Next(entry)) { |
915 delete static_cast<CachePage*>(entry->value); | 932 delete static_cast<CachePage*>(entry->value); |
916 } | 933 } |
917 delete i_cache; | 934 delete i_cache; |
918 } | 935 } |
919 } | 936 } |
920 | 937 |
921 | 938 |
922 void* Simulator::RedirectExternalReference(Isolate* isolate, | 939 void* Simulator::RedirectExternalReference(Isolate* isolate, |
923 void* external_function, | 940 void* external_function, |
924 ExternalReference::Type type) { | 941 ExternalReference::Type type) { |
925 Redirection* redirection = Redirection::Get(isolate, external_function, type); | 942 Redirection* redirection = Redirection::Get(isolate, external_function, type); |
926 return redirection->address_of_swi_instruction(); | 943 return redirection->address(); |
927 } | 944 } |
928 | 945 |
929 | 946 |
930 // Get the active Simulator for the current thread. | 947 // Get the active Simulator for the current thread. |
931 Simulator* Simulator::current(Isolate* isolate) { | 948 Simulator* Simulator::current(Isolate* isolate) { |
932 v8::internal::Isolate::PerIsolateThreadData* isolate_data = | 949 v8::internal::Isolate::PerIsolateThreadData* isolate_data = |
933 isolate->FindOrAllocatePerThreadDataForThisThread(); | 950 isolate->FindOrAllocatePerThreadDataForThisThread(); |
934 DCHECK(isolate_data != NULL); | 951 DCHECK(isolate_data != NULL); |
935 | 952 |
936 Simulator* sim = isolate_data->simulator(); | 953 Simulator* sim = isolate_data->simulator(); |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 reinterpret_cast<void*>(external), arg[0], arg[1]); | 1396 reinterpret_cast<void*>(external), arg[0], arg[1]); |
1380 if (!stack_aligned) { | 1397 if (!stack_aligned) { |
1381 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", | 1398 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", |
1382 get_register(sp)); | 1399 get_register(sp)); |
1383 } | 1400 } |
1384 PrintF("\n"); | 1401 PrintF("\n"); |
1385 } | 1402 } |
1386 CHECK(stack_aligned); | 1403 CHECK(stack_aligned); |
1387 SimulatorRuntimeDirectGetterCall target = | 1404 SimulatorRuntimeDirectGetterCall target = |
1388 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); | 1405 reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); |
1389 #if !ABI_PASSES_HANDLES_IN_REGS | 1406 if (!ABI_PASSES_HANDLES_IN_REGS) { |
1390 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); | 1407 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); |
1391 #endif | 1408 } |
1392 target(arg[0], arg[1]); | 1409 target(arg[0], arg[1]); |
1393 } else if (redirection->type() == | 1410 } else if (redirection->type() == |
1394 ExternalReference::PROFILING_GETTER_CALL) { | 1411 ExternalReference::PROFILING_GETTER_CALL) { |
1395 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { | 1412 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |
1396 PrintF("Call to host function at %p args %08" V8PRIxPTR | 1413 PrintF("Call to host function at %p args %08" V8PRIxPTR |
1397 " %08" V8PRIxPTR " %08" V8PRIxPTR, | 1414 " %08" V8PRIxPTR " %08" V8PRIxPTR, |
1398 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]); | 1415 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]); |
1399 if (!stack_aligned) { | 1416 if (!stack_aligned) { |
1400 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", | 1417 PrintF(" with unaligned stack %08" V8PRIxPTR "\n", |
1401 get_register(sp)); | 1418 get_register(sp)); |
1402 } | 1419 } |
1403 PrintF("\n"); | 1420 PrintF("\n"); |
1404 } | 1421 } |
1405 CHECK(stack_aligned); | 1422 CHECK(stack_aligned); |
1406 SimulatorRuntimeProfilingGetterCall target = | 1423 SimulatorRuntimeProfilingGetterCall target = |
1407 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external); | 1424 reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external); |
1408 #if !ABI_PASSES_HANDLES_IN_REGS | 1425 if (!ABI_PASSES_HANDLES_IN_REGS) { |
1409 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); | 1426 arg[0] = *(reinterpret_cast<intptr_t*>(arg[0])); |
1410 #endif | 1427 } |
1411 target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2])); | 1428 target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2])); |
1412 } else { | 1429 } else { |
1413 // builtin call. | 1430 // builtin call. |
1414 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { | 1431 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |
1415 SimulatorRuntimeCall target = | 1432 SimulatorRuntimeCall target = |
1416 reinterpret_cast<SimulatorRuntimeCall>(external); | 1433 reinterpret_cast<SimulatorRuntimeCall>(external); |
1417 PrintF( | 1434 PrintF( |
1418 "Call to host function at %p,\n" | 1435 "Call to host function at %p,\n" |
1419 "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR | 1436 "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR |
1420 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, | 1437 ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR, |
(...skipping 2438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3859 program_counter = get_pc(); | 3876 program_counter = get_pc(); |
3860 } | 3877 } |
3861 } | 3878 } |
3862 } | 3879 } |
3863 | 3880 |
3864 | 3881 |
3865 void Simulator::CallInternal(byte* entry) { | 3882 void Simulator::CallInternal(byte* entry) { |
3866 // Adjust JS-based stack limit to C-based stack limit. | 3883 // Adjust JS-based stack limit to C-based stack limit. |
3867 isolate_->stack_guard()->AdjustStackLimitForSimulator(); | 3884 isolate_->stack_guard()->AdjustStackLimitForSimulator(); |
3868 | 3885 |
3869 // Prepare to execute the code at entry | 3886 // Prepare to execute the code at entry |
3870 #if ABI_USES_FUNCTION_DESCRIPTORS | 3887 if (ABI_USES_FUNCTION_DESCRIPTORS) { |
3871 // entry is the function descriptor | 3888 // entry is the function descriptor |
3872 set_pc(*(reinterpret_cast<intptr_t*>(entry))); | 3889 set_pc(*(reinterpret_cast<intptr_t*>(entry))); |
3873 #else | 3890 } else { |
3874 // entry is the instruction address | 3891 // entry is the instruction address |
3875 set_pc(reinterpret_cast<intptr_t>(entry)); | 3892 set_pc(reinterpret_cast<intptr_t>(entry)); |
3876 #endif | 3893 } |
3877 | 3894 |
3878 // Put target address in ip (for JS prologue). | 3895 if (ABI_CALL_VIA_IP) { |
3879 set_register(r12, get_pc()); | 3896 // Put target address in ip (for JS prologue). |
| 3897 set_register(r12, get_pc()); |
| 3898 } |
3880 | 3899 |
3881 // Put down marker for end of simulation. The simulator will stop simulation | 3900 // Put down marker for end of simulation. The simulator will stop simulation |
3882 // when the PC reaches this value. By saving the "end simulation" value into | 3901 // when the PC reaches this value. By saving the "end simulation" value into |
3883 // the LR the simulation stops when returning to this call point. | 3902 // the LR the simulation stops when returning to this call point. |
3884 special_reg_lr_ = end_sim_pc; | 3903 special_reg_lr_ = end_sim_pc; |
3885 | 3904 |
3886 // Remember the values of non-volatile registers. | 3905 // Remember the values of non-volatile registers. |
3887 intptr_t r2_val = get_register(r2); | 3906 intptr_t r2_val = get_register(r2); |
3888 intptr_t r13_val = get_register(r13); | 3907 intptr_t r13_val = get_register(r13); |
3889 intptr_t r14_val = get_register(r14); | 3908 intptr_t r14_val = get_register(r14); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3926 set_register(r27, callee_saved_value); | 3945 set_register(r27, callee_saved_value); |
3927 set_register(r28, callee_saved_value); | 3946 set_register(r28, callee_saved_value); |
3928 set_register(r29, callee_saved_value); | 3947 set_register(r29, callee_saved_value); |
3929 set_register(r30, callee_saved_value); | 3948 set_register(r30, callee_saved_value); |
3930 set_register(fp, callee_saved_value); | 3949 set_register(fp, callee_saved_value); |
3931 | 3950 |
3932 // Start the simulation | 3951 // Start the simulation |
3933 Execute(); | 3952 Execute(); |
3934 | 3953 |
3935 // Check that the non-volatile registers have been preserved. | 3954 // Check that the non-volatile registers have been preserved. |
3936 CHECK_EQ(callee_saved_value, get_register(r2)); | 3955 if (ABI_TOC_REGISTER != 2) { |
3937 CHECK_EQ(callee_saved_value, get_register(r13)); | 3956 CHECK_EQ(callee_saved_value, get_register(r2)); |
| 3957 } |
| 3958 if (ABI_TOC_REGISTER != 13) { |
| 3959 CHECK_EQ(callee_saved_value, get_register(r13)); |
| 3960 } |
3938 CHECK_EQ(callee_saved_value, get_register(r14)); | 3961 CHECK_EQ(callee_saved_value, get_register(r14)); |
3939 CHECK_EQ(callee_saved_value, get_register(r15)); | 3962 CHECK_EQ(callee_saved_value, get_register(r15)); |
3940 CHECK_EQ(callee_saved_value, get_register(r16)); | 3963 CHECK_EQ(callee_saved_value, get_register(r16)); |
3941 CHECK_EQ(callee_saved_value, get_register(r17)); | 3964 CHECK_EQ(callee_saved_value, get_register(r17)); |
3942 CHECK_EQ(callee_saved_value, get_register(r18)); | 3965 CHECK_EQ(callee_saved_value, get_register(r18)); |
3943 CHECK_EQ(callee_saved_value, get_register(r19)); | 3966 CHECK_EQ(callee_saved_value, get_register(r19)); |
3944 CHECK_EQ(callee_saved_value, get_register(r20)); | 3967 CHECK_EQ(callee_saved_value, get_register(r20)); |
3945 CHECK_EQ(callee_saved_value, get_register(r21)); | 3968 CHECK_EQ(callee_saved_value, get_register(r21)); |
3946 CHECK_EQ(callee_saved_value, get_register(r22)); | 3969 CHECK_EQ(callee_saved_value, get_register(r22)); |
3947 CHECK_EQ(callee_saved_value, get_register(r23)); | 3970 CHECK_EQ(callee_saved_value, get_register(r23)); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4054 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 4077 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
4055 uintptr_t address = *stack_slot; | 4078 uintptr_t address = *stack_slot; |
4056 set_register(sp, current_sp + sizeof(uintptr_t)); | 4079 set_register(sp, current_sp + sizeof(uintptr_t)); |
4057 return address; | 4080 return address; |
4058 } | 4081 } |
4059 } // namespace internal | 4082 } // namespace internal |
4060 } // namespace v8 | 4083 } // namespace v8 |
4061 | 4084 |
4062 #endif // USE_SIMULATOR | 4085 #endif // USE_SIMULATOR |
4063 #endif // V8_TARGET_ARCH_PPC | 4086 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |