From 05f1be1bb3b1fae759c381ad19c5c6ca39d36b55 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Fri, 1 Mar 2013 12:23:24 +0000 Subject: [PATCH] Unify deoptimizer for accessor and arguments frames. This unifies the translation of artificial accessor stub and arguments adaptor frames. The frame layout is the same on all architectures and the computation code can be shared. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/12374044 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13784 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/deoptimizer-arm.cc | 214 ---------------------------------- src/deoptimizer.cc | 220 +++++++++++++++++++++++++++++++++++ src/ia32/deoptimizer-ia32.cc | 215 ---------------------------------- src/mips/deoptimizer-mips.cc | 214 ---------------------------------- src/x64/deoptimizer-x64.cc | 220 ----------------------------------- 5 files changed, 220 insertions(+), 863 deletions(-) diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc index 6c49dcafaa..2e1e3e3e6e 100644 --- a/src/arm/deoptimizer-arm.cc +++ b/src/arm/deoptimizer-arm.cc @@ -356,102 +356,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() { } -void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, - int frame_index) { - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (FLAG_trace_deopt) { - PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; - 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::ARGUMENTS_ADAPTOR); - - // Arguments adaptor can not be topmost or bottommost. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous - // frame's top and this frame's size. - uint32_t top_address; - top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - // Compute the incoming parameter translation. - int parameter_count = height; - unsigned output_offset = output_frame_size; - for (int i = 0; i < parameter_count; ++i) { - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t callers_pc = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, callers_pc); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", - top_address + output_offset, output_offset, callers_pc); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", - fp_value, output_offset, value); - } - - // A marker value is used in place of the context. - output_offset -= kPointerSize; - intptr_t context = reinterpret_cast( - Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); - output_frame->SetFrameSlot(output_offset, context); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", - top_address + output_offset, output_offset, context); - } - - // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. - output_offset -= kPointerSize; - value = reinterpret_cast(function); - output_frame->SetFrameSlot(output_offset, value); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", - top_address + output_offset, output_offset, value); - } - - // Number of incoming arguments. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(height - 1)); - output_frame->SetFrameSlot(output_offset, value); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", - top_address + output_offset, output_offset, value, height - 1); - } - - ASSERT(0 == output_offset); - - Builtins* builtins = isolate_->builtins(); - Code* adaptor_trampoline = - builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); - uint32_t pc = reinterpret_cast( - adaptor_trampoline->instruction_start() + - isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); - output_frame->SetPc(pc); -} - - void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, int frame_index) { // @@ -755,124 +659,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, - int frame_index, - bool is_setter_stub_frame) { - JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); - // The receiver (and the implicit return value, if any) are expected in - // registers by the LoadIC/StoreIC, so they don't belong to the output stack - // frame. This means that we have to use a height of 0. - unsigned height = 0; - unsigned height_in_bytes = height * kPointerSize; - const char* kind = is_setter_stub_frame ? "setter" : "getter"; - if (trace_) { - PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); - } - - // We need 5 stack entries from StackFrame::INTERNAL (lr, fp, cp, frame type, - // code object, see MacroAssembler::EnterFrame). For a setter stub frames we - // need one additional entry for the implicit return value, see - // StoreStubCompiler::CompileStoreViaSetter. - unsigned fixed_frame_entries = 5 + (is_setter_stub_frame ? 1 : 0); - unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; - 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, accessor); - output_frame->SetFrameType(StackFrame::INTERNAL); - - // A frame for an accessor stub can not be the topmost or bottommost one. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous frame's top and - // this frame's size. - uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - unsigned output_offset = output_frame_size; - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t callers_pc = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, callers_pc); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's pc\n", - top_address + output_offset, output_offset, callers_pc); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's fp\n", - fp_value, output_offset, value); - } - - // The context can be gotten from the previous frame. - output_offset -= kPointerSize; - value = output_[frame_index - 1]->GetContext(); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; context\n", - top_address + output_offset, output_offset, value); - } - - // A marker value is used in place of the function. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(StackFrame::INTERNAL)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; function (%s sentinel)\n", - top_address + output_offset, output_offset, value, kind); - } - - // Get Code object from accessor stub. - output_offset -= kPointerSize; - Builtins::Name name = is_setter_stub_frame ? - Builtins::kStoreIC_Setter_ForDeopt : - Builtins::kLoadIC_Getter_ForDeopt; - Code* accessor_stub = isolate_->builtins()->builtin(name); - value = reinterpret_cast(accessor_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; code object\n", - top_address + output_offset, output_offset, value); - } - - // Skip receiver. - Translation::Opcode opcode = - static_cast(iterator->Next()); - iterator->Skip(Translation::NumberOfOperandsFor(opcode)); - - if (is_setter_stub_frame) { - // The implicit return value was part of the artificial setter stub - // environment. - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - ASSERT(0 == output_offset); - - Smi* offset = is_setter_stub_frame ? - isolate_->heap()->setter_stub_deopt_pc_offset() : - isolate_->heap()->getter_stub_deopt_pc_offset(); - intptr_t pc = reinterpret_cast( - accessor_stub->instruction_start() + offset->value()); - output_frame->SetPc(pc); -} - - // This code is very similar to ia32 code, but relies on register names (fp, sp) // and how the frame is laid out. void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index 7267b0527e..c0b5945540 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -821,6 +821,226 @@ void Deoptimizer::DoComputeOutputFrames() { } +void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, + int frame_index) { + JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); + unsigned height = iterator->Next(); + unsigned height_in_bytes = height * kPointerSize; + if (trace_) { + PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); + } + + unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; + 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::ARGUMENTS_ADAPTOR); + + // Arguments adaptor can not be topmost or bottommost. + ASSERT(frame_index > 0 && frame_index < output_count_ - 1); + ASSERT(output_[frame_index] == NULL); + output_[frame_index] = output_frame; + + // The top address of the frame is computed from the previous + // frame's top and this frame's size. + intptr_t top_address; + top_address = output_[frame_index - 1]->GetTop() - output_frame_size; + output_frame->SetTop(top_address); + + // Compute the incoming parameter translation. + int parameter_count = height; + unsigned output_offset = output_frame_size; + for (int i = 0; i < parameter_count; ++i) { + output_offset -= kPointerSize; + DoTranslateCommand(iterator, frame_index, output_offset); + } + + // Read caller's PC from the previous frame. + output_offset -= kPointerSize; + intptr_t callers_pc = output_[frame_index - 1]->GetPc(); + output_frame->SetFrameSlot(output_offset, callers_pc); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; caller's pc\n", + top_address + output_offset, output_offset, callers_pc); + } + + // Read caller's FP from the previous frame, and set this frame's FP. + output_offset -= kPointerSize; + intptr_t value = output_[frame_index - 1]->GetFp(); + output_frame->SetFrameSlot(output_offset, value); + intptr_t fp_value = top_address + output_offset; + output_frame->SetFp(fp_value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; caller's fp\n", + fp_value, output_offset, value); + } + + // A marker value is used in place of the context. + output_offset -= kPointerSize; + intptr_t context = reinterpret_cast( + Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); + output_frame->SetFrameSlot(output_offset, context); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; context (adaptor sentinel)\n", + top_address + output_offset, output_offset, context); + } + + // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. + output_offset -= kPointerSize; + value = reinterpret_cast(function); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; function\n", + top_address + output_offset, output_offset, value); + } + + // Number of incoming arguments. + output_offset -= kPointerSize; + value = reinterpret_cast(Smi::FromInt(height - 1)); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; argc (%d)\n", + top_address + output_offset, output_offset, value, height - 1); + } + + ASSERT(0 == output_offset); + + Builtins* builtins = isolate_->builtins(); + Code* adaptor_trampoline = + builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); + intptr_t pc_value = reinterpret_cast( + adaptor_trampoline->instruction_start() + + isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); + output_frame->SetPc(pc_value); +} + + +void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, + int frame_index, + bool is_setter_stub_frame) { + JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); + // The receiver (and the implicit return value, if any) are expected in + // registers by the LoadIC/StoreIC, so they don't belong to the output stack + // frame. This means that we have to use a height of 0. + unsigned height = 0; + unsigned height_in_bytes = height * kPointerSize; + const char* kind = is_setter_stub_frame ? "setter" : "getter"; + if (trace_) { + PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); + } + + // We need 1 stack entry for the return address + 4 stack entries from + // StackFrame::INTERNAL (FP, context, frame type, code object, see + // MacroAssembler::EnterFrame). For a setter stub frame we need one additional + // entry for the implicit return value, see + // StoreStubCompiler::CompileStoreViaSetter. + unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0); + unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; + 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, accessor); + output_frame->SetFrameType(StackFrame::INTERNAL); + + // A frame for an accessor stub can not be the topmost or bottommost one. + ASSERT(frame_index > 0 && frame_index < output_count_ - 1); + ASSERT(output_[frame_index] == NULL); + output_[frame_index] = output_frame; + + // The top address of the frame is computed from the previous frame's top and + // this frame's size. + intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; + output_frame->SetTop(top_address); + + unsigned output_offset = output_frame_size; + + // Read caller's PC from the previous frame. + output_offset -= kPointerSize; + intptr_t callers_pc = output_[frame_index - 1]->GetPc(); + output_frame->SetFrameSlot(output_offset, callers_pc); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR + " ; caller's pc\n", + top_address + output_offset, output_offset, callers_pc); + } + + // Read caller's FP from the previous frame, and set this frame's FP. + output_offset -= kPointerSize; + intptr_t value = output_[frame_index - 1]->GetFp(); + output_frame->SetFrameSlot(output_offset, value); + intptr_t fp_value = top_address + output_offset; + output_frame->SetFp(fp_value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR + " ; caller's fp\n", + fp_value, output_offset, value); + } + + // The context can be gotten from the previous frame. + output_offset -= kPointerSize; + value = output_[frame_index - 1]->GetContext(); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR + " ; context\n", + top_address + output_offset, output_offset, value); + } + + // A marker value is used in place of the function. + output_offset -= kPointerSize; + value = reinterpret_cast(Smi::FromInt(StackFrame::INTERNAL)); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR + " ; function (%s sentinel)\n", + top_address + output_offset, output_offset, value, kind); + } + + // Get Code object from accessor stub. + output_offset -= kPointerSize; + Builtins::Name name = is_setter_stub_frame ? + Builtins::kStoreIC_Setter_ForDeopt : + Builtins::kLoadIC_Getter_ForDeopt; + Code* accessor_stub = isolate_->builtins()->builtin(name); + value = reinterpret_cast(accessor_stub); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR + " ; code object\n", + top_address + output_offset, output_offset, value); + } + + // Skip receiver. + Translation::Opcode opcode = + static_cast(iterator->Next()); + iterator->Skip(Translation::NumberOfOperandsFor(opcode)); + + if (is_setter_stub_frame) { + // The implicit return value was part of the artificial setter stub + // environment. + output_offset -= kPointerSize; + DoTranslateCommand(iterator, frame_index, output_offset); + } + + ASSERT(0 == output_offset); + + Smi* offset = is_setter_stub_frame ? + isolate_->heap()->setter_stub_deopt_pc_offset() : + isolate_->heap()->getter_stub_deopt_pc_offset(); + intptr_t pc = reinterpret_cast( + accessor_stub->instruction_start() + offset->value()); + output_frame->SetPc(pc); +} + + void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { ASSERT_NE(DEBUGGER, bailout_type_); diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc index c062fd7032..e27ea4cdcd 100644 --- a/src/ia32/deoptimizer-ia32.cc +++ b/src/ia32/deoptimizer-ia32.cc @@ -463,102 +463,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() { } -void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, - int frame_index) { - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (trace_) { - PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; - 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::ARGUMENTS_ADAPTOR); - - // Arguments adaptor can not be topmost or bottommost. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous - // frame's top and this frame's size. - uint32_t top_address; - top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - // Compute the incoming parameter translation. - int parameter_count = height; - unsigned output_offset = output_frame_size; - for (int i = 0; i < parameter_count; ++i) { - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t callers_pc = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, callers_pc); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", - top_address + output_offset, output_offset, callers_pc); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", - fp_value, output_offset, value); - } - - // A marker value is used in place of the context. - output_offset -= kPointerSize; - intptr_t context = reinterpret_cast( - Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); - output_frame->SetFrameSlot(output_offset, context); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", - top_address + output_offset, output_offset, context); - } - - // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. - output_offset -= kPointerSize; - value = reinterpret_cast(function); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", - top_address + output_offset, output_offset, value); - } - - // Number of incoming arguments. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(height - 1)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", - top_address + output_offset, output_offset, value, height - 1); - } - - ASSERT(0 == output_offset); - - Builtins* builtins = isolate_->builtins(); - Code* adaptor_trampoline = - builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); - uint32_t pc = reinterpret_cast( - adaptor_trampoline->instruction_start() + - isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); - output_frame->SetPc(pc); -} - - void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, int frame_index) { // @@ -852,125 +756,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, - int frame_index, - bool is_setter_stub_frame) { - JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); - // The receiver (and the implicit return value, if any) are expected in - // registers by the LoadIC/StoreIC, so they don't belong to the output stack - // frame. This means that we have to use a height of 0. - unsigned height = 0; - unsigned height_in_bytes = height * kPointerSize; - const char* kind = is_setter_stub_frame ? "setter" : "getter"; - if (trace_) { - PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); - } - - // We need 1 stack entry for the return address + 4 stack entries from - // StackFrame::INTERNAL (FP, context, frame type, code object, see - // MacroAssembler::EnterFrame). For a setter stub frame we need one additional - // entry for the implicit return value, see - // StoreStubCompiler::CompileStoreViaSetter. - unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0); - unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; - 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, accessor); - output_frame->SetFrameType(StackFrame::INTERNAL); - - // A frame for an accessor stub can not be the topmost or bottommost one. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous frame's top and - // this frame's size. - intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - unsigned output_offset = output_frame_size; - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t callers_pc = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, callers_pc); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's pc\n", - top_address + output_offset, output_offset, callers_pc); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's fp\n", - fp_value, output_offset, value); - } - - // The context can be gotten from the previous frame. - output_offset -= kPointerSize; - value = output_[frame_index - 1]->GetContext(); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; context\n", - top_address + output_offset, output_offset, value); - } - - // A marker value is used in place of the function. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(StackFrame::INTERNAL)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; function (%s sentinel)\n", - top_address + output_offset, output_offset, value, kind); - } - - // Get Code object from accessor stub. - output_offset -= kPointerSize; - Builtins::Name name = is_setter_stub_frame ? - Builtins::kStoreIC_Setter_ForDeopt : - Builtins::kLoadIC_Getter_ForDeopt; - Code* accessor_stub = isolate_->builtins()->builtin(name); - value = reinterpret_cast(accessor_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; code object\n", - top_address + output_offset, output_offset, value); - } - - // Skip receiver. - Translation::Opcode opcode = - static_cast(iterator->Next()); - iterator->Skip(Translation::NumberOfOperandsFor(opcode)); - - if (is_setter_stub_frame) { - // The implicit return value was part of the artificial setter stub - // environment. - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - ASSERT(0 == output_offset); - - Smi* offset = is_setter_stub_frame ? - isolate_->heap()->setter_stub_deopt_pc_offset() : - isolate_->heap()->getter_stub_deopt_pc_offset(); - intptr_t pc = reinterpret_cast( - accessor_stub->instruction_start() + offset->value()); - output_frame->SetPc(pc); -} - - void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, int frame_index) { BailoutId node_id = BailoutId(iterator->Next()); diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc index 00c7ece75f..4ea75676ae 100644 --- a/src/mips/deoptimizer-mips.cc +++ b/src/mips/deoptimizer-mips.cc @@ -349,102 +349,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() { } -void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, - int frame_index) { - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (FLAG_trace_deopt) { - PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; - 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::ARGUMENTS_ADAPTOR); - - // Arguments adaptor can not be topmost or bottommost. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous - // frame's top and this frame's size. - uint32_t top_address; - top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - // Compute the incoming parameter translation. - int parameter_count = height; - unsigned output_offset = output_frame_size; - for (int i = 0; i < parameter_count; ++i) { - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t callers_pc = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, callers_pc); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's pc\n", - top_address + output_offset, output_offset, callers_pc); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; caller's fp\n", - fp_value, output_offset, value); - } - - // A marker value is used in place of the context. - output_offset -= kPointerSize; - intptr_t context = reinterpret_cast( - Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); - output_frame->SetFrameSlot(output_offset, context); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; context (adaptor sentinel)\n", - top_address + output_offset, output_offset, context); - } - - // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. - output_offset -= kPointerSize; - value = reinterpret_cast(function); - output_frame->SetFrameSlot(output_offset, value); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function\n", - top_address + output_offset, output_offset, value); - } - - // Number of incoming arguments. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(height - 1)); - output_frame->SetFrameSlot(output_offset, value); - if (FLAG_trace_deopt) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; argc (%d)\n", - top_address + output_offset, output_offset, value, height - 1); - } - - ASSERT(0 == output_offset); - - Builtins* builtins = isolate_->builtins(); - Code* adaptor_trampoline = - builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); - uint32_t pc = reinterpret_cast( - adaptor_trampoline->instruction_start() + - isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); - output_frame->SetPc(pc); -} - - void Deoptimizer::DoCompiledStubFrame(TranslationIterator* iterator, int frame_index) { // @@ -706,124 +610,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, - int frame_index, - bool is_setter_stub_frame) { - JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); - // The receiver (and the implicit return value, if any) are expected in - // registers by the LoadIC/StoreIC, so they don't belong to the output stack - // frame. This means that we have to use a height of 0. - unsigned height = 0; - unsigned height_in_bytes = height * kPointerSize; - const char* kind = is_setter_stub_frame ? "setter" : "getter"; - if (trace_) { - PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); - } - - // We need 5 stack entries from StackFrame::INTERNAL (ra, fp, cp, frame type, - // code object, see MacroAssembler::EnterFrame). For a setter stub frame we - // need one additional entry for the implicit return value, see - // StoreStubCompiler::CompileStoreViaSetter. - unsigned fixed_frame_entries = 5 + (is_setter_stub_frame ? 1 : 0); - unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; - 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, accessor); - output_frame->SetFrameType(StackFrame::INTERNAL); - - // A frame for an accessor stub can not be the topmost or bottommost one. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous frame's top and - // this frame's size. - uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - unsigned output_offset = output_frame_size; - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's pc\n", - top_address + output_offset, output_offset, value); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's fp\n", - fp_value, output_offset, value); - } - - // The context can be gotten from the previous frame. - output_offset -= kPointerSize; - value = output_[frame_index - 1]->GetContext(); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; context\n", - top_address + output_offset, output_offset, value); - } - - // A marker value is used in place of the function. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(StackFrame::INTERNAL)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; function (%s sentinel)\n", - top_address + output_offset, output_offset, value, kind); - } - - // Get Code object from accessor stub. - output_offset -= kPointerSize; - Builtins::Name name = is_setter_stub_frame ? - Builtins::kStoreIC_Setter_ForDeopt : - Builtins::kLoadIC_Getter_ForDeopt; - Code* accessor_stub = isolate_->builtins()->builtin(name); - value = reinterpret_cast(accessor_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; code object\n", - top_address + output_offset, output_offset, value); - } - - // Skip receiver. - Translation::Opcode opcode = - static_cast(iterator->Next()); - iterator->Skip(Translation::NumberOfOperandsFor(opcode)); - - if (is_setter_stub_frame) { - // The implicit return value was part of the artificial setter stub - // environment. - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - ASSERT(0 == output_offset); - - Smi* offset = is_setter_stub_frame ? - isolate_->heap()->setter_stub_deopt_pc_offset() : - isolate_->heap()->getter_stub_deopt_pc_offset(); - intptr_t pc = reinterpret_cast( - accessor_stub->instruction_start() + offset->value()); - output_frame->SetPc(pc); -} - - // 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, diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc index 09973cb4fd..8e776f9bfb 100644 --- a/src/x64/deoptimizer-x64.cc +++ b/src/x64/deoptimizer-x64.cc @@ -348,107 +348,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() { } -void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, - int frame_index) { - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (trace_) { - PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; - 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::ARGUMENTS_ADAPTOR); - - // Arguments adaptor can not be topmost or bottommost. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous - // frame's top and this frame's size. - intptr_t top_address; - top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - // Compute the incoming parameter translation. - int parameter_count = height; - unsigned output_offset = output_frame_size; - for (int i = 0; i < parameter_count; ++i) { - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t callers_pc = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, callers_pc); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; caller's pc\n", - top_address + output_offset, output_offset, callers_pc); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; caller's fp\n", - fp_value, output_offset, value); - } - - // A marker value is used in place of the context. - output_offset -= kPointerSize; - intptr_t context = reinterpret_cast( - Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); - output_frame->SetFrameSlot(output_offset, context); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; context (adaptor sentinel)\n", - top_address + output_offset, output_offset, context); - } - - // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. - output_offset -= kPointerSize; - value = reinterpret_cast(function); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; function\n", - top_address + output_offset, output_offset, value); - } - - // Number of incoming arguments. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(height - 1)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; argc (%d)\n", - top_address + output_offset, output_offset, value, height - 1); - } - - ASSERT(0 == output_offset); - - Builtins* builtins = isolate_->builtins(); - Code* adaptor_trampoline = - builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); - intptr_t pc_value = reinterpret_cast( - adaptor_trampoline->instruction_start() + - isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); - output_frame->SetPc(pc_value); -} - - void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, int frame_index) { // @@ -756,125 +655,6 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, - int frame_index, - bool is_setter_stub_frame) { - JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); - // The receiver (and the implicit return value, if any) are expected in - // registers by the LoadIC/StoreIC, so they don't belong to the output stack - // frame. This means that we have to use a height of 0. - unsigned height = 0; - unsigned height_in_bytes = height * kPointerSize; - const char* kind = is_setter_stub_frame ? "setter" : "getter"; - if (trace_) { - PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); - } - - // We need 1 stack entry for the return address + 4 stack entries from - // StackFrame::INTERNAL (FP, context, frame type, code object, see - // MacroAssembler::EnterFrame). For a setter stub frame we need one additional - // entry for the implicit return value, see - // StoreStubCompiler::CompileStoreViaSetter. - unsigned fixed_frame_entries = 1 + 4 + (is_setter_stub_frame ? 1 : 0); - unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; - 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, accessor); - output_frame->SetFrameType(StackFrame::INTERNAL); - - // A frame for an accessor stub can not be the topmost or bottommost one. - ASSERT(frame_index > 0 && frame_index < output_count_ - 1); - ASSERT(output_[frame_index] == NULL); - output_[frame_index] = output_frame; - - // The top address of the frame is computed from the previous frame's top and - // this frame's size. - intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; - output_frame->SetTop(top_address); - - unsigned output_offset = output_frame_size; - - // Read caller's PC from the previous frame. - output_offset -= kPointerSize; - intptr_t callers_pc = output_[frame_index - 1]->GetPc(); - output_frame->SetFrameSlot(output_offset, callers_pc); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's pc\n", - top_address + output_offset, output_offset, callers_pc); - } - - // Read caller's FP from the previous frame, and set this frame's FP. - output_offset -= kPointerSize; - intptr_t value = output_[frame_index - 1]->GetFp(); - output_frame->SetFrameSlot(output_offset, value); - intptr_t fp_value = top_address + output_offset; - output_frame->SetFp(fp_value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; caller's fp\n", - fp_value, output_offset, value); - } - - // The context can be gotten from the previous frame. - output_offset -= kPointerSize; - value = output_[frame_index - 1]->GetContext(); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; context\n", - top_address + output_offset, output_offset, value); - } - - // A marker value is used in place of the function. - output_offset -= kPointerSize; - value = reinterpret_cast(Smi::FromInt(StackFrame::INTERNAL)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; function (%s sentinel)\n", - top_address + output_offset, output_offset, value, kind); - } - - // Get Code object from accessor stub. - output_offset -= kPointerSize; - Builtins::Name name = is_setter_stub_frame ? - Builtins::kStoreIC_Setter_ForDeopt : - Builtins::kLoadIC_Getter_ForDeopt; - Code* accessor_stub = isolate_->builtins()->builtin(name); - value = reinterpret_cast(accessor_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR - " ; code object\n", - top_address + output_offset, output_offset, value); - } - - // Skip receiver. - Translation::Opcode opcode = - static_cast(iterator->Next()); - iterator->Skip(Translation::NumberOfOperandsFor(opcode)); - - if (is_setter_stub_frame) { - // The implicit return value was part of the artificial setter stub - // environment. - output_offset -= kPointerSize; - DoTranslateCommand(iterator, frame_index, output_offset); - } - - ASSERT(0 == output_offset); - - Smi* offset = is_setter_stub_frame ? - isolate_->heap()->setter_stub_deopt_pc_offset() : - isolate_->heap()->getter_stub_deopt_pc_offset(); - intptr_t pc = reinterpret_cast( - accessor_stub->instruction_start() + offset->value()); - output_frame->SetPc(pc); -} - - void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, int frame_index) { BailoutId node_id = BailoutId(iterator->Next());