| 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 |