| 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 |