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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 output_offset, | 408 output_offset, |
409 input_value, | 409 input_value, |
410 input_offset, | 410 input_offset, |
411 name); | 411 name); |
412 } | 412 } |
413 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset)); | 413 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset)); |
414 input_offset -= kPointerSize; | 414 input_offset -= kPointerSize; |
415 output_offset -= kPointerSize; | 415 output_offset -= kPointerSize; |
416 } | 416 } |
417 | 417 |
418 // All OSR stack frames are dynamically aligned to an 8-byte boundary. | |
Massi
2012/06/11 10:03:32
Why don't we need to (eventually) move the incomin
Vyacheslav Egorov (Google)
2012/06/11 11:02:43
Incomming arguments are part of the frame translat
| |
419 int frame_pointer = input_->GetRegister(ebp.code()); | |
420 if ((frame_pointer & 0x4) == 0) { | |
421 // Return address at FP + 4 should be aligned, so FP mod 8 should be 4. | |
422 frame_pointer -= kPointerSize; | |
423 has_alignment_padding_ = 1; | |
424 } | |
425 | |
426 int32_t alignment_marker = has_alignment_padding_ ? 2 : 0; | |
427 if (FLAG_trace_osr) { | |
428 PrintF(" [esp + %d] <- 0x%08x ; (alignment marker)\n", | |
429 output_offset, | |
430 alignment_marker); | |
431 } | |
432 output_[0]->SetFrameSlot(output_offset, alignment_marker); | |
433 output_offset -= kPointerSize; | |
434 | |
418 // Translate the rest of the frame. | 435 // Translate the rest of the frame. |
419 while (ok && input_offset >= 0) { | 436 while (ok && input_offset >= 0) { |
420 ok = DoOsrTranslateCommand(&iterator, &input_offset); | 437 ok = DoOsrTranslateCommand(&iterator, &input_offset); |
421 } | 438 } |
422 | 439 |
423 // If translation of any command failed, continue using the input frame. | 440 // If translation of any command failed, continue using the input frame. |
424 if (!ok) { | 441 if (!ok) { |
425 delete output_[0]; | 442 delete output_[0]; |
426 output_[0] = input_; | 443 output_[0] = input_; |
427 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); | 444 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); |
428 } else { | 445 } else { |
429 // Set up the frame pointer and the context pointer. | 446 // Set up the frame pointer and the context pointer. |
430 output_[0]->SetRegister(ebp.code(), input_->GetRegister(ebp.code())); | 447 output_[0]->SetRegister(ebp.code(), frame_pointer); |
431 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); | 448 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); |
432 | 449 |
433 unsigned pc_offset = data->OsrPcOffset()->value(); | 450 unsigned pc_offset = data->OsrPcOffset()->value(); |
434 uint32_t pc = reinterpret_cast<uint32_t>( | 451 uint32_t pc = reinterpret_cast<uint32_t>( |
435 optimized_code_->entry() + pc_offset); | 452 optimized_code_->entry() + pc_offset); |
436 output_[0]->SetPc(pc); | 453 output_[0]->SetPc(pc); |
437 } | 454 } |
438 Code* continuation = | 455 Code* continuation = |
439 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); | 456 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); |
440 output_[0]->SetContinuation( | 457 output_[0]->SetContinuation( |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
681 FrameDescription* output_frame = | 698 FrameDescription* output_frame = |
682 new(output_frame_size) FrameDescription(output_frame_size, function); | 699 new(output_frame_size) FrameDescription(output_frame_size, function); |
683 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 700 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); |
684 | 701 |
685 bool is_bottommost = (0 == frame_index); | 702 bool is_bottommost = (0 == frame_index); |
686 bool is_topmost = (output_count_ - 1 == frame_index); | 703 bool is_topmost = (output_count_ - 1 == frame_index); |
687 ASSERT(frame_index >= 0 && frame_index < output_count_); | 704 ASSERT(frame_index >= 0 && frame_index < output_count_); |
688 ASSERT(output_[frame_index] == NULL); | 705 ASSERT(output_[frame_index] == NULL); |
689 output_[frame_index] = output_frame; | 706 output_[frame_index] = output_frame; |
690 | 707 |
708 // Compute the incoming parameter translation. | |
709 int parameter_count = function->shared()->formal_parameter_count() + 1; | |
710 unsigned output_offset = output_frame_size; | |
711 unsigned input_offset = input_frame_size; | |
712 | |
713 unsigned alignment_marker_offset = | |
714 input_offset - parameter_count * kPointerSize - | |
715 StandardFrameConstants::kFixedFrameSize - | |
716 kPointerSize; | |
717 | |
691 // The top address for the bottommost output frame can be computed from | 718 // The top address for the bottommost output frame can be computed from |
692 // the input frame pointer and the output frame's height. For all | 719 // the input frame pointer and the output frame's height. For all |
693 // subsequent output frames, it can be computed from the previous one's | 720 // subsequent output frames, it can be computed from the previous one's |
694 // top address and the current frame's size. | 721 // top address and the current frame's size. |
695 uint32_t top_address; | 722 uint32_t top_address; |
696 if (is_bottommost) { | 723 if (is_bottommost) { |
724 has_alignment_padding_ = | |
725 (input_->GetFrameSlot(alignment_marker_offset) == 2) ? 1 : 0; | |
697 // 2 = context and function in the frame. | 726 // 2 = context and function in the frame. |
698 top_address = | 727 // If the optimized frame had alignment padding, adjust the frame pointer |
699 input_->GetRegister(ebp.code()) - (2 * kPointerSize) - height_in_bytes; | 728 // to point to the new position of the old frame pointer after padding |
729 // is removed. Subtract 2 * kPointerSize for the context and function slots. | |
730 top_address = input_->GetRegister(ebp.code()) - (2 * kPointerSize) - | |
731 height_in_bytes + has_alignment_padding_ * kPointerSize; | |
700 } else { | 732 } else { |
701 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 733 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
702 } | 734 } |
703 output_frame->SetTop(top_address); | 735 output_frame->SetTop(top_address); |
704 | 736 |
705 // Compute the incoming parameter translation. | |
706 int parameter_count = function->shared()->formal_parameter_count() + 1; | |
707 unsigned output_offset = output_frame_size; | |
708 unsigned input_offset = input_frame_size; | |
709 for (int i = 0; i < parameter_count; ++i) { | 737 for (int i = 0; i < parameter_count; ++i) { |
710 output_offset -= kPointerSize; | 738 output_offset -= kPointerSize; |
711 DoTranslateCommand(iterator, frame_index, output_offset); | 739 DoTranslateCommand(iterator, frame_index, output_offset); |
712 } | 740 } |
713 input_offset -= (parameter_count * kPointerSize); | 741 input_offset -= (parameter_count * kPointerSize); |
714 | 742 |
715 // There are no translation commands for the caller's pc and fp, the | 743 // There are no translation commands for the caller's pc and fp, the |
716 // context, and the function. Synthesize their values and set them up | 744 // context, and the function. Synthesize their values and set them up |
717 // explicitly. | 745 // explicitly. |
718 // | 746 // |
(...skipping 21 matching lines...) Expand all Loading... | |
740 // pointer. | 768 // pointer. |
741 output_offset -= kPointerSize; | 769 output_offset -= kPointerSize; |
742 input_offset -= kPointerSize; | 770 input_offset -= kPointerSize; |
743 if (is_bottommost) { | 771 if (is_bottommost) { |
744 value = input_->GetFrameSlot(input_offset); | 772 value = input_->GetFrameSlot(input_offset); |
745 } else { | 773 } else { |
746 value = output_[frame_index - 1]->GetFp(); | 774 value = output_[frame_index - 1]->GetFp(); |
747 } | 775 } |
748 output_frame->SetFrameSlot(output_offset, value); | 776 output_frame->SetFrameSlot(output_offset, value); |
749 intptr_t fp_value = top_address + output_offset; | 777 intptr_t fp_value = top_address + output_offset; |
750 ASSERT(!is_bottommost || input_->GetRegister(ebp.code()) == fp_value); | 778 ASSERT(!is_bottommost || |
779 (input_->GetRegister(ebp.code()) + has_alignment_padding_ * kPointerSize) == fp_value); | |
751 output_frame->SetFp(fp_value); | 780 output_frame->SetFp(fp_value); |
752 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); | 781 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); |
753 if (FLAG_trace_deopt) { | 782 if (FLAG_trace_deopt) { |
754 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | 783 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", |
755 fp_value, output_offset, value); | 784 fp_value, output_offset, value); |
756 } | 785 } |
757 | 786 |
758 // For the bottommost output frame the context can be gotten from the input | 787 // For the bottommost output frame the context can be gotten from the input |
759 // frame. For all subsequent output frames it can be gotten from the function | 788 // frame. For all subsequent output frames it can be gotten from the function |
760 // so long as we don't inline functions that need local contexts. | 789 // so long as we don't inline functions that need local contexts. |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 __ push(eax); | 970 __ push(eax); |
942 __ PrepareCallCFunction(1, ebx); | 971 __ PrepareCallCFunction(1, ebx); |
943 __ mov(Operand(esp, 0 * kPointerSize), eax); | 972 __ mov(Operand(esp, 0 * kPointerSize), eax); |
944 { | 973 { |
945 AllowExternalCallThatCantCauseGC scope(masm()); | 974 AllowExternalCallThatCantCauseGC scope(masm()); |
946 __ CallCFunction( | 975 __ CallCFunction( |
947 ExternalReference::compute_output_frames_function(isolate), 1); | 976 ExternalReference::compute_output_frames_function(isolate), 1); |
948 } | 977 } |
949 __ pop(eax); | 978 __ pop(eax); |
950 | 979 |
980 if (type() != OSR) { | |
981 // If frame was dynamically aligned, pop padding. | |
982 Label no_padding; | |
983 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), Immediate( 0)); | |
984 __ j(equal, &no_padding); | |
985 __ pop(ecx); | |
986 __ cmp(ecx, Immediate(Smi::FromInt(0x12345))); | |
987 __ Assert(equal, "alignment marker expected"); | |
988 __ bind(&no_padding); | |
989 } else { | |
990 Label no_padding; | |
991 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), Immediate( 0)); | |
992 __ j(equal, &no_padding); | |
993 __ push(Immediate(Smi::FromInt(0x12345))); | |
994 __ bind(&no_padding); | |
995 } | |
996 | |
951 // Replace the current frame with the output frames. | 997 // Replace the current frame with the output frames. |
952 Label outer_push_loop, inner_push_loop; | 998 Label outer_push_loop, inner_push_loop; |
953 // Outer loop state: eax = current FrameDescription**, edx = one past the | 999 // Outer loop state: eax = current FrameDescription**, edx = one past the |
954 // last FrameDescription**. | 1000 // last FrameDescription**. |
955 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); | 1001 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); |
956 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); | 1002 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); |
957 __ lea(edx, Operand(eax, edx, times_4, 0)); | 1003 __ lea(edx, Operand(eax, edx, times_4, 0)); |
958 __ bind(&outer_push_loop); | 1004 __ bind(&outer_push_loop); |
959 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. | 1005 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. |
960 __ mov(ebx, Operand(eax, 0)); | 1006 __ mov(ebx, Operand(eax, 0)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1011 } | 1057 } |
1012 __ bind(&done); | 1058 __ bind(&done); |
1013 } | 1059 } |
1014 | 1060 |
1015 #undef __ | 1061 #undef __ |
1016 | 1062 |
1017 | 1063 |
1018 } } // namespace v8::internal | 1064 } } // namespace v8::internal |
1019 | 1065 |
1020 #endif // V8_TARGET_ARCH_IA32 | 1066 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |