| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 Simulator* sim = isolate_data->simulator(); | 105 Simulator* sim = isolate_data->simulator(); |
| 106 if (sim == NULL) { | 106 if (sim == NULL) { |
| 107 // TODO(146): delete the simulator object when a thread/isolate goes away. | 107 // TODO(146): delete the simulator object when a thread/isolate goes away. |
| 108 sim = new Simulator(new Decoder(), isolate); | 108 sim = new Simulator(new Decoder(), isolate); |
| 109 isolate_data->set_simulator(sim); | 109 isolate_data->set_simulator(sim); |
| 110 } | 110 } |
| 111 return sim; | 111 return sim; |
| 112 } | 112 } |
| 113 | 113 |
| 114 | 114 |
| 115 void Simulator::CallVoid(byte* entry, va_list args) { | 115 void Simulator::CallVoid(byte* entry, CallArgument* args) { |
| 116 int index_x = 0; | 116 int index_x = 0; |
| 117 int index_d = 0; | 117 int index_d = 0; |
| 118 | 118 |
| 119 // At this point, we don't know how much stack space we need (for arguments | |
| 120 // that don't fit into registers). We can only do one pass through the | |
| 121 // va_list, so we store the extra arguments in a vector, then copy them to | |
| 122 // their proper locations later. | |
| 123 std::vector<int64_t> stack_args(0); | 119 std::vector<int64_t> stack_args(0); |
| 124 | 120 for (int i = 0; !args[i].IsEnd(); i++) { |
| 125 // Process register arguments. | 121 CallArgument arg = args[i]; |
| 126 CallArgument arg = va_arg(args, CallArgument); | |
| 127 while (!arg.IsEnd()) { | |
| 128 if (arg.IsX() && (index_x < 8)) { | 122 if (arg.IsX() && (index_x < 8)) { |
| 129 set_xreg(index_x++, arg.bits()); | 123 set_xreg(index_x++, arg.bits()); |
| 130 } else if (arg.IsD() && (index_d < 8)) { | 124 } else if (arg.IsD() && (index_d < 8)) { |
| 131 set_dreg_bits(index_d++, arg.bits()); | 125 set_dreg_bits(index_d++, arg.bits()); |
| 132 } else { | 126 } else { |
| 133 ASSERT(arg.IsD() || arg.IsX()); | 127 ASSERT(arg.IsD() || arg.IsX()); |
| 134 stack_args.push_back(arg.bits()); | 128 stack_args.push_back(arg.bits()); |
| 135 } | 129 } |
| 136 arg = va_arg(args, CallArgument); | |
| 137 } | 130 } |
| 138 | 131 |
| 139 // Process stack arguments, and make sure the stack is suitably aligned. | 132 // Process stack arguments, and make sure the stack is suitably aligned. |
| 140 uintptr_t original_stack = sp(); | 133 uintptr_t original_stack = sp(); |
| 141 uintptr_t entry_stack = original_stack - | 134 uintptr_t entry_stack = original_stack - |
| 142 stack_args.size() * sizeof(stack_args[0]); | 135 stack_args.size() * sizeof(stack_args[0]); |
| 143 if (OS::ActivationFrameAlignment() != 0) { | 136 if (OS::ActivationFrameAlignment() != 0) { |
| 144 entry_stack &= -OS::ActivationFrameAlignment(); | 137 entry_stack &= -OS::ActivationFrameAlignment(); |
| 145 } | 138 } |
| 146 char * stack = reinterpret_cast<char*>(entry_stack); | 139 char * stack = reinterpret_cast<char*>(entry_stack); |
| 147 std::vector<int64_t>::const_iterator it; | 140 std::vector<int64_t>::const_iterator it; |
| 148 for (it = stack_args.begin(); it != stack_args.end(); it++) { | 141 for (it = stack_args.begin(); it != stack_args.end(); it++) { |
| 149 memcpy(stack, &(*it), sizeof(*it)); | 142 memcpy(stack, &(*it), sizeof(*it)); |
| 150 stack += sizeof(*it); | 143 stack += sizeof(*it); |
| 151 } | 144 } |
| 152 | 145 |
| 153 ASSERT(reinterpret_cast<uintptr_t>(stack) <= original_stack); | 146 ASSERT(reinterpret_cast<uintptr_t>(stack) <= original_stack); |
| 154 set_sp(entry_stack); | 147 set_sp(entry_stack); |
| 155 | 148 |
| 156 // Call the generated code. | 149 // Call the generated code. |
| 157 set_pc(entry); | 150 set_pc(entry); |
| 158 set_lr(kEndOfSimAddress); | 151 set_lr(kEndOfSimAddress); |
| 159 CheckPCSComplianceAndRun(); | 152 CheckPCSComplianceAndRun(); |
| 160 | 153 |
| 161 set_sp(original_stack); | 154 set_sp(original_stack); |
| 162 } | 155 } |
| 163 | 156 |
| 164 | 157 |
| 165 | 158 int64_t Simulator::CallInt64(byte* entry, CallArgument* args) { |
| 166 void Simulator::CallVoid(byte* entry, ...) { | |
| 167 va_list args; | |
| 168 va_start(args, entry); | |
| 169 CallVoid(entry, args); | 159 CallVoid(entry, args); |
| 170 va_end(args); | |
| 171 } | |
| 172 | |
| 173 | |
| 174 int64_t Simulator::CallInt64(byte* entry, ...) { | |
| 175 va_list args; | |
| 176 va_start(args, entry); | |
| 177 CallVoid(entry, args); | |
| 178 va_end(args); | |
| 179 | |
| 180 return xreg(0); | 160 return xreg(0); |
| 181 } | 161 } |
| 182 | 162 |
| 183 | 163 |
| 184 double Simulator::CallDouble(byte* entry, ...) { | 164 double Simulator::CallDouble(byte* entry, CallArgument* args) { |
| 185 va_list args; | |
| 186 va_start(args, entry); | |
| 187 CallVoid(entry, args); | 165 CallVoid(entry, args); |
| 188 va_end(args); | |
| 189 | |
| 190 return dreg(0); | 166 return dreg(0); |
| 191 } | 167 } |
| 192 | 168 |
| 193 | 169 |
| 194 int64_t Simulator::CallJS(byte* entry, | 170 int64_t Simulator::CallJS(byte* entry, |
| 195 byte* function_entry, | 171 byte* function_entry, |
| 196 JSFunction* func, | 172 JSFunction* func, |
| 197 Object* revc, | 173 Object* revc, |
| 198 int64_t argc, | 174 int64_t argc, |
| 199 Object*** argv) { | 175 Object*** argv) { |
| 200 return CallInt64(entry, | 176 CallArgument args[] = { |
| 201 CallArgument(function_entry), | 177 CallArgument(function_entry), |
| 202 CallArgument(func), | 178 CallArgument(func), |
| 203 CallArgument(revc), | 179 CallArgument(revc), |
| 204 CallArgument(argc), | 180 CallArgument(argc), |
| 205 CallArgument(argv), | 181 CallArgument(argv), |
| 206 CallArgument::End()); | 182 CallArgument::End() |
| 183 }; |
| 184 return CallInt64(entry, args); |
| 207 } | 185 } |
| 208 | 186 |
| 209 int64_t Simulator::CallRegExp(byte* entry, | 187 int64_t Simulator::CallRegExp(byte* entry, |
| 210 String* input, | 188 String* input, |
| 211 int64_t start_offset, | 189 int64_t start_offset, |
| 212 const byte* input_start, | 190 const byte* input_start, |
| 213 const byte* input_end, | 191 const byte* input_end, |
| 214 int* output, | 192 int* output, |
| 215 int64_t output_size, | 193 int64_t output_size, |
| 216 Address stack_base, | 194 Address stack_base, |
| 217 int64_t direct_call, | 195 int64_t direct_call, |
| 218 void* return_address, | 196 void* return_address, |
| 219 Isolate* isolate) { | 197 Isolate* isolate) { |
| 220 return CallInt64(entry, | 198 CallArgument args[] = { |
| 221 CallArgument(input), | 199 CallArgument(input), |
| 222 CallArgument(start_offset), | 200 CallArgument(start_offset), |
| 223 CallArgument(input_start), | 201 CallArgument(input_start), |
| 224 CallArgument(input_end), | 202 CallArgument(input_end), |
| 225 CallArgument(output), | 203 CallArgument(output), |
| 226 CallArgument(output_size), | 204 CallArgument(output_size), |
| 227 CallArgument(stack_base), | 205 CallArgument(stack_base), |
| 228 CallArgument(direct_call), | 206 CallArgument(direct_call), |
| 229 CallArgument(return_address), | 207 CallArgument(return_address), |
| 230 CallArgument(isolate), | 208 CallArgument(isolate), |
| 231 CallArgument::End()); | 209 CallArgument::End() |
| 210 }; |
| 211 return CallInt64(entry, args); |
| 232 } | 212 } |
| 233 | 213 |
| 234 | 214 |
| 235 void Simulator::CheckPCSComplianceAndRun() { | 215 void Simulator::CheckPCSComplianceAndRun() { |
| 236 #ifdef DEBUG | 216 #ifdef DEBUG |
| 237 CHECK_EQ(kNumberOfCalleeSavedRegisters, kCalleeSaved.Count()); | 217 CHECK_EQ(kNumberOfCalleeSavedRegisters, kCalleeSaved.Count()); |
| 238 CHECK_EQ(kNumberOfCalleeSavedFPRegisters, kCalleeSavedFP.Count()); | 218 CHECK_EQ(kNumberOfCalleeSavedFPRegisters, kCalleeSavedFP.Count()); |
| 239 | 219 |
| 240 int64_t saved_registers[kNumberOfCalleeSavedRegisters]; | 220 int64_t saved_registers[kNumberOfCalleeSavedRegisters]; |
| 241 uint64_t saved_fpregisters[kNumberOfCalleeSavedFPRegisters]; | 221 uint64_t saved_fpregisters[kNumberOfCalleeSavedFPRegisters]; |
| (...skipping 2698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2940 } else { // "mem" | 2920 } else { // "mem" |
| 2941 int64_t value; | 2921 int64_t value; |
| 2942 if (!GetValue(arg1, &value)) { | 2922 if (!GetValue(arg1, &value)) { |
| 2943 PrintF("%s unrecognized\n", arg1); | 2923 PrintF("%s unrecognized\n", arg1); |
| 2944 continue; | 2924 continue; |
| 2945 } | 2925 } |
| 2946 cur = reinterpret_cast<int64_t*>(value); | 2926 cur = reinterpret_cast<int64_t*>(value); |
| 2947 next_arg++; | 2927 next_arg++; |
| 2948 } | 2928 } |
| 2949 | 2929 |
| 2950 int64_t words; | 2930 int64_t words = 0; |
| 2951 if (argc == next_arg) { | 2931 if (argc == next_arg) { |
| 2952 words = 10; | 2932 words = 10; |
| 2953 } else if (argc == next_arg + 1) { | 2933 } else if (argc == next_arg + 1) { |
| 2954 if (!GetValue(argv[next_arg], &words)) { | 2934 if (!GetValue(argv[next_arg], &words)) { |
| 2955 PrintF("%s unrecognized\n", argv[next_arg]); | 2935 PrintF("%s unrecognized\n", argv[next_arg]); |
| 2956 PrintF("Printing 10 double words by default"); | 2936 PrintF("Printing 10 double words by default"); |
| 2957 words = 10; | 2937 words = 10; |
| 2958 } | 2938 } |
| 2939 } else { |
| 2940 UNREACHABLE(); |
| 2959 } | 2941 } |
| 2960 end = cur + words; | 2942 end = cur + words; |
| 2961 | 2943 |
| 2962 while (cur < end) { | 2944 while (cur < end) { |
| 2963 PrintF(" 0x%016" PRIx64 ": 0x%016" PRIx64 " %10" PRId64, | 2945 PrintF(" 0x%016" PRIx64 ": 0x%016" PRIx64 " %10" PRId64, |
| 2964 reinterpret_cast<uint64_t>(cur), *cur, *cur); | 2946 reinterpret_cast<uint64_t>(cur), *cur, *cur); |
| 2965 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); | 2947 HeapObject* obj = reinterpret_cast<HeapObject*>(*cur); |
| 2966 int64_t value = *cur; | 2948 int64_t value = *cur; |
| 2967 Heap* current_heap = v8::internal::Isolate::Current()->heap(); | 2949 Heap* current_heap = v8::internal::Isolate::Current()->heap(); |
| 2968 if (((value & 1) == 0) || current_heap->Contains(obj)) { | 2950 if (((value & 1) == 0) || current_heap->Contains(obj)) { |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3420 default: | 3402 default: |
| 3421 UNIMPLEMENTED(); | 3403 UNIMPLEMENTED(); |
| 3422 } | 3404 } |
| 3423 } | 3405 } |
| 3424 | 3406 |
| 3425 #endif // USE_SIMULATOR | 3407 #endif // USE_SIMULATOR |
| 3426 | 3408 |
| 3427 } } // namespace v8::internal | 3409 } } // namespace v8::internal |
| 3428 | 3410 |
| 3429 #endif // V8_TARGET_ARCH_A64 | 3411 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |