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

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

Issue 12328162: Merged r13654, r13655, r13657, r13695 into 3.16 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.16
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « src/mips/codegen-mips.cc ('k') | src/mips/frames-mips.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 // | .... | | .... | 452 // | .... | | .... |
453 // +-------------------------+ +-------------------------+ 453 // +-------------------------+ +-------------------------+
454 // | JSFunction continuation | | JSFunction continuation | 454 // | JSFunction continuation | | JSFunction continuation |
455 // +-------------------------+ +-------------------------+ 455 // +-------------------------+ +-------------------------+
456 // | | saved frame (fp) | | saved frame (fp) | 456 // | | saved frame (fp) | | saved frame (fp) |
457 // | +=========================+<-fp +=========================+<-fp 457 // | +=========================+<-fp +=========================+<-fp
458 // | | JSFunction context | | JSFunction context | 458 // | | JSFunction context | | JSFunction context |
459 // v +-------------------------+ +-------------------------| 459 // v +-------------------------+ +-------------------------|
460 // | COMPILED_STUB marker | | STUB_FAILURE marker | 460 // | COMPILED_STUB marker | | STUB_FAILURE marker |
461 // +-------------------------+ +-------------------------+ 461 // +-------------------------+ +-------------------------+
462 // | | | stub parameter 1 | 462 // | | | caller args.length_ |
463 // | ... | +-------------------------+ 463 // | ... | +-------------------------+
464 // | | | ... | 464 // | | | caller args.arguments_ |
465 // |-------------------------|<-sp +-------------------------+ 465 // |-------------------------|<-sp +-------------------------+
466 // | stub parameter n | 466 // | caller args pointer |
467 // parameters in registers +-------------------------+<-sp 467 // +-------------------------+
468 // and spilled to stack s0-s1 = number of parameters 468 // | caller stack param 1 |
469 // parameters in registers +-------------------------+
470 // and spilled to stack | .... |
471 // +-------------------------+
472 // | caller stack param n |
473 // +-------------------------+<-sp
474 // s0-s1 = number of parameters
469 // s2 = failure handler address 475 // s2 = failure handler address
470 // fp = saved frame 476 // fp = saved frame
471 // cp = JSFunction context 477 // cp = JSFunction context
472 // 478 //
473 479
474 ASSERT(compiled_code_->kind() == Code::COMPILED_STUB); 480 ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
475 int major_key = compiled_code_->major_key(); 481 int major_key = compiled_code_->major_key();
476 CodeStubInterfaceDescriptor* descriptor = 482 CodeStubInterfaceDescriptor* descriptor =
477 isolate_->code_stub_interface_descriptor(major_key); 483 isolate_->code_stub_interface_descriptor(major_key);
478 484
485 // The output frame must have room for all pushed register parameters
486 // and the standard stack frame slots.
479 int output_frame_size = StandardFrameConstants::kFixedFrameSize + 487 int output_frame_size = StandardFrameConstants::kFixedFrameSize +
480 kPointerSize * descriptor->register_param_count_; 488 kPointerSize * descriptor->register_param_count_;
481 489
490 // Include space for an argument object to the callee and optionally
491 // the space to pass the argument object to the stub failure handler.
492 output_frame_size += sizeof(Arguments) + kPointerSize;
493
482 FrameDescription* output_frame = 494 FrameDescription* output_frame =
483 new(output_frame_size) FrameDescription(output_frame_size, 0); 495 new(output_frame_size) FrameDescription(output_frame_size, 0);
484 ASSERT(frame_index == 0); 496 ASSERT(frame_index == 0);
485 output_[frame_index] = output_frame; 497 output_[frame_index] = output_frame;
486 Code* notify_failure = 498 Code* notify_failure =
487 isolate_->builtins()->builtin(Builtins::kNotifyStubFailure); 499 isolate_->builtins()->builtin(Builtins::kNotifyStubFailure);
488 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); 500 output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
489 output_frame->SetContinuation( 501 output_frame->SetContinuation(
490 reinterpret_cast<intptr_t>(notify_failure->entry())); 502 reinterpret_cast<intptr_t>(notify_failure->entry()));
491 503
492 Code* trampoline = NULL; 504 Code* trampoline = NULL;
493 StubFailureTrampolineStub().FindCodeInCache(&trampoline, isolate_); 505 int extra = descriptor->extra_expression_stack_count_;
506 StubFailureTrampolineStub(extra).FindCodeInCache(&trampoline, isolate_);
494 ASSERT(trampoline != NULL); 507 ASSERT(trampoline != NULL);
495 output_frame->SetPc(reinterpret_cast<intptr_t>( 508 output_frame->SetPc(reinterpret_cast<intptr_t>(
496 trampoline->instruction_start())); 509 trampoline->instruction_start()));
497 unsigned input_frame_size = input_->GetFrameSize(); 510 unsigned input_frame_size = input_->GetFrameSize();
498 511
512 intptr_t frame_ptr = input_->GetRegister(fp.code());
513
499 // JSFunction continuation 514 // JSFunction continuation
500 intptr_t input_frame_offset = input_frame_size - kPointerSize; 515 intptr_t input_frame_offset = input_frame_size - kPointerSize;
501 intptr_t output_frame_offset = output_frame_size - kPointerSize; 516 intptr_t output_frame_offset = output_frame_size - kPointerSize;
502 intptr_t value = input_->GetFrameSlot(input_frame_offset); 517 intptr_t value = input_->GetFrameSlot(input_frame_offset);
503 output_frame->SetFrameSlot(output_frame_offset, value); 518 output_frame->SetFrameSlot(output_frame_offset, value);
504 519
505 // saved frame ptr 520 // saved frame ptr
506 input_frame_offset -= kPointerSize; 521 input_frame_offset -= kPointerSize;
507 value = input_->GetFrameSlot(input_frame_offset); 522 value = input_->GetFrameSlot(input_frame_offset);
508 output_frame_offset -= kPointerSize; 523 output_frame_offset -= kPointerSize;
509 output_frame->SetFrameSlot(output_frame_offset, value); 524 output_frame->SetFrameSlot(output_frame_offset, value);
510 525
511 // Restore context 526 // Restore context
512 input_frame_offset -= kPointerSize; 527 input_frame_offset -= kPointerSize;
513 value = input_->GetFrameSlot(input_frame_offset); 528 value = input_->GetFrameSlot(input_frame_offset);
514 output_frame->SetRegister(cp.code(), value); 529 output_frame->SetRegister(cp.code(), value);
515 output_frame_offset -= kPointerSize; 530 output_frame_offset -= kPointerSize;
516 output_frame->SetFrameSlot(output_frame_offset, value); 531 output_frame->SetFrameSlot(output_frame_offset, value);
517 532
518 // Internal frame markers 533 // Internal frame markers
519 output_frame_offset -= kPointerSize; 534 output_frame_offset -= kPointerSize;
520 value = reinterpret_cast<intptr_t>( 535 value = reinterpret_cast<intptr_t>(
521 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE)); 536 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE));
522 output_frame->SetFrameSlot(output_frame_offset, value); 537 output_frame->SetFrameSlot(output_frame_offset, value);
523 538
539 int caller_arg_count = 0;
540 if (descriptor->stack_parameter_count_ != NULL) {
541 caller_arg_count =
542 input_->GetRegister(descriptor->stack_parameter_count_->code());
543 }
544
545 // Build the Arguments object for the caller's parameters and a pointer to it.
546 output_frame_offset -= kPointerSize;
547 value = frame_ptr + StandardFrameConstants::kCallerSPOffset +
548 (caller_arg_count - 1) * kPointerSize;
549 output_frame->SetFrameSlot(output_frame_offset, value);
550
551 output_frame->SetFrameSlot(output_frame_offset, value);
552 output_frame_offset -= kPointerSize;
553 output_frame->SetFrameSlot(output_frame_offset, caller_arg_count);
554
555 value = frame_ptr - (output_frame_size - output_frame_offset) -
556 StandardFrameConstants::kMarkerOffset;
557 output_frame_offset -= kPointerSize;
558 output_frame->SetFrameSlot(output_frame_offset, value);
559
560 // Copy the register parameters to the failure frame.
524 for (int i = 0; i < descriptor->register_param_count_; ++i) { 561 for (int i = 0; i < descriptor->register_param_count_; ++i) {
525 output_frame_offset -= kPointerSize; 562 output_frame_offset -= kPointerSize;
526 DoTranslateCommand(iterator, 0, output_frame_offset); 563 DoTranslateCommand(iterator, 0, output_frame_offset);
527 } 564 }
528 565
529 value = input_->GetRegister(fp.code()); 566 for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) {
530 output_frame->SetRegister(fp.code(), value); 567 double double_value = input_->GetDoubleRegister(i);
531 output_frame->SetFp(value); 568 output_frame->SetDoubleRegister(i, double_value);
569 }
570
571 output_frame->SetRegister(fp.code(), frame_ptr);
572 output_frame->SetFp(frame_ptr);
532 573
533 ApiFunction function(descriptor->deoptimization_handler_); 574 ApiFunction function(descriptor->deoptimization_handler_);
534 ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_); 575 ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
535 intptr_t handler = reinterpret_cast<intptr_t>(xref.address()); 576 intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
536 output_frame->SetRegister(s0.code(), descriptor->register_param_count_); 577 int params = descriptor->register_param_count_;
537 output_frame->SetRegister(s1.code(), 578 if (descriptor->stack_parameter_count_ != NULL) {
538 (descriptor->register_param_count_ - 1) * kPointerSize); 579 params++;
580 }
581 output_frame->SetRegister(s0.code(), params);
582 output_frame->SetRegister(s1.code(), (params - 1) * kPointerSize);
539 output_frame->SetRegister(s2.code(), handler); 583 output_frame->SetRegister(s2.code(), handler);
540 } 584 }
541 585
542 586
543 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, 587 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
544 int frame_index) { 588 int frame_index) {
545 Builtins* builtins = isolate_->builtins(); 589 Builtins* builtins = isolate_->builtins();
546 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); 590 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
547 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 591 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
548 unsigned height = iterator->Next(); 592 unsigned height = iterator->Next();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", 630 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
587 top_address + output_offset, output_offset, callers_pc); 631 top_address + output_offset, output_offset, callers_pc);
588 } 632 }
589 633
590 // Read caller's FP from the previous frame, and set this frame's FP. 634 // Read caller's FP from the previous frame, and set this frame's FP.
591 output_offset -= kPointerSize; 635 output_offset -= kPointerSize;
592 intptr_t value = output_[frame_index - 1]->GetFp(); 636 intptr_t value = output_[frame_index - 1]->GetFp();
593 output_frame->SetFrameSlot(output_offset, value); 637 output_frame->SetFrameSlot(output_offset, value);
594 intptr_t fp_value = top_address + output_offset; 638 intptr_t fp_value = top_address + output_offset;
595 output_frame->SetFp(fp_value); 639 output_frame->SetFp(fp_value);
596 if (FLAG_trace_deopt) { 640 if (trace_) {
597 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", 641 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
598 fp_value, output_offset, value); 642 fp_value, output_offset, value);
599 } 643 }
600 644
601 // The context can be gotten from the previous frame. 645 // The context can be gotten from the previous frame.
602 output_offset -= kPointerSize; 646 output_offset -= kPointerSize;
603 value = output_[frame_index - 1]->GetContext(); 647 value = output_[frame_index - 1]->GetContext();
604 output_frame->SetFrameSlot(output_offset, value); 648 output_frame->SetFrameSlot(output_offset, value);
605 if (FLAG_trace_deopt) { 649 if (trace_) {
606 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", 650 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
607 top_address + output_offset, output_offset, value); 651 top_address + output_offset, output_offset, value);
608 } 652 }
609 653
610 // A marker value is used in place of the function. 654 // A marker value is used in place of the function.
611 output_offset -= kPointerSize; 655 output_offset -= kPointerSize;
612 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); 656 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
613 output_frame->SetFrameSlot(output_offset, value); 657 output_frame->SetFrameSlot(output_offset, value);
614 if (FLAG_trace_deopt) { 658 if (trace_) {
615 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n", 659 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n",
616 top_address + output_offset, output_offset, value); 660 top_address + output_offset, output_offset, value);
617 } 661 }
618 662
619 // The output frame reflects a JSConstructStubGeneric frame. 663 // The output frame reflects a JSConstructStubGeneric frame.
620 output_offset -= kPointerSize; 664 output_offset -= kPointerSize;
621 value = reinterpret_cast<intptr_t>(construct_stub); 665 value = reinterpret_cast<intptr_t>(construct_stub);
622 output_frame->SetFrameSlot(output_offset, value); 666 output_frame->SetFrameSlot(output_offset, value);
623 if (FLAG_trace_deopt) { 667 if (trace_) {
624 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n", 668 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n",
625 top_address + output_offset, output_offset, value); 669 top_address + output_offset, output_offset, value);
626 } 670 }
627 671
628 // Number of incoming arguments. 672 // Number of incoming arguments.
629 output_offset -= kPointerSize; 673 output_offset -= kPointerSize;
630 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); 674 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1));
631 output_frame->SetFrameSlot(output_offset, value); 675 output_frame->SetFrameSlot(output_offset, value);
632 if (FLAG_trace_deopt) { 676 if (trace_) {
633 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", 677 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n",
634 top_address + output_offset, output_offset, value, height - 1); 678 top_address + output_offset, output_offset, value, height - 1);
635 } 679 }
636 680
637 // Constructor function being invoked by the stub. 681 // Constructor function being invoked by the stub.
638 output_offset -= kPointerSize; 682 output_offset -= kPointerSize;
639 value = reinterpret_cast<intptr_t>(function); 683 value = reinterpret_cast<intptr_t>(function);
640 output_frame->SetFrameSlot(output_offset, value); 684 output_frame->SetFrameSlot(output_offset, value);
641 if (FLAG_trace_deopt) { 685 if (trace_) {
642 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; constructor function\n", 686 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; constructor function\n",
643 top_address + output_offset, output_offset, value); 687 top_address + output_offset, output_offset, value);
644 } 688 }
645 689
646 // The newly allocated object was passed as receiver in the artificial 690 // The newly allocated object was passed as receiver in the artificial
647 // constructor stub environment created by HEnvironment::CopyForInlining(). 691 // constructor stub environment created by HEnvironment::CopyForInlining().
648 output_offset -= kPointerSize; 692 output_offset -= kPointerSize;
649 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); 693 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
650 output_frame->SetFrameSlot(output_offset, value); 694 output_frame->SetFrameSlot(output_offset, value);
651 if (FLAG_trace_deopt) { 695 if (trace_) {
652 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n", 696 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n",
653 top_address + output_offset, output_offset, value); 697 top_address + output_offset, output_offset, value);
654 } 698 }
655 699
656 ASSERT(0 == output_offset); 700 ASSERT(0 == output_offset);
657 701
658 uint32_t pc = reinterpret_cast<uint32_t>( 702 uint32_t pc = reinterpret_cast<uint32_t>(
659 construct_stub->instruction_start() + 703 construct_stub->instruction_start() +
660 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 704 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
661 output_frame->SetPc(pc); 705 output_frame->SetPc(pc);
662 } 706 }
663 707
664 708
665 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, 709 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
666 int frame_index, 710 int frame_index,
667 bool is_setter_stub_frame) { 711 bool is_setter_stub_frame) {
668 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); 712 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next()));
669 // The receiver (and the implicit return value, if any) are expected in 713 // The receiver (and the implicit return value, if any) are expected in
670 // registers by the LoadIC/StoreIC, so they don't belong to the output stack 714 // registers by the LoadIC/StoreIC, so they don't belong to the output stack
671 // frame. This means that we have to use a height of 0. 715 // frame. This means that we have to use a height of 0.
672 unsigned height = 0; 716 unsigned height = 0;
673 unsigned height_in_bytes = height * kPointerSize; 717 unsigned height_in_bytes = height * kPointerSize;
674 const char* kind = is_setter_stub_frame ? "setter" : "getter"; 718 const char* kind = is_setter_stub_frame ? "setter" : "getter";
675 if (FLAG_trace_deopt) { 719 if (trace_) {
676 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); 720 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes);
677 } 721 }
678 722
679 // We need 5 stack entries from StackFrame::INTERNAL (ra, fp, cp, frame type, 723 // We need 5 stack entries from StackFrame::INTERNAL (ra, fp, cp, frame type,
680 // code object, see MacroAssembler::EnterFrame). For a setter stub frame we 724 // code object, see MacroAssembler::EnterFrame). For a setter stub frame we
681 // need one additional entry for the implicit return value, see 725 // need one additional entry for the implicit return value, see
682 // StoreStubCompiler::CompileStoreViaSetter. 726 // StoreStubCompiler::CompileStoreViaSetter.
683 unsigned fixed_frame_entries = 5 + (is_setter_stub_frame ? 1 : 0); 727 unsigned fixed_frame_entries = 5 + (is_setter_stub_frame ? 1 : 0);
684 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; 728 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
685 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 729 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
(...skipping 12 matching lines...) Expand all
698 // this frame's size. 742 // this frame's size.
699 uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 743 uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
700 output_frame->SetTop(top_address); 744 output_frame->SetTop(top_address);
701 745
702 unsigned output_offset = output_frame_size; 746 unsigned output_offset = output_frame_size;
703 747
704 // Read caller's PC from the previous frame. 748 // Read caller's PC from the previous frame.
705 output_offset -= kPointerSize; 749 output_offset -= kPointerSize;
706 intptr_t value = output_[frame_index - 1]->GetPc(); 750 intptr_t value = output_[frame_index - 1]->GetPc();
707 output_frame->SetFrameSlot(output_offset, value); 751 output_frame->SetFrameSlot(output_offset, value);
708 if (FLAG_trace_deopt) { 752 if (trace_) {
709 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 753 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
710 " ; caller's pc\n", 754 " ; caller's pc\n",
711 top_address + output_offset, output_offset, value); 755 top_address + output_offset, output_offset, value);
712 } 756 }
713 757
714 // Read caller's FP from the previous frame, and set this frame's FP. 758 // Read caller's FP from the previous frame, and set this frame's FP.
715 output_offset -= kPointerSize; 759 output_offset -= kPointerSize;
716 value = output_[frame_index - 1]->GetFp(); 760 value = output_[frame_index - 1]->GetFp();
717 output_frame->SetFrameSlot(output_offset, value); 761 output_frame->SetFrameSlot(output_offset, value);
718 intptr_t fp_value = top_address + output_offset; 762 intptr_t fp_value = top_address + output_offset;
719 output_frame->SetFp(fp_value); 763 output_frame->SetFp(fp_value);
720 if (FLAG_trace_deopt) { 764 if (trace_) {
721 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 765 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
722 " ; caller's fp\n", 766 " ; caller's fp\n",
723 fp_value, output_offset, value); 767 fp_value, output_offset, value);
724 } 768 }
725 769
726 // The context can be gotten from the previous frame. 770 // The context can be gotten from the previous frame.
727 output_offset -= kPointerSize; 771 output_offset -= kPointerSize;
728 value = output_[frame_index - 1]->GetContext(); 772 value = output_[frame_index - 1]->GetContext();
729 output_frame->SetFrameSlot(output_offset, value); 773 output_frame->SetFrameSlot(output_offset, value);
730 if (FLAG_trace_deopt) { 774 if (trace_) {
731 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 775 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
732 " ; context\n", 776 " ; context\n",
733 top_address + output_offset, output_offset, value); 777 top_address + output_offset, output_offset, value);
734 } 778 }
735 779
736 // A marker value is used in place of the function. 780 // A marker value is used in place of the function.
737 output_offset -= kPointerSize; 781 output_offset -= kPointerSize;
738 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); 782 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
739 output_frame->SetFrameSlot(output_offset, value); 783 output_frame->SetFrameSlot(output_offset, value);
740 if (FLAG_trace_deopt) { 784 if (trace_) {
741 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 785 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
742 " ; function (%s sentinel)\n", 786 " ; function (%s sentinel)\n",
743 top_address + output_offset, output_offset, value, kind); 787 top_address + output_offset, output_offset, value, kind);
744 } 788 }
745 789
746 // Get Code object from accessor stub. 790 // Get Code object from accessor stub.
747 output_offset -= kPointerSize; 791 output_offset -= kPointerSize;
748 Builtins::Name name = is_setter_stub_frame ? 792 Builtins::Name name = is_setter_stub_frame ?
749 Builtins::kStoreIC_Setter_ForDeopt : 793 Builtins::kStoreIC_Setter_ForDeopt :
750 Builtins::kLoadIC_Getter_ForDeopt; 794 Builtins::kLoadIC_Getter_ForDeopt;
751 Code* accessor_stub = isolate_->builtins()->builtin(name); 795 Code* accessor_stub = isolate_->builtins()->builtin(name);
752 value = reinterpret_cast<intptr_t>(accessor_stub); 796 value = reinterpret_cast<intptr_t>(accessor_stub);
753 output_frame->SetFrameSlot(output_offset, value); 797 output_frame->SetFrameSlot(output_offset, value);
754 if (FLAG_trace_deopt) { 798 if (trace_) {
755 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 799 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
756 " ; code object\n", 800 " ; code object\n",
757 top_address + output_offset, output_offset, value); 801 top_address + output_offset, output_offset, value);
758 } 802 }
759 803
760 // Skip receiver. 804 // Skip receiver.
761 Translation::Opcode opcode = 805 Translation::Opcode opcode =
762 static_cast<Translation::Opcode>(iterator->Next()); 806 static_cast<Translation::Opcode>(iterator->Next());
763 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); 807 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
764 808
(...skipping 25 matching lines...) Expand all
790 if (frame_index != 0) { 834 if (frame_index != 0) {
791 function = JSFunction::cast(ComputeLiteral(iterator->Next())); 835 function = JSFunction::cast(ComputeLiteral(iterator->Next()));
792 } else { 836 } else {
793 int closure_id = iterator->Next(); 837 int closure_id = iterator->Next();
794 USE(closure_id); 838 USE(closure_id);
795 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); 839 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
796 function = function_; 840 function = function_;
797 } 841 }
798 unsigned height = iterator->Next(); 842 unsigned height = iterator->Next();
799 unsigned height_in_bytes = height * kPointerSize; 843 unsigned height_in_bytes = height * kPointerSize;
800 if (FLAG_trace_deopt) { 844 if (trace_) {
801 PrintF(" translating "); 845 PrintF(" translating ");
802 function->PrintName(); 846 function->PrintName();
803 PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); 847 PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
804 } 848 }
805 849
806 // The 'fixed' part of the frame consists of the incoming parameters and 850 // The 'fixed' part of the frame consists of the incoming parameters and
807 // the part described by JavaScriptFrameConstants. 851 // the part described by JavaScriptFrameConstants.
808 unsigned fixed_frame_size = ComputeFixedSize(function); 852 unsigned fixed_frame_size = ComputeFixedSize(function);
809 unsigned input_frame_size = input_->GetFrameSize(); 853 unsigned input_frame_size = input_->GetFrameSize();
810 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 854 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 // function code and AST id of the bailout. 898 // function code and AST id of the bailout.
855 output_offset -= kPointerSize; 899 output_offset -= kPointerSize;
856 input_offset -= kPointerSize; 900 input_offset -= kPointerSize;
857 intptr_t value; 901 intptr_t value;
858 if (is_bottommost) { 902 if (is_bottommost) {
859 value = input_->GetFrameSlot(input_offset); 903 value = input_->GetFrameSlot(input_offset);
860 } else { 904 } else {
861 value = output_[frame_index - 1]->GetPc(); 905 value = output_[frame_index - 1]->GetPc();
862 } 906 }
863 output_frame->SetFrameSlot(output_offset, value); 907 output_frame->SetFrameSlot(output_offset, value);
864 if (FLAG_trace_deopt) { 908 if (trace_) {
865 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", 909 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n",
866 top_address + output_offset, output_offset, value); 910 top_address + output_offset, output_offset, value);
867 } 911 }
868 912
869 // The caller's frame pointer for the bottommost output frame is the same 913 // The caller's frame pointer for the bottommost output frame is the same
870 // as in the input frame. For all subsequent output frames, it can be 914 // as in the input frame. For all subsequent output frames, it can be
871 // read from the previous one. Also compute and set this frame's frame 915 // read from the previous one. Also compute and set this frame's frame
872 // pointer. 916 // pointer.
873 output_offset -= kPointerSize; 917 output_offset -= kPointerSize;
874 input_offset -= kPointerSize; 918 input_offset -= kPointerSize;
875 if (is_bottommost) { 919 if (is_bottommost) {
876 value = input_->GetFrameSlot(input_offset); 920 value = input_->GetFrameSlot(input_offset);
877 } else { 921 } else {
878 value = output_[frame_index - 1]->GetFp(); 922 value = output_[frame_index - 1]->GetFp();
879 } 923 }
880 output_frame->SetFrameSlot(output_offset, value); 924 output_frame->SetFrameSlot(output_offset, value);
881 intptr_t fp_value = top_address + output_offset; 925 intptr_t fp_value = top_address + output_offset;
882 ASSERT(!is_bottommost || input_->GetRegister(fp.code()) == fp_value); 926 ASSERT(!is_bottommost || input_->GetRegister(fp.code()) == fp_value);
883 output_frame->SetFp(fp_value); 927 output_frame->SetFp(fp_value);
884 if (is_topmost) { 928 if (is_topmost) {
885 output_frame->SetRegister(fp.code(), fp_value); 929 output_frame->SetRegister(fp.code(), fp_value);
886 } 930 }
887 if (FLAG_trace_deopt) { 931 if (trace_) {
888 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", 932 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
889 fp_value, output_offset, value); 933 fp_value, output_offset, value);
890 } 934 }
891 935
892 // For the bottommost output frame the context can be gotten from the input 936 // For the bottommost output frame the context can be gotten from the input
893 // frame. For all subsequent output frames it can be gotten from the function 937 // frame. For all subsequent output frames it can be gotten from the function
894 // so long as we don't inline functions that need local contexts. 938 // so long as we don't inline functions that need local contexts.
895 output_offset -= kPointerSize; 939 output_offset -= kPointerSize;
896 input_offset -= kPointerSize; 940 input_offset -= kPointerSize;
897 if (is_bottommost) { 941 if (is_bottommost) {
898 value = input_->GetFrameSlot(input_offset); 942 value = input_->GetFrameSlot(input_offset);
899 } else { 943 } else {
900 value = reinterpret_cast<intptr_t>(function->context()); 944 value = reinterpret_cast<intptr_t>(function->context());
901 } 945 }
902 output_frame->SetFrameSlot(output_offset, value); 946 output_frame->SetFrameSlot(output_offset, value);
903 output_frame->SetContext(value); 947 output_frame->SetContext(value);
904 if (is_topmost) output_frame->SetRegister(cp.code(), value); 948 if (is_topmost) output_frame->SetRegister(cp.code(), value);
905 if (FLAG_trace_deopt) { 949 if (trace_) {
906 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", 950 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n",
907 top_address + output_offset, output_offset, value); 951 top_address + output_offset, output_offset, value);
908 } 952 }
909 953
910 // The function was mentioned explicitly in the BEGIN_FRAME. 954 // The function was mentioned explicitly in the BEGIN_FRAME.
911 output_offset -= kPointerSize; 955 output_offset -= kPointerSize;
912 input_offset -= kPointerSize; 956 input_offset -= kPointerSize;
913 value = reinterpret_cast<uint32_t>(function); 957 value = reinterpret_cast<uint32_t>(function);
914 // The function for the bottommost output frame should also agree with the 958 // The function for the bottommost output frame should also agree with the
915 // input frame. 959 // input frame.
916 ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value); 960 ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value);
917 output_frame->SetFrameSlot(output_offset, value); 961 output_frame->SetFrameSlot(output_offset, value);
918 if (FLAG_trace_deopt) { 962 if (trace_) {
919 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", 963 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n",
920 top_address + output_offset, output_offset, value); 964 top_address + output_offset, output_offset, value);
921 } 965 }
922 966
923 // Translate the rest of the frame. 967 // Translate the rest of the frame.
924 for (unsigned i = 0; i < height; ++i) { 968 for (unsigned i = 0; i < height; ++i) {
925 output_offset -= kPointerSize; 969 output_offset -= kPointerSize;
926 DoTranslateCommand(iterator, frame_index, output_offset); 970 DoTranslateCommand(iterator, frame_index, output_offset);
927 } 971 }
928 ASSERT(0 == output_offset); 972 ASSERT(0 == output_offset);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 1113 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
1070 if ((saved_regs & (1 << i)) != 0) { 1114 if ((saved_regs & (1 << i)) != 0) {
1071 __ lw(a2, MemOperand(sp, i * kPointerSize)); 1115 __ lw(a2, MemOperand(sp, i * kPointerSize));
1072 __ sw(a2, MemOperand(a1, offset)); 1116 __ sw(a2, MemOperand(a1, offset));
1073 } else if (FLAG_debug_code) { 1117 } else if (FLAG_debug_code) {
1074 __ li(a2, kDebugZapValue); 1118 __ li(a2, kDebugZapValue);
1075 __ sw(a2, MemOperand(a1, offset)); 1119 __ sw(a2, MemOperand(a1, offset));
1076 } 1120 }
1077 } 1121 }
1078 1122
1123 int double_regs_offset = FrameDescription::double_registers_offset();
1079 if (CpuFeatures::IsSupported(FPU)) { 1124 if (CpuFeatures::IsSupported(FPU)) {
1080 CpuFeatures::Scope scope(FPU); 1125 CpuFeatures::Scope scope(FPU);
1081 // Copy FPU registers to 1126 // Copy FPU registers to
1082 // double_registers_[DoubleRegister::kNumAllocatableRegisters] 1127 // double_registers_[DoubleRegister::kNumAllocatableRegisters]
1083 int double_regs_offset = FrameDescription::double_registers_offset();
1084 for (int i = 0; i < FPURegister::NumAllocatableRegisters(); ++i) { 1128 for (int i = 0; i < FPURegister::NumAllocatableRegisters(); ++i) {
1085 int dst_offset = i * kDoubleSize + double_regs_offset; 1129 int dst_offset = i * kDoubleSize + double_regs_offset;
1086 int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; 1130 int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
1087 __ ldc1(f0, MemOperand(sp, src_offset)); 1131 __ ldc1(f0, MemOperand(sp, src_offset));
1088 __ sdc1(f0, MemOperand(a1, dst_offset)); 1132 __ sdc1(f0, MemOperand(a1, dst_offset));
1089 } 1133 }
1090 } 1134 }
1091 1135
1092 // Remove the bailout id, eventually return address, and the saved registers 1136 // Remove the bailout id, eventually return address, and the saved registers
1093 // from the stack. 1137 // from the stack.
(...skipping 30 matching lines...) Expand all
1124 { 1168 {
1125 AllowExternalCallThatCantCauseGC scope(masm()); 1169 AllowExternalCallThatCantCauseGC scope(masm());
1126 __ CallCFunction( 1170 __ CallCFunction(
1127 ExternalReference::compute_output_frames_function(isolate), 1); 1171 ExternalReference::compute_output_frames_function(isolate), 1);
1128 } 1172 }
1129 __ pop(a0); // Restore deoptimizer object (class Deoptimizer). 1173 __ pop(a0); // Restore deoptimizer object (class Deoptimizer).
1130 1174
1131 // Replace the current (input) frame with the output frames. 1175 // Replace the current (input) frame with the output frames.
1132 Label outer_push_loop, inner_push_loop, 1176 Label outer_push_loop, inner_push_loop,
1133 outer_loop_header, inner_loop_header; 1177 outer_loop_header, inner_loop_header;
1134 // Outer loop state: a0 = current "FrameDescription** output_", 1178 // Outer loop state: t0 = current "FrameDescription** output_",
1135 // a1 = one past the last FrameDescription**. 1179 // a1 = one past the last FrameDescription**.
1136 __ lw(a1, MemOperand(a0, Deoptimizer::output_count_offset())); 1180 __ lw(a1, MemOperand(a0, Deoptimizer::output_count_offset()));
1137 __ lw(a0, MemOperand(a0, Deoptimizer::output_offset())); // a0 is output_. 1181 __ lw(t0, MemOperand(a0, Deoptimizer::output_offset())); // t0 is output_.
1138 __ sll(a1, a1, kPointerSizeLog2); // Count to offset. 1182 __ sll(a1, a1, kPointerSizeLog2); // Count to offset.
1139 __ addu(a1, a0, a1); // a1 = one past the last FrameDescription**. 1183 __ addu(a1, t0, a1); // a1 = one past the last FrameDescription**.
1140 __ jmp(&outer_loop_header); 1184 __ jmp(&outer_loop_header);
1141 __ bind(&outer_push_loop); 1185 __ bind(&outer_push_loop);
1142 // Inner loop state: a2 = current FrameDescription*, a3 = loop index. 1186 // Inner loop state: a2 = current FrameDescription*, a3 = loop index.
1143 __ lw(a2, MemOperand(a0, 0)); // output_[ix] 1187 __ lw(a2, MemOperand(t0, 0)); // output_[ix]
1144 __ lw(a3, MemOperand(a2, FrameDescription::frame_size_offset())); 1188 __ lw(a3, MemOperand(a2, FrameDescription::frame_size_offset()));
1145 __ jmp(&inner_loop_header); 1189 __ jmp(&inner_loop_header);
1146 __ bind(&inner_push_loop); 1190 __ bind(&inner_push_loop);
1147 __ Subu(a3, a3, Operand(sizeof(uint32_t))); 1191 __ Subu(a3, a3, Operand(sizeof(uint32_t)));
1148 __ Addu(t2, a2, Operand(a3)); 1192 __ Addu(t2, a2, Operand(a3));
1149 __ lw(t3, MemOperand(t2, FrameDescription::frame_content_offset())); 1193 __ lw(t3, MemOperand(t2, FrameDescription::frame_content_offset()));
1150 __ push(t3); 1194 __ push(t3);
1151 __ bind(&inner_loop_header); 1195 __ bind(&inner_loop_header);
1152 __ Branch(&inner_push_loop, ne, a3, Operand(zero_reg)); 1196 __ Branch(&inner_push_loop, ne, a3, Operand(zero_reg));
1153 1197
1154 __ Addu(a0, a0, Operand(kPointerSize)); 1198 __ Addu(t0, t0, Operand(kPointerSize));
1155 __ bind(&outer_loop_header); 1199 __ bind(&outer_loop_header);
1156 __ Branch(&outer_push_loop, lt, a0, Operand(a1)); 1200 __ Branch(&outer_push_loop, lt, t0, Operand(a1));
1157 1201
1202 if (CpuFeatures::IsSupported(FPU)) {
1203 CpuFeatures::Scope scope(FPU);
1204
1205 __ lw(a1, MemOperand(a0, Deoptimizer::input_offset()));
1206 for (int i = 0; i < FPURegister::kMaxNumAllocatableRegisters; ++i) {
1207 const FPURegister fpu_reg = FPURegister::FromAllocationIndex(i);
1208 int src_offset = i * kDoubleSize + double_regs_offset;
1209 __ ldc1(fpu_reg, MemOperand(a1, src_offset));
1210 }
1211 }
1158 1212
1159 // Push state, pc, and continuation from the last output frame. 1213 // Push state, pc, and continuation from the last output frame.
1160 if (type() != OSR) { 1214 if (type() != OSR) {
1161 __ lw(t2, MemOperand(a2, FrameDescription::state_offset())); 1215 __ lw(t2, MemOperand(a2, FrameDescription::state_offset()));
1162 __ push(t2); 1216 __ push(t2);
1163 } 1217 }
1164 1218
1165 __ lw(t2, MemOperand(a2, FrameDescription::pc_offset())); 1219 __ lw(t2, MemOperand(a2, FrameDescription::pc_offset()));
1166 __ push(t2); 1220 __ push(t2);
1167 __ lw(t2, MemOperand(a2, FrameDescription::continuation_offset())); 1221 __ lw(t2, MemOperand(a2, FrameDescription::continuation_offset()));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 } 1282 }
1229 1283
1230 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), 1284 ASSERT_EQ(masm()->SizeOfCodeGeneratedSince(&table_start),
1231 count() * table_entry_size_); 1285 count() * table_entry_size_);
1232 } 1286 }
1233 1287
1234 #undef __ 1288 #undef __
1235 1289
1236 1290
1237 } } // namespace v8::internal 1291 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/codegen-mips.cc ('k') | src/mips/frames-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698