OLD | NEW |
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 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); | 461 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); |
462 } | 462 } |
463 } | 463 } |
464 | 464 |
465 | 465 |
466 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, | 466 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, |
467 int frame_index) { | 467 int frame_index) { |
468 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 468 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
469 unsigned height = iterator->Next(); | 469 unsigned height = iterator->Next(); |
470 unsigned height_in_bytes = height * kPointerSize; | 470 unsigned height_in_bytes = height * kPointerSize; |
471 if (FLAG_trace_deopt) { | 471 if (trace_) { |
472 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); | 472 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); |
473 } | 473 } |
474 | 474 |
475 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; | 475 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; |
476 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 476 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
477 | 477 |
478 // Allocate and store the output frame description. | 478 // Allocate and store the output frame description. |
479 FrameDescription* output_frame = | 479 FrameDescription* output_frame = |
480 new(output_frame_size) FrameDescription(output_frame_size, function); | 480 new(output_frame_size) FrameDescription(output_frame_size, function); |
481 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); | 481 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); |
(...skipping 14 matching lines...) Expand all Loading... |
496 unsigned output_offset = output_frame_size; | 496 unsigned output_offset = output_frame_size; |
497 for (int i = 0; i < parameter_count; ++i) { | 497 for (int i = 0; i < parameter_count; ++i) { |
498 output_offset -= kPointerSize; | 498 output_offset -= kPointerSize; |
499 DoTranslateCommand(iterator, frame_index, output_offset); | 499 DoTranslateCommand(iterator, frame_index, output_offset); |
500 } | 500 } |
501 | 501 |
502 // Read caller's PC from the previous frame. | 502 // Read caller's PC from the previous frame. |
503 output_offset -= kPointerSize; | 503 output_offset -= kPointerSize; |
504 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 504 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
505 output_frame->SetFrameSlot(output_offset, callers_pc); | 505 output_frame->SetFrameSlot(output_offset, callers_pc); |
506 if (FLAG_trace_deopt) { | 506 if (trace_) { |
507 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", | 507 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", |
508 top_address + output_offset, output_offset, callers_pc); | 508 top_address + output_offset, output_offset, callers_pc); |
509 } | 509 } |
510 | 510 |
511 // Read caller's FP from the previous frame, and set this frame's FP. | 511 // Read caller's FP from the previous frame, and set this frame's FP. |
512 output_offset -= kPointerSize; | 512 output_offset -= kPointerSize; |
513 intptr_t value = output_[frame_index - 1]->GetFp(); | 513 intptr_t value = output_[frame_index - 1]->GetFp(); |
514 output_frame->SetFrameSlot(output_offset, value); | 514 output_frame->SetFrameSlot(output_offset, value); |
515 intptr_t fp_value = top_address + output_offset; | 515 intptr_t fp_value = top_address + output_offset; |
516 output_frame->SetFp(fp_value); | 516 output_frame->SetFp(fp_value); |
517 if (FLAG_trace_deopt) { | 517 if (trace_) { |
518 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | 518 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", |
519 fp_value, output_offset, value); | 519 fp_value, output_offset, value); |
520 } | 520 } |
521 | 521 |
522 // A marker value is used in place of the context. | 522 // A marker value is used in place of the context. |
523 output_offset -= kPointerSize; | 523 output_offset -= kPointerSize; |
524 intptr_t context = reinterpret_cast<intptr_t>( | 524 intptr_t context = reinterpret_cast<intptr_t>( |
525 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 525 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
526 output_frame->SetFrameSlot(output_offset, context); | 526 output_frame->SetFrameSlot(output_offset, context); |
527 if (FLAG_trace_deopt) { | 527 if (trace_) { |
528 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", | 528 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", |
529 top_address + output_offset, output_offset, context); | 529 top_address + output_offset, output_offset, context); |
530 } | 530 } |
531 | 531 |
532 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. | 532 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. |
533 output_offset -= kPointerSize; | 533 output_offset -= kPointerSize; |
534 value = reinterpret_cast<intptr_t>(function); | 534 value = reinterpret_cast<intptr_t>(function); |
535 output_frame->SetFrameSlot(output_offset, value); | 535 output_frame->SetFrameSlot(output_offset, value); |
536 if (FLAG_trace_deopt) { | 536 if (trace_) { |
537 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", | 537 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", |
538 top_address + output_offset, output_offset, value); | 538 top_address + output_offset, output_offset, value); |
539 } | 539 } |
540 | 540 |
541 // Number of incoming arguments. | 541 // Number of incoming arguments. |
542 output_offset -= kPointerSize; | 542 output_offset -= kPointerSize; |
543 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); | 543 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); |
544 output_frame->SetFrameSlot(output_offset, value); | 544 output_frame->SetFrameSlot(output_offset, value); |
545 if (FLAG_trace_deopt) { | 545 if (trace_) { |
546 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", | 546 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", |
547 top_address + output_offset, output_offset, value, height - 1); | 547 top_address + output_offset, output_offset, value, height - 1); |
548 } | 548 } |
549 | 549 |
550 ASSERT(0 == output_offset); | 550 ASSERT(0 == output_offset); |
551 | 551 |
552 Builtins* builtins = isolate_->builtins(); | 552 Builtins* builtins = isolate_->builtins(); |
553 Code* adaptor_trampoline = | 553 Code* adaptor_trampoline = |
554 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); | 554 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); |
555 uint32_t pc = reinterpret_cast<uint32_t>( | 555 uint32_t pc = reinterpret_cast<uint32_t>( |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 } | 696 } |
697 | 697 |
698 | 698 |
699 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, | 699 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, |
700 int frame_index) { | 700 int frame_index) { |
701 Builtins* builtins = isolate_->builtins(); | 701 Builtins* builtins = isolate_->builtins(); |
702 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | 702 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); |
703 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 703 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
704 unsigned height = iterator->Next(); | 704 unsigned height = iterator->Next(); |
705 unsigned height_in_bytes = height * kPointerSize; | 705 unsigned height_in_bytes = height * kPointerSize; |
706 if (FLAG_trace_deopt) { | 706 if (trace_) { |
707 PrintF(" translating construct stub => height=%d\n", height_in_bytes); | 707 PrintF(" translating construct stub => height=%d\n", height_in_bytes); |
708 } | 708 } |
709 | 709 |
710 unsigned fixed_frame_size = 7 * kPointerSize; | 710 unsigned fixed_frame_size = 7 * kPointerSize; |
711 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 711 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
712 | 712 |
713 // Allocate and store the output frame description. | 713 // Allocate and store the output frame description. |
714 FrameDescription* output_frame = | 714 FrameDescription* output_frame = |
715 new(output_frame_size) FrameDescription(output_frame_size, function); | 715 new(output_frame_size) FrameDescription(output_frame_size, function); |
716 output_frame->SetFrameType(StackFrame::CONSTRUCT); | 716 output_frame->SetFrameType(StackFrame::CONSTRUCT); |
(...skipping 14 matching lines...) Expand all Loading... |
731 unsigned output_offset = output_frame_size; | 731 unsigned output_offset = output_frame_size; |
732 for (int i = 0; i < parameter_count; ++i) { | 732 for (int i = 0; i < parameter_count; ++i) { |
733 output_offset -= kPointerSize; | 733 output_offset -= kPointerSize; |
734 DoTranslateCommand(iterator, frame_index, output_offset); | 734 DoTranslateCommand(iterator, frame_index, output_offset); |
735 } | 735 } |
736 | 736 |
737 // Read caller's PC from the previous frame. | 737 // Read caller's PC from the previous frame. |
738 output_offset -= kPointerSize; | 738 output_offset -= kPointerSize; |
739 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 739 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
740 output_frame->SetFrameSlot(output_offset, callers_pc); | 740 output_frame->SetFrameSlot(output_offset, callers_pc); |
741 if (FLAG_trace_deopt) { | 741 if (trace_) { |
742 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", | 742 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", |
743 top_address + output_offset, output_offset, callers_pc); | 743 top_address + output_offset, output_offset, callers_pc); |
744 } | 744 } |
745 | 745 |
746 // Read caller's FP from the previous frame, and set this frame's FP. | 746 // Read caller's FP from the previous frame, and set this frame's FP. |
747 output_offset -= kPointerSize; | 747 output_offset -= kPointerSize; |
748 intptr_t value = output_[frame_index - 1]->GetFp(); | 748 intptr_t value = output_[frame_index - 1]->GetFp(); |
749 output_frame->SetFrameSlot(output_offset, value); | 749 output_frame->SetFrameSlot(output_offset, value); |
750 intptr_t fp_value = top_address + output_offset; | 750 intptr_t fp_value = top_address + output_offset; |
751 output_frame->SetFp(fp_value); | 751 output_frame->SetFp(fp_value); |
752 if (FLAG_trace_deopt) { | 752 if (trace_) { |
753 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | 753 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", |
754 fp_value, output_offset, value); | 754 fp_value, output_offset, value); |
755 } | 755 } |
756 | 756 |
757 // The context can be gotten from the previous frame. | 757 // The context can be gotten from the previous frame. |
758 output_offset -= kPointerSize; | 758 output_offset -= kPointerSize; |
759 value = output_[frame_index - 1]->GetContext(); | 759 value = output_[frame_index - 1]->GetContext(); |
760 output_frame->SetFrameSlot(output_offset, value); | 760 output_frame->SetFrameSlot(output_offset, value); |
761 if (FLAG_trace_deopt) { | 761 if (trace_) { |
762 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", | 762 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", |
763 top_address + output_offset, output_offset, value); | 763 top_address + output_offset, output_offset, value); |
764 } | 764 } |
765 | 765 |
766 // A marker value is used in place of the function. | 766 // A marker value is used in place of the function. |
767 output_offset -= kPointerSize; | 767 output_offset -= kPointerSize; |
768 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); | 768 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT)); |
769 output_frame->SetFrameSlot(output_offset, value); | 769 output_frame->SetFrameSlot(output_offset, value); |
770 if (FLAG_trace_deopt) { | 770 if (trace_) { |
771 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n", | 771 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n", |
772 top_address + output_offset, output_offset, value); | 772 top_address + output_offset, output_offset, value); |
773 } | 773 } |
774 | 774 |
775 // The output frame reflects a JSConstructStubGeneric frame. | 775 // The output frame reflects a JSConstructStubGeneric frame. |
776 output_offset -= kPointerSize; | 776 output_offset -= kPointerSize; |
777 value = reinterpret_cast<intptr_t>(construct_stub); | 777 value = reinterpret_cast<intptr_t>(construct_stub); |
778 output_frame->SetFrameSlot(output_offset, value); | 778 output_frame->SetFrameSlot(output_offset, value); |
779 if (FLAG_trace_deopt) { | 779 if (trace_) { |
780 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n", | 780 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\n", |
781 top_address + output_offset, output_offset, value); | 781 top_address + output_offset, output_offset, value); |
782 } | 782 } |
783 | 783 |
784 // Number of incoming arguments. | 784 // Number of incoming arguments. |
785 output_offset -= kPointerSize; | 785 output_offset -= kPointerSize; |
786 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); | 786 value = reinterpret_cast<uint32_t>(Smi::FromInt(height - 1)); |
787 output_frame->SetFrameSlot(output_offset, value); | 787 output_frame->SetFrameSlot(output_offset, value); |
788 if (FLAG_trace_deopt) { | 788 if (trace_) { |
789 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", | 789 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", |
790 top_address + output_offset, output_offset, value, height - 1); | 790 top_address + output_offset, output_offset, value, height - 1); |
791 } | 791 } |
792 | 792 |
793 // The newly allocated object was passed as receiver in the artificial | 793 // The newly allocated object was passed as receiver in the artificial |
794 // constructor stub environment created by HEnvironment::CopyForInlining(). | 794 // constructor stub environment created by HEnvironment::CopyForInlining(). |
795 output_offset -= kPointerSize; | 795 output_offset -= kPointerSize; |
796 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); | 796 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); |
797 output_frame->SetFrameSlot(output_offset, value); | 797 output_frame->SetFrameSlot(output_offset, value); |
798 if (FLAG_trace_deopt) { | 798 if (trace_) { |
799 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n", | 799 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n", |
800 top_address + output_offset, output_offset, value); | 800 top_address + output_offset, output_offset, value); |
801 } | 801 } |
802 | 802 |
803 ASSERT(0 == output_offset); | 803 ASSERT(0 == output_offset); |
804 | 804 |
805 uint32_t pc = reinterpret_cast<uint32_t>( | 805 uint32_t pc = reinterpret_cast<uint32_t>( |
806 construct_stub->instruction_start() + | 806 construct_stub->instruction_start() + |
807 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | 807 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); |
808 output_frame->SetPc(pc); | 808 output_frame->SetPc(pc); |
809 } | 809 } |
810 | 810 |
811 | 811 |
812 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, | 812 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, |
813 int frame_index, | 813 int frame_index, |
814 bool is_setter_stub_frame) { | 814 bool is_setter_stub_frame) { |
815 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); | 815 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); |
816 // The receiver (and the implicit return value, if any) are expected in | 816 // The receiver (and the implicit return value, if any) are expected in |
817 // registers by the LoadIC/StoreIC, so they don't belong to the output stack | 817 // registers by the LoadIC/StoreIC, so they don't belong to the output stack |
818 // frame. This means that we have to use a height of 0. | 818 // frame. This means that we have to use a height of 0. |
819 unsigned height = 0; | 819 unsigned height = 0; |
820 unsigned height_in_bytes = height * kPointerSize; | 820 unsigned height_in_bytes = height * kPointerSize; |
821 const char* kind = is_setter_stub_frame ? "setter" : "getter"; | 821 const char* kind = is_setter_stub_frame ? "setter" : "getter"; |
822 if (FLAG_trace_deopt) { | 822 if (trace_) { |
823 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); | 823 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); |
824 } | 824 } |
825 | 825 |
826 // We need 1 stack entry for the return address + 4 stack entries from | 826 // We need 1 stack entry for the return address + 4 stack entries from |
827 // StackFrame::INTERNAL (FP, context, frame type, code object, see | 827 // StackFrame::INTERNAL (FP, context, frame type, code object, see |
828 // MacroAssembler::EnterFrame). For a setter stub frame we need one additional | 828 // MacroAssembler::EnterFrame). For a setter stub frame we need one additional |
829 // entry for the implicit return value, see | 829 // entry for the implicit return value, see |
830 // StoreStubCompiler::CompileStoreViaSetter. | 830 // StoreStubCompiler::CompileStoreViaSetter. |
831 unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0); | 831 unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0); |
832 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; | 832 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; |
(...skipping 13 matching lines...) Expand all Loading... |
846 // this frame's size. | 846 // this frame's size. |
847 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 847 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
848 output_frame->SetTop(top_address); | 848 output_frame->SetTop(top_address); |
849 | 849 |
850 unsigned output_offset = output_frame_size; | 850 unsigned output_offset = output_frame_size; |
851 | 851 |
852 // Read caller's PC from the previous frame. | 852 // Read caller's PC from the previous frame. |
853 output_offset -= kPointerSize; | 853 output_offset -= kPointerSize; |
854 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 854 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
855 output_frame->SetFrameSlot(output_offset, callers_pc); | 855 output_frame->SetFrameSlot(output_offset, callers_pc); |
856 if (FLAG_trace_deopt) { | 856 if (trace_) { |
857 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 857 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
858 " ; caller's pc\n", | 858 " ; caller's pc\n", |
859 top_address + output_offset, output_offset, callers_pc); | 859 top_address + output_offset, output_offset, callers_pc); |
860 } | 860 } |
861 | 861 |
862 // Read caller's FP from the previous frame, and set this frame's FP. | 862 // Read caller's FP from the previous frame, and set this frame's FP. |
863 output_offset -= kPointerSize; | 863 output_offset -= kPointerSize; |
864 intptr_t value = output_[frame_index - 1]->GetFp(); | 864 intptr_t value = output_[frame_index - 1]->GetFp(); |
865 output_frame->SetFrameSlot(output_offset, value); | 865 output_frame->SetFrameSlot(output_offset, value); |
866 intptr_t fp_value = top_address + output_offset; | 866 intptr_t fp_value = top_address + output_offset; |
867 output_frame->SetFp(fp_value); | 867 output_frame->SetFp(fp_value); |
868 if (FLAG_trace_deopt) { | 868 if (trace_) { |
869 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 869 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
870 " ; caller's fp\n", | 870 " ; caller's fp\n", |
871 fp_value, output_offset, value); | 871 fp_value, output_offset, value); |
872 } | 872 } |
873 | 873 |
874 // The context can be gotten from the previous frame. | 874 // The context can be gotten from the previous frame. |
875 output_offset -= kPointerSize; | 875 output_offset -= kPointerSize; |
876 value = output_[frame_index - 1]->GetContext(); | 876 value = output_[frame_index - 1]->GetContext(); |
877 output_frame->SetFrameSlot(output_offset, value); | 877 output_frame->SetFrameSlot(output_offset, value); |
878 if (FLAG_trace_deopt) { | 878 if (trace_) { |
879 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 879 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
880 " ; context\n", | 880 " ; context\n", |
881 top_address + output_offset, output_offset, value); | 881 top_address + output_offset, output_offset, value); |
882 } | 882 } |
883 | 883 |
884 // A marker value is used in place of the function. | 884 // A marker value is used in place of the function. |
885 output_offset -= kPointerSize; | 885 output_offset -= kPointerSize; |
886 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); | 886 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); |
887 output_frame->SetFrameSlot(output_offset, value); | 887 output_frame->SetFrameSlot(output_offset, value); |
888 if (FLAG_trace_deopt) { | 888 if (trace_) { |
889 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 889 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
890 " ; function (%s sentinel)\n", | 890 " ; function (%s sentinel)\n", |
891 top_address + output_offset, output_offset, value, kind); | 891 top_address + output_offset, output_offset, value, kind); |
892 } | 892 } |
893 | 893 |
894 // Get Code object from accessor stub. | 894 // Get Code object from accessor stub. |
895 output_offset -= kPointerSize; | 895 output_offset -= kPointerSize; |
896 Builtins::Name name = is_setter_stub_frame ? | 896 Builtins::Name name = is_setter_stub_frame ? |
897 Builtins::kStoreIC_Setter_ForDeopt : | 897 Builtins::kStoreIC_Setter_ForDeopt : |
898 Builtins::kLoadIC_Getter_ForDeopt; | 898 Builtins::kLoadIC_Getter_ForDeopt; |
899 Code* accessor_stub = isolate_->builtins()->builtin(name); | 899 Code* accessor_stub = isolate_->builtins()->builtin(name); |
900 value = reinterpret_cast<intptr_t>(accessor_stub); | 900 value = reinterpret_cast<intptr_t>(accessor_stub); |
901 output_frame->SetFrameSlot(output_offset, value); | 901 output_frame->SetFrameSlot(output_offset, value); |
902 if (FLAG_trace_deopt) { | 902 if (trace_) { |
903 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 903 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
904 " ; code object\n", | 904 " ; code object\n", |
905 top_address + output_offset, output_offset, value); | 905 top_address + output_offset, output_offset, value); |
906 } | 906 } |
907 | 907 |
908 // Skip receiver. | 908 // Skip receiver. |
909 Translation::Opcode opcode = | 909 Translation::Opcode opcode = |
910 static_cast<Translation::Opcode>(iterator->Next()); | 910 static_cast<Translation::Opcode>(iterator->Next()); |
911 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | 911 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); |
912 | 912 |
(...skipping 22 matching lines...) Expand all Loading... |
935 if (frame_index != 0) { | 935 if (frame_index != 0) { |
936 function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 936 function = JSFunction::cast(ComputeLiteral(iterator->Next())); |
937 } else { | 937 } else { |
938 int closure_id = iterator->Next(); | 938 int closure_id = iterator->Next(); |
939 USE(closure_id); | 939 USE(closure_id); |
940 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); | 940 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); |
941 function = function_; | 941 function = function_; |
942 } | 942 } |
943 unsigned height = iterator->Next(); | 943 unsigned height = iterator->Next(); |
944 unsigned height_in_bytes = height * kPointerSize; | 944 unsigned height_in_bytes = height * kPointerSize; |
945 if (FLAG_trace_deopt) { | 945 if (trace_) { |
946 PrintF(" translating "); | 946 PrintF(" translating "); |
947 function->PrintName(); | 947 function->PrintName(); |
948 PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); | 948 PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); |
949 } | 949 } |
950 | 950 |
951 // The 'fixed' part of the frame consists of the incoming parameters and | 951 // The 'fixed' part of the frame consists of the incoming parameters and |
952 // the part described by JavaScriptFrameConstants. | 952 // the part described by JavaScriptFrameConstants. |
953 unsigned fixed_frame_size = ComputeFixedSize(function); | 953 unsigned fixed_frame_size = ComputeFixedSize(function); |
954 unsigned input_frame_size = input_->GetFrameSize(); | 954 unsigned input_frame_size = input_->GetFrameSize(); |
955 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 955 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 // function code and AST id of the bailout. | 1013 // function code and AST id of the bailout. |
1014 output_offset -= kPointerSize; | 1014 output_offset -= kPointerSize; |
1015 input_offset -= kPointerSize; | 1015 input_offset -= kPointerSize; |
1016 intptr_t value; | 1016 intptr_t value; |
1017 if (is_bottommost) { | 1017 if (is_bottommost) { |
1018 value = input_->GetFrameSlot(input_offset); | 1018 value = input_->GetFrameSlot(input_offset); |
1019 } else { | 1019 } else { |
1020 value = output_[frame_index - 1]->GetPc(); | 1020 value = output_[frame_index - 1]->GetPc(); |
1021 } | 1021 } |
1022 output_frame->SetFrameSlot(output_offset, value); | 1022 output_frame->SetFrameSlot(output_offset, value); |
1023 if (FLAG_trace_deopt) { | 1023 if (trace_) { |
1024 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", | 1024 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", |
1025 top_address + output_offset, output_offset, value); | 1025 top_address + output_offset, output_offset, value); |
1026 } | 1026 } |
1027 | 1027 |
1028 // The caller's frame pointer for the bottommost output frame is the same | 1028 // The caller's frame pointer for the bottommost output frame is the same |
1029 // as in the input frame. For all subsequent output frames, it can be | 1029 // as in the input frame. For all subsequent output frames, it can be |
1030 // read from the previous one. Also compute and set this frame's frame | 1030 // read from the previous one. Also compute and set this frame's frame |
1031 // pointer. | 1031 // pointer. |
1032 output_offset -= kPointerSize; | 1032 output_offset -= kPointerSize; |
1033 input_offset -= kPointerSize; | 1033 input_offset -= kPointerSize; |
1034 if (is_bottommost) { | 1034 if (is_bottommost) { |
1035 value = input_->GetFrameSlot(input_offset); | 1035 value = input_->GetFrameSlot(input_offset); |
1036 } else { | 1036 } else { |
1037 value = output_[frame_index - 1]->GetFp(); | 1037 value = output_[frame_index - 1]->GetFp(); |
1038 } | 1038 } |
1039 output_frame->SetFrameSlot(output_offset, value); | 1039 output_frame->SetFrameSlot(output_offset, value); |
1040 intptr_t fp_value = top_address + output_offset; | 1040 intptr_t fp_value = top_address + output_offset; |
1041 ASSERT(!is_bottommost || | 1041 ASSERT(!is_bottommost || |
1042 (input_->GetRegister(ebp.code()) + has_alignment_padding_ * kPointerSize) == | 1042 (input_->GetRegister(ebp.code()) + has_alignment_padding_ * kPointerSize) == |
1043 fp_value); | 1043 fp_value); |
1044 output_frame->SetFp(fp_value); | 1044 output_frame->SetFp(fp_value); |
1045 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); | 1045 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); |
1046 if (FLAG_trace_deopt) { | 1046 if (trace_) { |
1047 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | 1047 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", |
1048 fp_value, output_offset, value); | 1048 fp_value, output_offset, value); |
1049 } | 1049 } |
1050 ASSERT(!is_bottommost || !has_alignment_padding_ || | 1050 ASSERT(!is_bottommost || !has_alignment_padding_ || |
1051 (fp_value & kPointerSize) != 0); | 1051 (fp_value & kPointerSize) != 0); |
1052 | 1052 |
1053 // For the bottommost output frame the context can be gotten from the input | 1053 // For the bottommost output frame the context can be gotten from the input |
1054 // frame. For all subsequent output frames it can be gotten from the function | 1054 // frame. For all subsequent output frames it can be gotten from the function |
1055 // so long as we don't inline functions that need local contexts. | 1055 // so long as we don't inline functions that need local contexts. |
1056 output_offset -= kPointerSize; | 1056 output_offset -= kPointerSize; |
1057 input_offset -= kPointerSize; | 1057 input_offset -= kPointerSize; |
1058 if (is_bottommost) { | 1058 if (is_bottommost) { |
1059 value = input_->GetFrameSlot(input_offset); | 1059 value = input_->GetFrameSlot(input_offset); |
1060 } else { | 1060 } else { |
1061 value = reinterpret_cast<uint32_t>(function->context()); | 1061 value = reinterpret_cast<uint32_t>(function->context()); |
1062 } | 1062 } |
1063 output_frame->SetFrameSlot(output_offset, value); | 1063 output_frame->SetFrameSlot(output_offset, value); |
1064 output_frame->SetContext(value); | 1064 output_frame->SetContext(value); |
1065 if (is_topmost) output_frame->SetRegister(esi.code(), value); | 1065 if (is_topmost) output_frame->SetRegister(esi.code(), value); |
1066 if (FLAG_trace_deopt) { | 1066 if (trace_) { |
1067 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", | 1067 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", |
1068 top_address + output_offset, output_offset, value); | 1068 top_address + output_offset, output_offset, value); |
1069 } | 1069 } |
1070 | 1070 |
1071 // The function was mentioned explicitly in the BEGIN_FRAME. | 1071 // The function was mentioned explicitly in the BEGIN_FRAME. |
1072 output_offset -= kPointerSize; | 1072 output_offset -= kPointerSize; |
1073 input_offset -= kPointerSize; | 1073 input_offset -= kPointerSize; |
1074 value = reinterpret_cast<uint32_t>(function); | 1074 value = reinterpret_cast<uint32_t>(function); |
1075 // The function for the bottommost output frame should also agree with the | 1075 // The function for the bottommost output frame should also agree with the |
1076 // input frame. | 1076 // input frame. |
1077 ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value); | 1077 ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value); |
1078 output_frame->SetFrameSlot(output_offset, value); | 1078 output_frame->SetFrameSlot(output_offset, value); |
1079 if (FLAG_trace_deopt) { | 1079 if (trace_) { |
1080 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", | 1080 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", |
1081 top_address + output_offset, output_offset, value); | 1081 top_address + output_offset, output_offset, value); |
1082 } | 1082 } |
1083 | 1083 |
1084 // Translate the rest of the frame. | 1084 // Translate the rest of the frame. |
1085 for (unsigned i = 0; i < height; ++i) { | 1085 for (unsigned i = 0; i < height; ++i) { |
1086 output_offset -= kPointerSize; | 1086 output_offset -= kPointerSize; |
1087 DoTranslateCommand(iterator, frame_index, output_offset); | 1087 DoTranslateCommand(iterator, frame_index, output_offset); |
1088 } | 1088 } |
1089 ASSERT(0 == output_offset); | 1089 ASSERT(0 == output_offset); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 } | 1352 } |
1353 __ bind(&done); | 1353 __ bind(&done); |
1354 } | 1354 } |
1355 | 1355 |
1356 #undef __ | 1356 #undef __ |
1357 | 1357 |
1358 | 1358 |
1359 } } // namespace v8::internal | 1359 } } // namespace v8::internal |
1360 | 1360 |
1361 #endif // V8_TARGET_ARCH_IA32 | 1361 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |