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

Side by Side Diff: src/arm/deoptimizer-arm.cc

Issue 21340002: Generate a custom OSR entrypoint for OSR compiles on all platforms, and transition to optimized cod… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remerge with recent changes. Created 7 years, 3 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 ASSERT_EQ(kBranchBeforeInterrupt, 168 ASSERT_EQ(kBranchBeforeInterrupt,
169 Memory::int32_at(pc_after - 3 * kInstrSize)); 169 Memory::int32_at(pc_after - 3 * kInstrSize));
170 ASSERT(reinterpret_cast<uint32_t>(interrupt_builtin->entry()) == 170 ASSERT(reinterpret_cast<uint32_t>(interrupt_builtin->entry()) ==
171 Memory::uint32_at(interrupt_address_pointer)); 171 Memory::uint32_at(interrupt_address_pointer));
172 return NOT_PATCHED; 172 return NOT_PATCHED;
173 } 173 }
174 } 174 }
175 #endif // DEBUG 175 #endif // DEBUG
176 176
177 177
178 static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
179 ByteArray* translations = data->TranslationByteArray();
180 int length = data->DeoptCount();
181 for (int i = 0; i < length; i++) {
182 if (data->AstId(i) == ast_id) {
183 TranslationIterator it(translations, data->TranslationIndex(i)->value());
184 int value = it.Next();
185 ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
186 // Read the number of frames.
187 value = it.Next();
188 if (value == 1) return i;
189 }
190 }
191 UNREACHABLE();
192 return -1;
193 }
194
195
196 void Deoptimizer::DoComputeOsrOutputFrame() {
197 DeoptimizationInputData* data = DeoptimizationInputData::cast(
198 compiled_code_->deoptimization_data());
199 unsigned ast_id = data->OsrAstId()->value();
200
201 int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
202 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
203 ByteArray* translations = data->TranslationByteArray();
204
205 TranslationIterator iterator(translations, translation_index);
206 Translation::Opcode opcode =
207 static_cast<Translation::Opcode>(iterator.Next());
208 ASSERT(Translation::BEGIN == opcode);
209 USE(opcode);
210 int count = iterator.Next();
211 iterator.Skip(1); // Drop JS frame count.
212 ASSERT(count == 1);
213 USE(count);
214
215 opcode = static_cast<Translation::Opcode>(iterator.Next());
216 USE(opcode);
217 ASSERT(Translation::JS_FRAME == opcode);
218 unsigned node_id = iterator.Next();
219 USE(node_id);
220 ASSERT(node_id == ast_id);
221 int closure_id = iterator.Next();
222 USE(closure_id);
223 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
224 unsigned height = iterator.Next();
225 unsigned height_in_bytes = height * kPointerSize;
226 USE(height_in_bytes);
227
228 unsigned fixed_size = ComputeFixedSize(function_);
229 unsigned input_frame_size = input_->GetFrameSize();
230 ASSERT(fixed_size + height_in_bytes == input_frame_size);
231
232 unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
233 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
234 unsigned outgoing_size = outgoing_height * kPointerSize;
235 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
236 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
237
238 if (FLAG_trace_osr) {
239 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
240 reinterpret_cast<intptr_t>(function_));
241 PrintFunctionName();
242 PrintF(" => node=%u, frame=%d->%d]\n",
243 ast_id,
244 input_frame_size,
245 output_frame_size);
246 }
247
248 // There's only one output frame in the OSR case.
249 output_count_ = 1;
250 output_ = new FrameDescription*[1];
251 output_[0] = new(output_frame_size) FrameDescription(
252 output_frame_size, function_);
253 output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT);
254
255 // Clear the incoming parameters in the optimized frame to avoid
256 // confusing the garbage collector.
257 unsigned output_offset = output_frame_size - kPointerSize;
258 int parameter_count = function_->shared()->formal_parameter_count() + 1;
259 for (int i = 0; i < parameter_count; ++i) {
260 output_[0]->SetFrameSlot(output_offset, 0);
261 output_offset -= kPointerSize;
262 }
263
264 // Translate the incoming parameters. This may overwrite some of the
265 // incoming argument slots we've just cleared.
266 int input_offset = input_frame_size - kPointerSize;
267 bool ok = true;
268 int limit = input_offset - (parameter_count * kPointerSize);
269 while (ok && input_offset > limit) {
270 ok = DoOsrTranslateCommand(&iterator, &input_offset);
271 }
272
273 // There are no translation commands for the caller's pc and fp, the
274 // context, and the function. Set them up explicitly.
275 for (int i = StandardFrameConstants::kCallerPCOffset;
276 ok && i >= StandardFrameConstants::kMarkerOffset;
277 i -= kPointerSize) {
278 uint32_t input_value = input_->GetFrameSlot(input_offset);
279 if (FLAG_trace_osr) {
280 const char* name = "UNKNOWN";
281 switch (i) {
282 case StandardFrameConstants::kCallerPCOffset:
283 name = "caller's pc";
284 break;
285 case StandardFrameConstants::kCallerFPOffset:
286 name = "fp";
287 break;
288 case StandardFrameConstants::kContextOffset:
289 name = "context";
290 break;
291 case StandardFrameConstants::kMarkerOffset:
292 name = "function";
293 break;
294 }
295 PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n",
296 output_offset,
297 input_value,
298 input_offset,
299 name);
300 }
301
302 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
303 input_offset -= kPointerSize;
304 output_offset -= kPointerSize;
305 }
306
307 // Translate the rest of the frame.
308 while (ok && input_offset >= 0) {
309 ok = DoOsrTranslateCommand(&iterator, &input_offset);
310 }
311
312 // If translation of any command failed, continue using the input frame.
313 if (!ok) {
314 delete output_[0];
315 output_[0] = input_;
316 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
317 } else {
318 // Set up the frame pointer and the context pointer.
319 output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code()));
320 output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code()));
321
322 unsigned pc_offset = data->OsrPcOffset()->value();
323 uint32_t pc = reinterpret_cast<uint32_t>(
324 compiled_code_->entry() + pc_offset);
325 output_[0]->SetPc(pc);
326 }
327 Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
328 output_[0]->SetContinuation(
329 reinterpret_cast<uint32_t>(continuation->entry()));
330
331 if (FLAG_trace_osr) {
332 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
333 ok ? "finished" : "aborted",
334 reinterpret_cast<intptr_t>(function_));
335 PrintFunctionName();
336 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
337 }
338 }
339
340
341 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 178 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
342 // Set the register values. The values are not important as there are no 179 // Set the register values. The values are not important as there are no
343 // callee saved registers in JavaScript frames, so all registers are 180 // callee saved registers in JavaScript frames, so all registers are
344 // spilled. Registers fp and sp are set to the correct values though. 181 // spilled. Registers fp and sp are set to the correct values though.
345 182
346 for (int i = 0; i < Register::kNumRegisters; i++) { 183 for (int i = 0; i < Register::kNumRegisters; i++) {
347 input_->SetRegister(i, i * 4); 184 input_->SetRegister(i, i * 4);
348 } 185 }
349 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); 186 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
350 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); 187 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) { 380 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) {
544 if (i == kDoubleRegZero.code()) continue; 381 if (i == kDoubleRegZero.code()) continue;
545 if (i == kScratchDoubleReg.code()) continue; 382 if (i == kScratchDoubleReg.code()) continue;
546 383
547 const DwVfpRegister reg = DwVfpRegister::from_code(i); 384 const DwVfpRegister reg = DwVfpRegister::from_code(i);
548 __ vldr(reg, r1, src_offset, i < 16 ? al : ne); 385 __ vldr(reg, r1, src_offset, i < 16 ? al : ne);
549 src_offset += kDoubleSize; 386 src_offset += kDoubleSize;
550 } 387 }
551 388
552 // Push state, pc, and continuation from the last output frame. 389 // Push state, pc, and continuation from the last output frame.
553 if (type() != OSR) { 390 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset()));
554 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset())); 391 __ push(r6);
555 __ push(r6);
556 }
557
558 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset())); 392 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset()));
559 __ push(r6); 393 __ push(r6);
560 __ ldr(r6, MemOperand(r2, FrameDescription::continuation_offset())); 394 __ ldr(r6, MemOperand(r2, FrameDescription::continuation_offset()));
561 __ push(r6); 395 __ push(r6);
562 396
563 // Push the registers from the last output frame. 397 // Push the registers from the last output frame.
564 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { 398 for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
565 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 399 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
566 __ ldr(r6, MemOperand(r2, offset)); 400 __ ldr(r6, MemOperand(r2, offset));
567 __ push(r6); 401 __ push(r6);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 438
605 439
606 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { 440 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
607 SetFrameSlot(offset, value); 441 SetFrameSlot(offset, value);
608 } 442 }
609 443
610 444
611 #undef __ 445 #undef __
612 446
613 } } // namespace v8::internal 447 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/lithium-arm.cc » ('j') | src/compiler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698