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 |