| 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. | 
|  | 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_state = (has_alignment_padding_ == 1) ? | 
|  | 427     kAlignmentPaddingPushed : | 
|  | 428     kNoAlignmentPadding; | 
|  | 429   if (FLAG_trace_osr) { | 
|  | 430     PrintF("    [esp + %d] <- 0x%08x ; (alignment state)\n", | 
|  | 431            output_offset, | 
|  | 432            alignment_state); | 
|  | 433   } | 
|  | 434   output_[0]->SetFrameSlot(output_offset, alignment_state); | 
|  | 435   output_offset -= kPointerSize; | 
|  | 436 | 
| 418   // Translate the rest of the frame. | 437   // Translate the rest of the frame. | 
| 419   while (ok && input_offset >= 0) { | 438   while (ok && input_offset >= 0) { | 
| 420     ok = DoOsrTranslateCommand(&iterator, &input_offset); | 439     ok = DoOsrTranslateCommand(&iterator, &input_offset); | 
| 421   } | 440   } | 
| 422 | 441 | 
| 423   // If translation of any command failed, continue using the input frame. | 442   // If translation of any command failed, continue using the input frame. | 
| 424   if (!ok) { | 443   if (!ok) { | 
| 425     delete output_[0]; | 444     delete output_[0]; | 
| 426     output_[0] = input_; | 445     output_[0] = input_; | 
| 427     output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); | 446     output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); | 
| 428   } else { | 447   } else { | 
| 429     // Set up the frame pointer and the context pointer. | 448     // Set up the frame pointer and the context pointer. | 
| 430     output_[0]->SetRegister(ebp.code(), input_->GetRegister(ebp.code())); | 449     output_[0]->SetRegister(ebp.code(), frame_pointer); | 
| 431     output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); | 450     output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); | 
| 432 | 451 | 
| 433     unsigned pc_offset = data->OsrPcOffset()->value(); | 452     unsigned pc_offset = data->OsrPcOffset()->value(); | 
| 434     uint32_t pc = reinterpret_cast<uint32_t>( | 453     uint32_t pc = reinterpret_cast<uint32_t>( | 
| 435         optimized_code_->entry() + pc_offset); | 454         optimized_code_->entry() + pc_offset); | 
| 436     output_[0]->SetPc(pc); | 455     output_[0]->SetPc(pc); | 
| 437   } | 456   } | 
| 438   Code* continuation = | 457   Code* continuation = | 
| 439       function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); | 458       function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); | 
| 440   output_[0]->SetContinuation( | 459   output_[0]->SetContinuation( | 
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 681   FrameDescription* output_frame = | 700   FrameDescription* output_frame = | 
| 682       new(output_frame_size) FrameDescription(output_frame_size, function); | 701       new(output_frame_size) FrameDescription(output_frame_size, function); | 
| 683   output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 702   output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 
| 684 | 703 | 
| 685   bool is_bottommost = (0 == frame_index); | 704   bool is_bottommost = (0 == frame_index); | 
| 686   bool is_topmost = (output_count_ - 1 == frame_index); | 705   bool is_topmost = (output_count_ - 1 == frame_index); | 
| 687   ASSERT(frame_index >= 0 && frame_index < output_count_); | 706   ASSERT(frame_index >= 0 && frame_index < output_count_); | 
| 688   ASSERT(output_[frame_index] == NULL); | 707   ASSERT(output_[frame_index] == NULL); | 
| 689   output_[frame_index] = output_frame; | 708   output_[frame_index] = output_frame; | 
| 690 | 709 | 
|  | 710   // Compute the incoming parameter translation. | 
|  | 711   int parameter_count = function->shared()->formal_parameter_count() + 1; | 
|  | 712   unsigned output_offset = output_frame_size; | 
|  | 713   unsigned input_offset = input_frame_size; | 
|  | 714 | 
|  | 715   unsigned alignment_state_offset = | 
|  | 716     input_offset - parameter_count * kPointerSize - | 
|  | 717     StandardFrameConstants::kFixedFrameSize - | 
|  | 718     kPointerSize; | 
|  | 719 | 
| 691   // The top address for the bottommost output frame can be computed from | 720   // 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 | 721   // 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 | 722   // subsequent output frames, it can be computed from the previous one's | 
| 694   // top address and the current frame's size. | 723   // top address and the current frame's size. | 
| 695   uint32_t top_address; | 724   uint32_t top_address; | 
| 696   if (is_bottommost) { | 725   if (is_bottommost) { | 
|  | 726     int32_t alignment_state = input_->GetFrameSlot(alignment_state_offset); | 
|  | 727     has_alignment_padding_ = | 
|  | 728       (alignment_state == kAlignmentPaddingPushed) ? 1 : 0; | 
| 697     // 2 = context and function in the frame. | 729     // 2 = context and function in the frame. | 
| 698     top_address = | 730     // If the optimized frame had alignment padding, adjust the frame pointer | 
| 699         input_->GetRegister(ebp.code()) - (2 * kPointerSize) - height_in_bytes; | 731     // to point to the new position of the old frame pointer after padding | 
|  | 732     // is removed. Subtract 2 * kPointerSize for the context and function slots. | 
|  | 733     top_address = input_->GetRegister(ebp.code()) - (2 * kPointerSize) - | 
|  | 734         height_in_bytes + has_alignment_padding_ * kPointerSize; | 
| 700   } else { | 735   } else { | 
| 701     top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 736     top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 
| 702   } | 737   } | 
| 703   output_frame->SetTop(top_address); | 738   output_frame->SetTop(top_address); | 
| 704 | 739 | 
| 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) { | 740   for (int i = 0; i < parameter_count; ++i) { | 
| 710     output_offset -= kPointerSize; | 741     output_offset -= kPointerSize; | 
| 711     DoTranslateCommand(iterator, frame_index, output_offset); | 742     DoTranslateCommand(iterator, frame_index, output_offset); | 
| 712   } | 743   } | 
| 713   input_offset -= (parameter_count * kPointerSize); | 744   input_offset -= (parameter_count * kPointerSize); | 
| 714 | 745 | 
| 715   // There are no translation commands for the caller's pc and fp, the | 746   // 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 | 747   // context, and the function.  Synthesize their values and set them up | 
| 717   // explicitly. | 748   // explicitly. | 
| 718   // | 749   // | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 740   // pointer. | 771   // pointer. | 
| 741   output_offset -= kPointerSize; | 772   output_offset -= kPointerSize; | 
| 742   input_offset -= kPointerSize; | 773   input_offset -= kPointerSize; | 
| 743   if (is_bottommost) { | 774   if (is_bottommost) { | 
| 744     value = input_->GetFrameSlot(input_offset); | 775     value = input_->GetFrameSlot(input_offset); | 
| 745   } else { | 776   } else { | 
| 746     value = output_[frame_index - 1]->GetFp(); | 777     value = output_[frame_index - 1]->GetFp(); | 
| 747   } | 778   } | 
| 748   output_frame->SetFrameSlot(output_offset, value); | 779   output_frame->SetFrameSlot(output_offset, value); | 
| 749   intptr_t fp_value = top_address + output_offset; | 780   intptr_t fp_value = top_address + output_offset; | 
| 750   ASSERT(!is_bottommost || input_->GetRegister(ebp.code()) == fp_value); | 781   ASSERT(!is_bottommost || | 
|  | 782     (input_->GetRegister(ebp.code()) + has_alignment_padding_ * kPointerSize) == | 
|  | 783     fp_value); | 
| 751   output_frame->SetFp(fp_value); | 784   output_frame->SetFp(fp_value); | 
| 752   if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); | 785   if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); | 
| 753   if (FLAG_trace_deopt) { | 786   if (FLAG_trace_deopt) { | 
| 754     PrintF("    0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | 787     PrintF("    0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", | 
| 755            fp_value, output_offset, value); | 788            fp_value, output_offset, value); | 
| 756   } | 789   } | 
| 757 | 790 | 
| 758   // For the bottommost output frame the context can be gotten from the input | 791   // 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 | 792   // 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. | 793   // 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); | 974   __ push(eax); | 
| 942   __ PrepareCallCFunction(1, ebx); | 975   __ PrepareCallCFunction(1, ebx); | 
| 943   __ mov(Operand(esp, 0 * kPointerSize), eax); | 976   __ mov(Operand(esp, 0 * kPointerSize), eax); | 
| 944   { | 977   { | 
| 945     AllowExternalCallThatCantCauseGC scope(masm()); | 978     AllowExternalCallThatCantCauseGC scope(masm()); | 
| 946     __ CallCFunction( | 979     __ CallCFunction( | 
| 947         ExternalReference::compute_output_frames_function(isolate), 1); | 980         ExternalReference::compute_output_frames_function(isolate), 1); | 
| 948   } | 981   } | 
| 949   __ pop(eax); | 982   __ pop(eax); | 
| 950 | 983 | 
|  | 984   if (type() != OSR) { | 
|  | 985     // If frame was dynamically aligned, pop padding. | 
|  | 986     Label no_padding; | 
|  | 987     __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), | 
|  | 988            Immediate(0)); | 
|  | 989     __ j(equal, &no_padding); | 
|  | 990     __ pop(ecx); | 
|  | 991     if (FLAG_debug_code) { | 
|  | 992       __ cmp(ecx, Immediate(kAlignmentZapValue)); | 
|  | 993       __ Assert(equal, "alignment marker expected"); | 
|  | 994     } | 
|  | 995     __ bind(&no_padding); | 
|  | 996   } else { | 
|  | 997     // If frame needs dynamic alignment push padding. | 
|  | 998     Label no_padding; | 
|  | 999     __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), | 
|  | 1000            Immediate(0)); | 
|  | 1001     __ j(equal, &no_padding); | 
|  | 1002     __ push(Immediate(kAlignmentZapValue)); | 
|  | 1003     __ bind(&no_padding); | 
|  | 1004   } | 
|  | 1005 | 
| 951   // Replace the current frame with the output frames. | 1006   // Replace the current frame with the output frames. | 
| 952   Label outer_push_loop, inner_push_loop; | 1007   Label outer_push_loop, inner_push_loop; | 
| 953   // Outer loop state: eax = current FrameDescription**, edx = one past the | 1008   // Outer loop state: eax = current FrameDescription**, edx = one past the | 
| 954   // last FrameDescription**. | 1009   // last FrameDescription**. | 
| 955   __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); | 1010   __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); | 
| 956   __ mov(eax, Operand(eax, Deoptimizer::output_offset())); | 1011   __ mov(eax, Operand(eax, Deoptimizer::output_offset())); | 
| 957   __ lea(edx, Operand(eax, edx, times_4, 0)); | 1012   __ lea(edx, Operand(eax, edx, times_4, 0)); | 
| 958   __ bind(&outer_push_loop); | 1013   __ bind(&outer_push_loop); | 
| 959   // Inner loop state: ebx = current FrameDescription*, ecx = loop index. | 1014   // Inner loop state: ebx = current FrameDescription*, ecx = loop index. | 
| 960   __ mov(ebx, Operand(eax, 0)); | 1015   __ mov(ebx, Operand(eax, 0)); | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1011   } | 1066   } | 
| 1012   __ bind(&done); | 1067   __ bind(&done); | 
| 1013 } | 1068 } | 
| 1014 | 1069 | 
| 1015 #undef __ | 1070 #undef __ | 
| 1016 | 1071 | 
| 1017 | 1072 | 
| 1018 } }  // namespace v8::internal | 1073 } }  // namespace v8::internal | 
| 1019 | 1074 | 
| 1020 #endif  // V8_TARGET_ARCH_IA32 | 1075 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|