From: palfia@homejinni.com Date: Fri, 17 May 2013 10:46:42 +0000 (+0000) Subject: MIPS: Unify deoptimizer for JavaScript frames. X-Git-Tag: upstream/4.7.83~14199 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ef4ce2e550f79b64cab2e79eb5c913867d9059c8;p=platform%2Fupstream%2Fv8.git MIPS: Unify deoptimizer for JavaScript frames. Port r14715 (84633474) Original commit message: This unifies the translation of an optimized frame to a full JavaScript frame. Only the frame's context and fp register as well as alignment padding are different on each architecture and can be factored out. BUG= Review URL: https://codereview.chromium.org/15291002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14717 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc index bd1d0c4..31fad2b 100644 --- a/src/mips/deoptimizer-mips.cc +++ b/src/mips/deoptimizer-mips.cc @@ -366,184 +366,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() { } -// This code is very similar to ia32/arm code, but relies on register names -// (fp, sp) and how the frame is laid out. -void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, - int frame_index) { - // Read the ast node id, function, and frame height for this output frame. - BailoutId node_id = BailoutId(iterator->Next()); - JSFunction* function; - if (frame_index != 0) { - function = JSFunction::cast(ComputeLiteral(iterator->Next())); - } else { - int closure_id = iterator->Next(); - USE(closure_id); - ASSERT_EQ(Translation::kSelfLiteralId, closure_id); - function = function_; - } - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (trace_) { - PrintF(" translating "); - function->PrintName(); - PrintF(" => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); - } - - // The 'fixed' part of the frame consists of the incoming parameters and - // the part described by JavaScriptFrameConstants. - unsigned fixed_frame_size = ComputeFixedSize(function); - unsigned input_frame_size = input_->GetFrameSize(); - unsigned output_frame_size = height_in_bytes + fixed_frame_size; - - // Allocate and store the output frame description. - FrameDescription* output_frame = - new(output_frame_size) FrameDescription(output_frame_size, function); - output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); - - bool is_bottommost = (0 == frame_index); - bool is_topmost = (output_count_ - 1 == frame_index); - ASSERT(frame_index >= 0 && frame_index < output_count_); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address for the bottommost output frame can be computed from - // the input frame pointer and the output frame's height. For all - // subsequent output frames, it can be computed from the previous one's - // top address and the current frame's size. - uint32_t top_address; - if (is_bottommost) { - // 2 = context and function in the frame. - top_address = - input_->GetRegister(fp.code()) - (2 * kPointerSize) - height_in_bytes; - } else { - top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - } - output_frame->SetTop(top_address); - - // Compute the incoming parameter translation. - int parameter_count = function->shared()->formal_parameter_count() + 1; - unsigned output_offset = output_frame_size; - unsigned input_offset = input_frame_size; - for (int i = 0; i < parameter_count; ++i) { - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - input_offset -= (parameter_count * kPointerSize); - - // There are no translation commands for the caller's pc and fp, the - // context, and the function. Synthesize their values and set them up - // explicitly. - // - // The caller's pc for the bottommost output frame is the same as in the - // input frame. For all subsequent output frames, it can be read from the - // previous one. This frame's pc can be computed from the non-optimized - // function code and AST id of the bailout. - output_offset -= kPointerSize; - input_offset -= kPointerSize; - intptr_t value; - if (is_bottommost) { - value = input_->GetFrameSlot(input_offset); - } else { - value = output_[frame_index - 1]->GetPc(); - } - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", - top_address + output_offset, output_offset, value); - } - - // The caller's frame pointer for the bottommost output frame is the same - // as in the input frame. For all subsequent output frames, it can be - // read from the previous one. Also compute and set this frame's frame - // pointer. - output_offset -= kPointerSize; - input_offset -= kPointerSize; - if (is_bottommost) { - value = input_->GetFrameSlot(input_offset); - } else { - value = output_[frame_index - 1]->GetFp(); - } - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - ASSERT(!is_bottommost || input_->GetRegister(fp.code()) == fp_value); - output_frame->SetFp(fp_value); - if (is_topmost) { - output_frame->SetRegister(fp.code(), fp_value); - } - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", - fp_value, output_offset, value); - } - - // For the bottommost output frame the context can be gotten from the input - // frame. For all subsequent output frames it can be gotten from the function - // so long as we don't inline functions that need local contexts. - output_offset -= kPointerSize; - input_offset -= kPointerSize; - if (is_bottommost) { - value = input_->GetFrameSlot(input_offset); - } else { - value = reinterpret_cast(function->context()); - } - output_frame->SetFrameSlot(output_offset, value); - output_frame->SetContext(value); - if (is_topmost) output_frame->SetRegister(cp.code(), value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context\n", - top_address + output_offset, output_offset, value); - } - - // The function was mentioned explicitly in the BEGIN_FRAME. - output_offset -= kPointerSize; - input_offset -= kPointerSize; - value = reinterpret_cast(function); - // The function for the bottommost output frame should also agree with the - // input frame. - ASSERT(!is_bottommost || input_->GetFrameSlot(input_offset) == value); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", - top_address + output_offset, output_offset, value); - } - - // Translate the rest of the frame. - for (unsigned i = 0; i < height; ++i) { - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - ASSERT(0 == output_offset); - - // Compute this frame's PC, state, and continuation. - Code* non_optimized_code = function->shared()->code(); - FixedArray* raw_data = non_optimized_code->deoptimization_data(); - DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); - Address start = non_optimized_code->instruction_start(); - unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); - unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); - uint32_t pc_value = reinterpret_cast(start + pc_offset); - output_frame->SetPc(pc_value); - - FullCodeGenerator::State state = - FullCodeGenerator::StateField::decode(pc_and_state); - output_frame->SetState(Smi::FromInt(state)); - - - // Set the continuation for the topmost frame. - if (is_topmost && bailout_type_ != DEBUGGER) { - Builtins* builtins = isolate_->builtins(); - Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); - if (bailout_type_ == LAZY) { - continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); - } else if (bailout_type_ == SOFT) { - continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); - } else { - ASSERT(bailout_type_ == EAGER); - } - output_frame->SetContinuation( - reinterpret_cast(continuation->entry())); - } -} - void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { // Set the register values. The values are not important as there are no // callee saved registers in JavaScript frames, so all registers are @@ -588,6 +410,12 @@ void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { } +bool Deoptimizer::HasAlignmentPadding(JSFunction* function) { + // There is no dynamic alignment padding on MIPS in the input frame. + return false; +} + + #define __ masm()-> diff --git a/src/mips/frames-mips.cc b/src/mips/frames-mips.cc index 79505ae..540caa9 100644 --- a/src/mips/frames-mips.cc +++ b/src/mips/frames-mips.cc @@ -47,6 +47,10 @@ Address ExitFrame::ComputeStackPointer(Address fp) { } +Register JavaScriptFrame::fp_register() { return v8::internal::fp; } +Register JavaScriptFrame::context_register() { return cp; } + + Register StubFailureTrampolineFrame::fp_register() { return v8::internal::fp; } Register StubFailureTrampolineFrame::context_register() { return cp; }