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

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

Issue 9511002: MIPS: Implement inlining of constructor calls. (Closed)
Patch Set: Created 8 years, 9 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 348 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
349 int frame_index) { 349 int frame_index) {
350 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 350 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
351 unsigned height = iterator->Next(); 351 unsigned height = iterator->Next();
352 unsigned height_in_bytes = height * kPointerSize; 352 unsigned height_in_bytes = height * kPointerSize;
353 if (FLAG_trace_deopt) { 353 if (FLAG_trace_deopt) {
354 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); 354 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes);
355 } 355 }
356 356
357 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; 357 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
358 unsigned input_frame_size = input_->GetFrameSize();
359 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 358 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
360 359
361 // Allocate and store the output frame description. 360 // Allocate and store the output frame description.
362 FrameDescription* output_frame = 361 FrameDescription* output_frame =
363 new(output_frame_size) FrameDescription(output_frame_size, function); 362 new(output_frame_size) FrameDescription(output_frame_size, function);
364 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); 363 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
365 364
366 // Arguments adaptor can not be topmost or bottommost. 365 // Arguments adaptor can not be topmost or bottommost.
367 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 366 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
368 ASSERT(output_[frame_index] == NULL); 367 ASSERT(output_[frame_index] == NULL);
369 output_[frame_index] = output_frame; 368 output_[frame_index] = output_frame;
370 369
371 // The top address of the frame is computed from the previous 370 // The top address of the frame is computed from the previous
372 // frame's top and this frame's size. 371 // frame's top and this frame's size.
373 uint32_t top_address; 372 uint32_t top_address;
374 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 373 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
375 output_frame->SetTop(top_address); 374 output_frame->SetTop(top_address);
376 375
377 // Compute the incoming parameter translation. 376 // Compute the incoming parameter translation.
378 int parameter_count = height; 377 int parameter_count = height;
379 unsigned output_offset = output_frame_size; 378 unsigned output_offset = output_frame_size;
380 unsigned input_offset = input_frame_size;
381 for (int i = 0; i < parameter_count; ++i) { 379 for (int i = 0; i < parameter_count; ++i) {
382 output_offset -= kPointerSize; 380 output_offset -= kPointerSize;
383 DoTranslateCommand(iterator, frame_index, output_offset); 381 DoTranslateCommand(iterator, frame_index, output_offset);
384 } 382 }
385 input_offset -= (parameter_count * kPointerSize);
386 383
387 // Read caller's PC from the previous frame. 384 // Read caller's PC from the previous frame.
388 output_offset -= kPointerSize; 385 output_offset -= kPointerSize;
389 input_offset -= kPointerSize;
390 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 386 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
391 output_frame->SetFrameSlot(output_offset, callers_pc); 387 output_frame->SetFrameSlot(output_offset, callers_pc);
392 if (FLAG_trace_deopt) { 388 if (FLAG_trace_deopt) {
393 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", 389 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
394 top_address + output_offset, output_offset, callers_pc); 390 top_address + output_offset, output_offset, callers_pc);
395 } 391 }
396 392
397 // Read caller's FP from the previous frame, and set this frame's FP. 393 // Read caller's FP from the previous frame, and set this frame's FP.
398 output_offset -= kPointerSize; 394 output_offset -= kPointerSize;
399 input_offset -= kPointerSize;
400 intptr_t value = output_[frame_index - 1]->GetFp(); 395 intptr_t value = output_[frame_index - 1]->GetFp();
401 output_frame->SetFrameSlot(output_offset, value); 396 output_frame->SetFrameSlot(output_offset, value);
402 intptr_t fp_value = top_address + output_offset; 397 intptr_t fp_value = top_address + output_offset;
403 output_frame->SetFp(fp_value); 398 output_frame->SetFp(fp_value);
404 if (FLAG_trace_deopt) { 399 if (FLAG_trace_deopt) {
405 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", 400 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
406 fp_value, output_offset, value); 401 fp_value, output_offset, value);
407 } 402 }
408 403
409 // A marker value is used in place of the context. 404 // A marker value is used in place of the context.
410 output_offset -= kPointerSize; 405 output_offset -= kPointerSize;
411 input_offset -= kPointerSize;
412 intptr_t context = reinterpret_cast<intptr_t>( 406 intptr_t context = reinterpret_cast<intptr_t>(
413 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 407 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
414 output_frame->SetFrameSlot(output_offset, context); 408 output_frame->SetFrameSlot(output_offset, context);
415 if (FLAG_trace_deopt) { 409 if (FLAG_trace_deopt) {
416 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", 410 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n",
417 top_address + output_offset, output_offset, context); 411 top_address + output_offset, output_offset, context);
418 } 412 }
419 413
420 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. 414 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
421 output_offset -= kPointerSize; 415 output_offset -= kPointerSize;
422 input_offset -= kPointerSize;
423 value = reinterpret_cast<intptr_t>(function); 416 value = reinterpret_cast<intptr_t>(function);
424 output_frame->SetFrameSlot(output_offset, value); 417 output_frame->SetFrameSlot(output_offset, value);
425 if (FLAG_trace_deopt) { 418 if (FLAG_trace_deopt) {
426 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", 419 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n",
427 top_address + output_offset, output_offset, value); 420 top_address + output_offset, output_offset, value);
428 } 421 }
429 422
430 // Number of incoming arguments. 423 // Number of incoming arguments.
431 output_offset -= kPointerSize; 424 output_offset -= kPointerSize;
432 input_offset -= kPointerSize;
433 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); 425 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
434 output_frame->SetFrameSlot(output_offset, value); 426 output_frame->SetFrameSlot(output_offset, value);
435 if (FLAG_trace_deopt) { 427 if (FLAG_trace_deopt) {
436 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", 428 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
437 top_address + output_offset, output_offset, value, height - 1); 429 top_address + output_offset, output_offset, value, height - 1);
438 } 430 }
439 431
440 ASSERT(0 == output_offset); 432 ASSERT(0 == output_offset);
441 433
442 Builtins* builtins = isolate_->builtins(); 434 Builtins* builtins = isolate_->builtins();
443 Code* adaptor_trampoline = 435 Code* adaptor_trampoline =
444 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); 436 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
445 uint32_t pc = reinterpret_cast<uint32_t>( 437 uint32_t pc = reinterpret_cast<uint32_t>(
446 adaptor_trampoline->instruction_start() + 438 adaptor_trampoline->instruction_start() +
447 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); 439 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
448 output_frame->SetPc(pc); 440 output_frame->SetPc(pc);
449 } 441 }
450 442
451 443
444 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
445 int frame_index) {
446 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
447 unsigned height = iterator->Next();
448 unsigned height_in_bytes = height * kPointerSize;
449 if (FLAG_trace_deopt) {
450 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
451 }
452
453 unsigned fixed_frame_size = 7 * kPointerSize;
454 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
455
456 // Allocate and store the output frame description.
457 FrameDescription* output_frame =
458 new(output_frame_size) FrameDescription(output_frame_size, function);
459 output_frame->SetFrameType(StackFrame::CONSTRUCT);
460
461 // Construct stub can not be topmost or bottommost.
462 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
463 ASSERT(output_[frame_index] == NULL);
464 output_[frame_index] = output_frame;
465
466 // The top address of the frame is computed from the previous
467 // frame's top and this frame's size.
468 uint32_t top_address;
469 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
470 output_frame->SetTop(top_address);
471
472 // Compute the incoming parameter translation.
473 int parameter_count = height;
474 unsigned output_offset = output_frame_size;
475 for (int i = 0; i < parameter_count; ++i) {
476 output_offset -= kPointerSize;
477 DoTranslateCommand(iterator, frame_index, output_offset);
478 }
479
480 // Read caller's PC from the previous frame.
481 output_offset -= kPointerSize;
482 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
483 output_frame->SetFrameSlot(output_offset, callers_pc);
484 if (FLAG_trace_deopt) {
485 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
486 top_address + output_offset, output_offset, callers_pc);
487 }
488
489 // Read caller's FP from the previous frame, and set this frame's FP.
490 output_offset -= kPointerSize;
491 intptr_t value = output_[frame_index - 1]->GetFp();
492 output_frame->SetFrameSlot(output_offset, value);
493 intptr_t fp_value = top_address + output_offset;
494 output_frame->SetFp(fp_value);
495 if (FLAG_trace_deopt) {
496 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
497 fp_value, output_offset, value);
498 }
499
500 // The context can be gotten from the previous frame.
501 output_offset -= kPointerSize;
502 value = output_[frame_index - 1]->GetContext();
503 output_frame->SetFrameSlot(output_offset, value);
504 if (FLAG_trace_deopt) {
505 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
506 top_address + output_offset, output_offset, value);
507 }
508
509 // A marker value is used in place of the function.
510 output_offset -= kPointerSize;
511 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
512 output_frame->SetFrameSlot(output_offset, value);
513 if (FLAG_trace_deopt) {
514 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n",
515 top_address + output_offset, output_offset, value);
516 }
517
518 // Number of incoming arguments.
519 output_offset -= kPointerSize;
520 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
521 output_frame->SetFrameSlot(output_offset, value);
522 if (FLAG_trace_deopt) {
523 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
524 top_address + output_offset, output_offset, value, height - 1);
525 }
526
527 // Constructor function being invoked by the stub.
528 output_offset -= kPointerSize;
529 value = reinterpret_cast<intptr_t>(function);
530 output_frame->SetFrameSlot(output_offset, value);
531 if (FLAG_trace_deopt) {
532 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; constructor function\n",
533 top_address + output_offset, output_offset, value);
534 }
535
536 // The newly allocated object was passed as receiver in the artificial
537 // constructor stub environment created by HEnvironment::CopyForInlining().
538 output_offset -= kPointerSize;
539 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
540 output_frame->SetFrameSlot(output_offset, value);
541 if (FLAG_trace_deopt) {
542 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n",
543 top_address + output_offset, output_offset, value);
544 }
545
546 ASSERT(0 == output_offset);
547
548 Builtins* builtins = isolate_->builtins();
549 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
550 uint32_t pc = reinterpret_cast<uint32_t>(
551 construct_stub->instruction_start() +
552 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
553 output_frame->SetPc(pc);
554 }
555
556
452 // This code is very similar to ia32/arm code, but relies on register names 557 // This code is very similar to ia32/arm code, but relies on register names
453 // (fp, sp) and how the frame is laid out. 558 // (fp, sp) and how the frame is laid out.
454 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 559 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
455 int frame_index) { 560 int frame_index) {
456 // Read the ast node id, function, and frame height for this output frame. 561 // Read the ast node id, function, and frame height for this output frame.
457 int node_id = iterator->Next(); 562 int node_id = iterator->Next();
458 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 563 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
459 unsigned height = iterator->Next(); 564 unsigned height = iterator->Next();
460 unsigned height_in_bytes = height * kPointerSize; 565 unsigned height_in_bytes = height * kPointerSize;
461 if (FLAG_trace_deopt) { 566 if (FLAG_trace_deopt) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 // frame. For all subsequent output frames it can be gotten from the function 659 // frame. For all subsequent output frames it can be gotten from the function
555 // so long as we don't inline functions that need local contexts. 660 // so long as we don't inline functions that need local contexts.
556 output_offset -= kPointerSize; 661 output_offset -= kPointerSize;
557 input_offset -= kPointerSize; 662 input_offset -= kPointerSize;
558 if (is_bottommost) { 663 if (is_bottommost) {
559 value = input_->GetFrameSlot(input_offset); 664 value = input_->GetFrameSlot(input_offset);
560 } else { 665 } else {
561 value = reinterpret_cast<intptr_t>(function->context()); 666 value = reinterpret_cast<intptr_t>(function->context());
562 } 667 }
563 output_frame->SetFrameSlot(output_offset, value); 668 output_frame->SetFrameSlot(output_offset, value);
564 if (is_topmost) { 669 output_frame->SetContext(value);
565 output_frame->SetRegister(cp.code(), value); 670 if (is_topmost) output_frame->SetRegister(cp.code(), value);
566 }
567 if (FLAG_trace_deopt) { 671 if (FLAG_trace_deopt) {
568 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", 672 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
569 top_address + output_offset, output_offset, value); 673 top_address + output_offset, output_offset, value);
570 } 674 }
571 675
572 // The function was mentioned explicitly in the BEGIN_FRAME. 676 // The function was mentioned explicitly in the BEGIN_FRAME.
573 output_offset -= kPointerSize; 677 output_offset -= kPointerSize;
574 input_offset -= kPointerSize; 678 input_offset -= kPointerSize;
575 value = reinterpret_cast<uint32_t>(function); 679 value = reinterpret_cast<uint32_t>(function);
576 // The function for the bottommost output frame should also agree with the 680 // The function for the bottommost output frame should also agree with the
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 } 988 }
885 989
886 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), 990 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start),
887 count() * table_entry_size_); 991 count() * table_entry_size_);
888 } 992 }
889 993
890 #undef __ 994 #undef __
891 995
892 996
893 } } // namespace v8::internal 997 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698