Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: src/ia32/deoptimizer-ia32.cc

Issue 10532066: Reimplement dynamic frame alignment for frames that are compiled via OSR or have more than 2 double… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: don't align frames of recursive functions Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/ia32/frames-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize; 344 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize;
345 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value(); 345 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
346 unsigned outgoing_size = outgoing_height * kPointerSize; 346 unsigned outgoing_size = outgoing_height * kPointerSize;
347 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size; 347 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
348 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call. 348 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
349 349
350 if (FLAG_trace_osr) { 350 if (FLAG_trace_osr) {
351 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ", 351 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
352 reinterpret_cast<intptr_t>(function_)); 352 reinterpret_cast<intptr_t>(function_));
353 function_->PrintName(); 353 function_->PrintName();
354 PrintF(" => node=%u, frame=%d->%d]\n", 354 PrintF(" => node=%u, frame=%d->%d, ebp:esp=0x%08x:0x%08x]\n",
355 ast_id, 355 ast_id,
356 input_frame_size, 356 input_frame_size,
357 output_frame_size); 357 output_frame_size,
358 input_->GetRegister(ebp.code()),
359 input_->GetRegister(esp.code()));
358 } 360 }
359 361
360 // There's only one output frame in the OSR case. 362 // There's only one output frame in the OSR case.
361 output_count_ = 1; 363 output_count_ = 1;
362 output_ = new FrameDescription*[1]; 364 output_ = new FrameDescription*[1];
363 output_[0] = new(output_frame_size) FrameDescription( 365 output_[0] = new(output_frame_size) FrameDescription(
364 output_frame_size, function_); 366 output_frame_size, function_);
365 output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT); 367 output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT);
366 368
367 // Clear the incoming parameters in the optimized frame to avoid 369 // Clear the incoming parameters in the optimized frame to avoid
(...skipping 29 matching lines...) Expand all
397 case StandardFrameConstants::kCallerFPOffset: 399 case StandardFrameConstants::kCallerFPOffset:
398 name = "fp"; 400 name = "fp";
399 break; 401 break;
400 case StandardFrameConstants::kContextOffset: 402 case StandardFrameConstants::kContextOffset:
401 name = "context"; 403 name = "context";
402 break; 404 break;
403 case StandardFrameConstants::kMarkerOffset: 405 case StandardFrameConstants::kMarkerOffset:
404 name = "function"; 406 name = "function";
405 break; 407 break;
406 } 408 }
407 PrintF(" [esp + %d] <- 0x%08x ; [esp + %d] (fixed part - %s)\n", 409 PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n",
408 output_offset, 410 output_offset,
409 input_value, 411 input_value,
410 input_offset, 412 input_offset,
411 name); 413 name);
412 } 414 }
413 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset)); 415 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
414 input_offset -= kPointerSize; 416 input_offset -= kPointerSize;
415 output_offset -= kPointerSize; 417 output_offset -= kPointerSize;
416 } 418 }
417 419
420 // All OSR stack frames are dynamically aligned to an 8-byte boundary.
421 int frame_pointer = input_->GetRegister(ebp.code());
422 if ((frame_pointer & kPointerSize) != 0) {
423 frame_pointer -= kPointerSize;
424 has_alignment_padding_ = 1;
425 }
426
427 int32_t alignment_state = (has_alignment_padding_ == 1) ?
428 kAlignmentPaddingPushed :
429 kNoAlignmentPadding;
430 if (FLAG_trace_osr) {
431 PrintF(" [sp + %d] <- 0x%08x ; (alignment state)\n",
432 output_offset,
433 alignment_state);
434 }
435 output_[0]->SetFrameSlot(output_offset, alignment_state);
436 output_offset -= kPointerSize;
437
418 // Translate the rest of the frame. 438 // Translate the rest of the frame.
419 while (ok && input_offset >= 0) { 439 while (ok && input_offset >= 0) {
420 ok = DoOsrTranslateCommand(&iterator, &input_offset); 440 ok = DoOsrTranslateCommand(&iterator, &input_offset);
421 } 441 }
422 442
423 // If translation of any command failed, continue using the input frame. 443 // If translation of any command failed, continue using the input frame.
424 if (!ok) { 444 if (!ok) {
425 delete output_[0]; 445 delete output_[0];
426 output_[0] = input_; 446 output_[0] = input_;
427 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); 447 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
428 } else { 448 } else {
429 // Set up the frame pointer and the context pointer. 449 // Set up the frame pointer and the context pointer.
430 output_[0]->SetRegister(ebp.code(), input_->GetRegister(ebp.code())); 450 output_[0]->SetRegister(ebp.code(), frame_pointer);
431 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); 451 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code()));
432 452
433 unsigned pc_offset = data->OsrPcOffset()->value(); 453 unsigned pc_offset = data->OsrPcOffset()->value();
434 uint32_t pc = reinterpret_cast<uint32_t>( 454 uint32_t pc = reinterpret_cast<uint32_t>(
435 optimized_code_->entry() + pc_offset); 455 optimized_code_->entry() + pc_offset);
436 output_[0]->SetPc(pc); 456 output_[0]->SetPc(pc);
437 } 457 }
438 Code* continuation = 458 Code* continuation =
439 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); 459 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
440 output_[0]->SetContinuation( 460 output_[0]->SetContinuation(
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 FrameDescription* output_frame = 701 FrameDescription* output_frame =
682 new(output_frame_size) FrameDescription(output_frame_size, function); 702 new(output_frame_size) FrameDescription(output_frame_size, function);
683 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); 703 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
684 704
685 bool is_bottommost = (0 == frame_index); 705 bool is_bottommost = (0 == frame_index);
686 bool is_topmost = (output_count_ - 1 == frame_index); 706 bool is_topmost = (output_count_ - 1 == frame_index);
687 ASSERT(frame_index >= 0 && frame_index < output_count_); 707 ASSERT(frame_index >= 0 && frame_index < output_count_);
688 ASSERT(output_[frame_index] == NULL); 708 ASSERT(output_[frame_index] == NULL);
689 output_[frame_index] = output_frame; 709 output_[frame_index] = output_frame;
690 710
711 // Compute the incoming parameter translation.
712 int parameter_count = function->shared()->formal_parameter_count() + 1;
713 unsigned output_offset = output_frame_size;
714 unsigned input_offset = input_frame_size;
715
716 unsigned alignment_state_offset =
717 input_offset - parameter_count * kPointerSize -
718 StandardFrameConstants::kFixedFrameSize -
719 kPointerSize;
720 ASSERT(JavaScriptFrameConstants::kDynamicAlignmentStateOffset ==
721 JavaScriptFrameConstants::kLocal0Offset);
722
691 // The top address for the bottommost output frame can be computed from 723 // 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 724 // 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 725 // subsequent output frames, it can be computed from the previous one's
694 // top address and the current frame's size. 726 // top address and the current frame's size.
695 uint32_t top_address; 727 uint32_t top_address;
696 if (is_bottommost) { 728 if (is_bottommost) {
729 int32_t alignment_state = input_->GetFrameSlot(alignment_state_offset);
730 has_alignment_padding_ =
731 (alignment_state == kAlignmentPaddingPushed) ? 1 : 0;
697 // 2 = context and function in the frame. 732 // 2 = context and function in the frame.
698 top_address = 733 // If the optimized frame had alignment padding, adjust the frame pointer
699 input_->GetRegister(ebp.code()) - (2 * kPointerSize) - height_in_bytes; 734 // to point to the new position of the old frame pointer after padding
735 // is removed. Subtract 2 * kPointerSize for the context and function slots.
736 top_address = input_->GetRegister(ebp.code()) - (2 * kPointerSize) -
737 height_in_bytes + has_alignment_padding_ * kPointerSize;
700 } else { 738 } else {
701 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 739 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
702 } 740 }
703 output_frame->SetTop(top_address); 741 output_frame->SetTop(top_address);
704 742
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) { 743 for (int i = 0; i < parameter_count; ++i) {
710 output_offset -= kPointerSize; 744 output_offset -= kPointerSize;
711 DoTranslateCommand(iterator, frame_index, output_offset); 745 DoTranslateCommand(iterator, frame_index, output_offset);
712 } 746 }
713 input_offset -= (parameter_count * kPointerSize); 747 input_offset -= (parameter_count * kPointerSize);
714 748
715 // There are no translation commands for the caller's pc and fp, the 749 // 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 750 // context, and the function. Synthesize their values and set them up
717 // explicitly. 751 // explicitly.
718 // 752 //
(...skipping 21 matching lines...) Expand all
740 // pointer. 774 // pointer.
741 output_offset -= kPointerSize; 775 output_offset -= kPointerSize;
742 input_offset -= kPointerSize; 776 input_offset -= kPointerSize;
743 if (is_bottommost) { 777 if (is_bottommost) {
744 value = input_->GetFrameSlot(input_offset); 778 value = input_->GetFrameSlot(input_offset);
745 } else { 779 } else {
746 value = output_[frame_index - 1]->GetFp(); 780 value = output_[frame_index - 1]->GetFp();
747 } 781 }
748 output_frame->SetFrameSlot(output_offset, value); 782 output_frame->SetFrameSlot(output_offset, value);
749 intptr_t fp_value = top_address + output_offset; 783 intptr_t fp_value = top_address + output_offset;
750 ASSERT(!is_bottommost || input_->GetRegister(ebp.code()) == fp_value); 784 ASSERT(!is_bottommost ||
785 (input_->GetRegister(ebp.code()) + has_alignment_padding_ * kPointerSize) ==
786 fp_value);
751 output_frame->SetFp(fp_value); 787 output_frame->SetFp(fp_value);
752 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); 788 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value);
753 if (FLAG_trace_deopt) { 789 if (FLAG_trace_deopt) {
754 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", 790 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
755 fp_value, output_offset, value); 791 fp_value, output_offset, value);
756 } 792 }
793 ASSERT(!is_bottommost || !has_alignment_padding_ ||
794 (fp_value & kPointerSize) != 0);
757 795
758 // For the bottommost output frame the context can be gotten from the input 796 // 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 797 // 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. 798 // so long as we don't inline functions that need local contexts.
761 output_offset -= kPointerSize; 799 output_offset -= kPointerSize;
762 input_offset -= kPointerSize; 800 input_offset -= kPointerSize;
763 if (is_bottommost) { 801 if (is_bottommost) {
764 value = input_->GetFrameSlot(input_offset); 802 value = input_->GetFrameSlot(input_offset);
765 } else { 803 } else {
766 value = reinterpret_cast<uint32_t>(function->context()); 804 value = reinterpret_cast<uint32_t>(function->context());
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 __ push(eax); 979 __ push(eax);
942 __ PrepareCallCFunction(1, ebx); 980 __ PrepareCallCFunction(1, ebx);
943 __ mov(Operand(esp, 0 * kPointerSize), eax); 981 __ mov(Operand(esp, 0 * kPointerSize), eax);
944 { 982 {
945 AllowExternalCallThatCantCauseGC scope(masm()); 983 AllowExternalCallThatCantCauseGC scope(masm());
946 __ CallCFunction( 984 __ CallCFunction(
947 ExternalReference::compute_output_frames_function(isolate), 1); 985 ExternalReference::compute_output_frames_function(isolate), 1);
948 } 986 }
949 __ pop(eax); 987 __ pop(eax);
950 988
989 if (type() != OSR) {
990 // If frame was dynamically aligned, pop padding.
991 Label no_padding;
992 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
993 Immediate(0));
994 __ j(equal, &no_padding);
995 __ pop(ecx);
996 if (FLAG_debug_code) {
997 __ cmp(ecx, Immediate(kAlignmentZapValue));
998 __ Assert(equal, "alignment marker expected");
999 }
1000 __ bind(&no_padding);
1001 } else {
1002 // If frame needs dynamic alignment push padding.
1003 Label no_padding;
1004 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
1005 Immediate(0));
1006 __ j(equal, &no_padding);
1007 __ push(Immediate(kAlignmentZapValue));
1008 __ bind(&no_padding);
1009 }
1010
951 // Replace the current frame with the output frames. 1011 // Replace the current frame with the output frames.
952 Label outer_push_loop, inner_push_loop; 1012 Label outer_push_loop, inner_push_loop;
953 // Outer loop state: eax = current FrameDescription**, edx = one past the 1013 // Outer loop state: eax = current FrameDescription**, edx = one past the
954 // last FrameDescription**. 1014 // last FrameDescription**.
955 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); 1015 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
956 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); 1016 __ mov(eax, Operand(eax, Deoptimizer::output_offset()));
957 __ lea(edx, Operand(eax, edx, times_4, 0)); 1017 __ lea(edx, Operand(eax, edx, times_4, 0));
958 __ bind(&outer_push_loop); 1018 __ bind(&outer_push_loop);
959 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. 1019 // Inner loop state: ebx = current FrameDescription*, ecx = loop index.
960 __ mov(ebx, Operand(eax, 0)); 1020 __ mov(ebx, Operand(eax, 0));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 } 1071 }
1012 __ bind(&done); 1072 __ bind(&done);
1013 } 1073 }
1014 1074
1015 #undef __ 1075 #undef __
1016 1076
1017 1077
1018 } } // namespace v8::internal 1078 } } // namespace v8::internal
1019 1079
1020 #endif // V8_TARGET_ARCH_IA32 1080 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/ia32/frames-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698