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 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 ok = DoOsrTranslateCommand(&iterator, &input_offset); | 420 ok = DoOsrTranslateCommand(&iterator, &input_offset); |
421 } | 421 } |
422 | 422 |
423 // If translation of any command failed, continue using the input frame. | 423 // If translation of any command failed, continue using the input frame. |
424 if (!ok) { | 424 if (!ok) { |
425 delete output_[0]; | 425 delete output_[0]; |
426 output_[0] = input_; | 426 output_[0] = input_; |
427 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); | 427 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); |
428 } else { | 428 } else { |
429 // Set up the frame pointer and the context pointer. | 429 // Set up the frame pointer and the context pointer. |
430 // All OSR stack frames are dynamically aligned to an 8-byte boundary. | 430 output_[0]->SetRegister(ebp.code(), input_->GetRegister(ebp.code())); |
431 int frame_pointer = input_->GetRegister(ebp.code()); | |
432 if ((frame_pointer & 0x4) == 0) { | |
433 // Return address at FP + 4 should be aligned, so FP mod 8 should be 4. | |
434 frame_pointer -= kPointerSize; | |
435 has_alignment_padding_ = 1; | |
436 } | |
437 output_[0]->SetRegister(ebp.code(), frame_pointer); | |
438 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); | 431 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); |
439 | 432 |
440 unsigned pc_offset = data->OsrPcOffset()->value(); | 433 unsigned pc_offset = data->OsrPcOffset()->value(); |
441 uint32_t pc = reinterpret_cast<uint32_t>( | 434 uint32_t pc = reinterpret_cast<uint32_t>( |
442 optimized_code_->entry() + pc_offset); | 435 optimized_code_->entry() + pc_offset); |
443 output_[0]->SetPc(pc); | 436 output_[0]->SetPc(pc); |
444 } | 437 } |
445 Code* continuation = | 438 Code* continuation = |
446 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); | 439 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); |
447 output_[0]->SetContinuation( | 440 output_[0]->SetContinuation( |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 ASSERT(frame_index >= 0 && frame_index < output_count_); | 678 ASSERT(frame_index >= 0 && frame_index < output_count_); |
686 ASSERT(output_[frame_index] == NULL); | 679 ASSERT(output_[frame_index] == NULL); |
687 output_[frame_index] = output_frame; | 680 output_[frame_index] = output_frame; |
688 | 681 |
689 // The top address for the bottommost output frame can be computed from | 682 // The top address for the bottommost output frame can be computed from |
690 // the input frame pointer and the output frame's height. For all | 683 // the input frame pointer and the output frame's height. For all |
691 // subsequent output frames, it can be computed from the previous one's | 684 // subsequent output frames, it can be computed from the previous one's |
692 // top address and the current frame's size. | 685 // top address and the current frame's size. |
693 uint32_t top_address; | 686 uint32_t top_address; |
694 if (is_bottommost) { | 687 if (is_bottommost) { |
695 // If the optimized frame had alignment padding, adjust the frame pointer | 688 // 2 = context and function in the frame. |
696 // to point to the new position of the old frame pointer after padding | 689 top_address = |
697 // is removed. Subtract 2 * kPointerSize for the context and function slots. | 690 input_->GetRegister(ebp.code()) - (2 * kPointerSize) - height_in_bytes; |
698 top_address = input_->GetRegister(ebp.code()) - (2 * kPointerSize) - | |
699 height_in_bytes + has_alignment_padding_ * kPointerSize; | |
700 } else { | 691 } else { |
701 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 692 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
702 } | 693 } |
703 output_frame->SetTop(top_address); | 694 output_frame->SetTop(top_address); |
704 | 695 |
705 // Compute the incoming parameter translation. | 696 // Compute the incoming parameter translation. |
706 int parameter_count = function->shared()->formal_parameter_count() + 1; | 697 int parameter_count = function->shared()->formal_parameter_count() + 1; |
707 unsigned output_offset = output_frame_size; | 698 unsigned output_offset = output_frame_size; |
708 unsigned input_offset = input_frame_size; | 699 unsigned input_offset = input_frame_size; |
709 for (int i = 0; i < parameter_count; ++i) { | 700 for (int i = 0; i < parameter_count; ++i) { |
(...skipping 30 matching lines...) Expand all Loading... |
740 // pointer. | 731 // pointer. |
741 output_offset -= kPointerSize; | 732 output_offset -= kPointerSize; |
742 input_offset -= kPointerSize; | 733 input_offset -= kPointerSize; |
743 if (is_bottommost) { | 734 if (is_bottommost) { |
744 value = input_->GetFrameSlot(input_offset); | 735 value = input_->GetFrameSlot(input_offset); |
745 } else { | 736 } else { |
746 value = output_[frame_index - 1]->GetFp(); | 737 value = output_[frame_index - 1]->GetFp(); |
747 } | 738 } |
748 output_frame->SetFrameSlot(output_offset, value); | 739 output_frame->SetFrameSlot(output_offset, value); |
749 intptr_t fp_value = top_address + output_offset; | 740 intptr_t fp_value = top_address + output_offset; |
750 ASSERT(!is_bottommost || | 741 ASSERT(!is_bottommost || input_->GetRegister(ebp.code()) == fp_value); |
751 input_->GetRegister(ebp.code()) + has_alignment_padding_ * kPointerSize | |
752 == fp_value); | |
753 output_frame->SetFp(fp_value); | 742 output_frame->SetFp(fp_value); |
754 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); | 743 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); |
755 if (FLAG_trace_deopt) { | 744 if (FLAG_trace_deopt) { |
756 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | 745 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", |
757 fp_value, output_offset, value); | 746 fp_value, output_offset, value); |
758 } | 747 } |
759 | 748 |
760 // For the bottommost output frame the context can be gotten from the input | 749 // For the bottommost output frame the context can be gotten from the input |
761 // frame. For all subsequent output frames it can be gotten from the function | 750 // frame. For all subsequent output frames it can be gotten from the function |
762 // so long as we don't inline functions that need local contexts. | 751 // so long as we don't inline functions that need local contexts. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 // limit and copy the contents of the activation frame to the input | 921 // limit and copy the contents of the activation frame to the input |
933 // frame description. | 922 // frame description. |
934 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset())); | 923 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset())); |
935 Label pop_loop; | 924 Label pop_loop; |
936 __ bind(&pop_loop); | 925 __ bind(&pop_loop); |
937 __ pop(Operand(edx, 0)); | 926 __ pop(Operand(edx, 0)); |
938 __ add(edx, Immediate(sizeof(uint32_t))); | 927 __ add(edx, Immediate(sizeof(uint32_t))); |
939 __ cmp(ecx, esp); | 928 __ cmp(ecx, esp); |
940 __ j(not_equal, &pop_loop); | 929 __ j(not_equal, &pop_loop); |
941 | 930 |
942 // If frame was dynamically aligned, pop padding. | |
943 Label sentinel, sentinel_done; | |
944 __ pop(ecx); | |
945 __ cmp(ecx, Operand(eax, Deoptimizer::frame_alignment_marker_offset())); | |
946 __ j(equal, &sentinel); | |
947 __ push(ecx); | |
948 __ jmp(&sentinel_done); | |
949 __ bind(&sentinel); | |
950 __ mov(Operand(eax, Deoptimizer::has_alignment_padding_offset()), | |
951 Immediate(1)); | |
952 __ bind(&sentinel_done); | |
953 // Compute the output frame in the deoptimizer. | 931 // Compute the output frame in the deoptimizer. |
954 __ push(eax); | 932 __ push(eax); |
955 __ PrepareCallCFunction(1, ebx); | 933 __ PrepareCallCFunction(1, ebx); |
956 __ mov(Operand(esp, 0 * kPointerSize), eax); | 934 __ mov(Operand(esp, 0 * kPointerSize), eax); |
957 { | 935 { |
958 AllowExternalCallThatCantCauseGC scope(masm()); | 936 AllowExternalCallThatCantCauseGC scope(masm()); |
959 __ CallCFunction( | 937 __ CallCFunction( |
960 ExternalReference::compute_output_frames_function(isolate), 1); | 938 ExternalReference::compute_output_frames_function(isolate), 1); |
961 } | 939 } |
962 __ pop(eax); | 940 __ pop(eax); |
963 | 941 |
964 if (type() == OSR) { | |
965 // If alignment padding is added, push the sentinel. | |
966 Label no_osr_padding; | |
967 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), | |
968 Immediate(0)); | |
969 __ j(equal, &no_osr_padding, Label::kNear); | |
970 __ push(Operand(eax, Deoptimizer::frame_alignment_marker_offset())); | |
971 __ bind(&no_osr_padding); | |
972 } | |
973 | |
974 | |
975 // Replace the current frame with the output frames. | 942 // Replace the current frame with the output frames. |
976 Label outer_push_loop, inner_push_loop; | 943 Label outer_push_loop, inner_push_loop; |
977 // Outer loop state: eax = current FrameDescription**, edx = one past the | 944 // Outer loop state: eax = current FrameDescription**, edx = one past the |
978 // last FrameDescription**. | 945 // last FrameDescription**. |
979 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); | 946 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); |
980 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); | 947 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); |
981 __ lea(edx, Operand(eax, edx, times_4, 0)); | 948 __ lea(edx, Operand(eax, edx, times_4, 0)); |
982 __ bind(&outer_push_loop); | 949 __ bind(&outer_push_loop); |
983 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. | 950 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. |
984 __ mov(ebx, Operand(eax, 0)); | 951 __ mov(ebx, Operand(eax, 0)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1035 } | 1002 } |
1036 __ bind(&done); | 1003 __ bind(&done); |
1037 } | 1004 } |
1038 | 1005 |
1039 #undef __ | 1006 #undef __ |
1040 | 1007 |
1041 | 1008 |
1042 } } // namespace v8::internal | 1009 } } // namespace v8::internal |
1043 | 1010 |
1044 #endif // V8_TARGET_ARCH_IA32 | 1011 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |