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

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

Issue 7976024: Add dynamic stack frame alignment to optimized functions with untagged doubles on the stack. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove stray changes from assembler-[platform].h files. Created 9 years, 3 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 unsigned pc_offset = data->OsrPcOffset()->value(); 433 unsigned pc_offset = data->OsrPcOffset()->value();
434 uint32_t pc = reinterpret_cast<uint32_t>( 434 uint32_t pc = reinterpret_cast<uint32_t>(
435 optimized_code_->entry() + pc_offset); 435 optimized_code_->entry() + pc_offset);
436 output_[0]->SetPc(pc); 436 output_[0]->SetPc(pc);
437 } 437 }
438 Code* continuation = 438 Code* continuation =
439 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); 439 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
440 output_[0]->SetContinuation( 440 output_[0]->SetContinuation(
441 reinterpret_cast<uint32_t>(continuation->entry())); 441 reinterpret_cast<uint32_t>(continuation->entry()));
442 442
443 // All OSR stack frames are dynamically aligned to an 8-byte boundary.
444 int frame_pointer = output_[0]->GetRegister(ebp.code());
Kevin Millikin (Chromium) 2011/09/23 09:38:49 Don't put this here (i.e., don't set ebp register
445 if ((frame_pointer & 0x4) == 0) {
446 // Return address at FP + 4 should be aligned, so FP mod 8 should be 4.
447 output_[0]->SetRegister(ebp.code(), frame_pointer - kPointerSize);
448 has_alignment_padding_ = 1;
449 }
450
443 if (FLAG_trace_osr) { 451 if (FLAG_trace_osr) {
444 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 452 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
445 ok ? "finished" : "aborted", 453 ok ? "finished" : "aborted",
446 reinterpret_cast<intptr_t>(function)); 454 reinterpret_cast<intptr_t>(function));
447 function->PrintName(); 455 function->PrintName();
448 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); 456 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
449 } 457 }
450 } 458 }
451 459
452 460
(...skipping 30 matching lines...) Expand all
483 bool is_bottommost = (0 == frame_index); 491 bool is_bottommost = (0 == frame_index);
484 bool is_topmost = (output_count_ - 1 == frame_index); 492 bool is_topmost = (output_count_ - 1 == frame_index);
485 ASSERT(frame_index >= 0 && frame_index < output_count_); 493 ASSERT(frame_index >= 0 && frame_index < output_count_);
486 ASSERT(output_[frame_index] == NULL); 494 ASSERT(output_[frame_index] == NULL);
487 output_[frame_index] = output_frame; 495 output_[frame_index] = output_frame;
488 496
489 // The top address for the bottommost output frame can be computed from 497 // The top address for the bottommost output frame can be computed from
490 // the input frame pointer and the output frame's height. For all 498 // the input frame pointer and the output frame's height. For all
491 // subsequent output frames, it can be computed from the previous one's 499 // subsequent output frames, it can be computed from the previous one's
492 // top address and the current frame's size. 500 // top address and the current frame's size.
501
502 // If the optimized frame had alignment padding, adjust the frame pointer
Kevin Millikin (Chromium) 2011/09/23 09:38:49 I also don't like this here. First, it breaks up
William Hesse 2011/09/23 12:50:11 Done.
503 // to point to the new position of the old frame pointer after padding
504 // is removed.
505 if (has_alignment_padding_ == 1) {
506 input_->SetRegister(ebp.code(),
507 input_->GetRegister(ebp.code()) + kPointerSize);
508 }
509
493 uint32_t top_address; 510 uint32_t top_address;
494 if (is_bottommost) { 511 if (is_bottommost) {
495 // 2 = context and function in the frame. 512 // 2 = context and function in the frame.
496 top_address = 513 top_address =
497 input_->GetRegister(ebp.code()) - (2 * kPointerSize) - height_in_bytes; 514 input_->GetRegister(ebp.code()) - (2 * kPointerSize) - height_in_bytes;
Kevin Millikin (Chromium) 2011/09/23 09:38:49 Here: input_->GetRegister(ebp.code()) - (2 * kPoi
William Hesse 2011/09/23 12:50:11 Done.
498 } else { 515 } else {
499 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 516 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
500 } 517 }
501 output_frame->SetTop(top_address); 518 output_frame->SetTop(top_address);
502 519
503 // Compute the incoming parameter translation. 520 // Compute the incoming parameter translation.
504 int parameter_count = function->shared()->formal_parameter_count() + 1; 521 int parameter_count = function->shared()->formal_parameter_count() + 1;
505 unsigned output_offset = output_frame_size; 522 unsigned output_offset = output_frame_size;
506 unsigned input_offset = input_frame_size; 523 unsigned input_offset = input_frame_size;
507 for (int i = 0; i < parameter_count; ++i) { 524 for (int i = 0; i < parameter_count; ++i) {
(...skipping 30 matching lines...) Expand all
538 // pointer. 555 // pointer.
539 output_offset -= kPointerSize; 556 output_offset -= kPointerSize;
540 input_offset -= kPointerSize; 557 input_offset -= kPointerSize;
541 if (is_bottommost) { 558 if (is_bottommost) {
542 value = input_->GetFrameSlot(input_offset); 559 value = input_->GetFrameSlot(input_offset);
543 } else { 560 } else {
544 value = output_[frame_index - 1]->GetFp(); 561 value = output_[frame_index - 1]->GetFp();
545 } 562 }
546 output_frame->SetFrameSlot(output_offset, value); 563 output_frame->SetFrameSlot(output_offset, value);
547 intptr_t fp_value = top_address + output_offset; 564 intptr_t fp_value = top_address + output_offset;
548 ASSERT(!is_bottommost || input_->GetRegister(ebp.code()) == fp_value); 565 ASSERT(!is_bottommost || input_->GetRegister(ebp.code()) == fp_value);
Kevin Millikin (Chromium) 2011/09/23 09:38:49 Here: ASSERT(!is_bottommost || input_->Get
William Hesse 2011/09/23 12:50:11 Done.
549 output_frame->SetFp(fp_value); 566 output_frame->SetFp(fp_value);
550 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); 567 if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value);
551 if (FLAG_trace_deopt) { 568 if (FLAG_trace_deopt) {
552 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", 569 PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n",
553 fp_value, output_offset, value); 570 fp_value, output_offset, value);
554 } 571 }
555 572
556 // For the bottommost output frame the context can be gotten from the input 573 // For the bottommost output frame the context can be gotten from the input
557 // frame. For all subsequent output frames it can be gotten from the function 574 // frame. For all subsequent output frames it can be gotten from the function
558 // so long as we don't inline functions that need local contexts. 575 // so long as we don't inline functions that need local contexts.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // limit and copy the contents of the activation frame to the input 744 // limit and copy the contents of the activation frame to the input
728 // frame description. 745 // frame description.
729 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset())); 746 __ lea(edx, Operand(ebx, FrameDescription::frame_content_offset()));
730 Label pop_loop; 747 Label pop_loop;
731 __ bind(&pop_loop); 748 __ bind(&pop_loop);
732 __ pop(Operand(edx, 0)); 749 __ pop(Operand(edx, 0));
733 __ add(Operand(edx), Immediate(sizeof(uint32_t))); 750 __ add(Operand(edx), Immediate(sizeof(uint32_t)));
734 __ cmp(ecx, Operand(esp)); 751 __ cmp(ecx, Operand(esp));
735 __ j(not_equal, &pop_loop); 752 __ j(not_equal, &pop_loop);
736 753
754 // If frame was dynamically aligned, pop padding.
755 Label sentinel, sentinel_done;
756 __ pop(Operand(ecx));
757 __ cmp(ecx, Operand(eax, Deoptimizer::frame_alignment_marker_offset()));
758 __ j(equal, &sentinel);
759 __ push(Operand(ecx));
760 __ jmp(&sentinel_done);
761 __ bind(&sentinel);
762 __ mov(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
763 Immediate(1));
764 __ bind(&sentinel_done);
737 // Compute the output frame in the deoptimizer. 765 // Compute the output frame in the deoptimizer.
738 __ push(eax); 766 __ push(eax);
739 __ PrepareCallCFunction(1, ebx); 767 __ PrepareCallCFunction(1, ebx);
740 __ mov(Operand(esp, 0 * kPointerSize), eax); 768 __ mov(Operand(esp, 0 * kPointerSize), eax);
741 { 769 {
742 AllowExternalCallThatCantCauseGC scope(masm()); 770 AllowExternalCallThatCantCauseGC scope(masm());
743 __ CallCFunction( 771 __ CallCFunction(
744 ExternalReference::compute_output_frames_function(isolate), 1); 772 ExternalReference::compute_output_frames_function(isolate), 1);
745 } 773 }
746 __ pop(eax); 774 __ pop(eax);
747 775
776 if (type() == OSR) {
777 // If alignment padding is added, push the sentinel.
778 Label no_osr_padding;
779 __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
780 Immediate(0));
781 __ j(equal, &no_osr_padding, Label::kNear);
782 __ push(Operand(eax, Deoptimizer::frame_alignment_marker_offset()));
783 __ bind(&no_osr_padding);
784 }
785
786
748 // Replace the current frame with the output frames. 787 // Replace the current frame with the output frames.
749 Label outer_push_loop, inner_push_loop; 788 Label outer_push_loop, inner_push_loop;
750 // Outer loop state: eax = current FrameDescription**, edx = one past the 789 // Outer loop state: eax = current FrameDescription**, edx = one past the
751 // last FrameDescription**. 790 // last FrameDescription**.
752 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset())); 791 __ mov(edx, Operand(eax, Deoptimizer::output_count_offset()));
753 __ mov(eax, Operand(eax, Deoptimizer::output_offset())); 792 __ mov(eax, Operand(eax, Deoptimizer::output_offset()));
754 __ lea(edx, Operand(eax, edx, times_4, 0)); 793 __ lea(edx, Operand(eax, edx, times_4, 0));
755 __ bind(&outer_push_loop); 794 __ bind(&outer_push_loop);
756 // Inner loop state: ebx = current FrameDescription*, ecx = loop index. 795 // Inner loop state: ebx = current FrameDescription*, ecx = loop index.
757 __ mov(ebx, Operand(eax, 0)); 796 __ mov(ebx, Operand(eax, 0));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 } 847 }
809 __ bind(&done); 848 __ bind(&done);
810 } 849 }
811 850
812 #undef __ 851 #undef __
813 852
814 853
815 } } // namespace v8::internal 854 } } // namespace v8::internal
816 855
817 #endif // V8_TARGET_ARCH_IA32 856 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698