From 2b7891c3034dd3b8e07ded08d6a03f338cc21346 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Wed, 6 Mar 2013 16:12:24 +0000 Subject: [PATCH] Unify deoptimizer for construct stub frames. This unifies the translation of artificial construct stub frames. The frame layout is almost the same on all architectures and only differs in the presence of a slot holding the constructor function. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/12379042 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13843 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/deoptimizer-arm.cc | 122 -------------------------------- src/arm/frames-arm.h | 16 +++++ src/deoptimizer.cc | 133 +++++++++++++++++++++++++++++++++++ src/ia32/deoptimizer-ia32.cc | 113 ----------------------------- src/ia32/frames-ia32.h | 16 +++++ src/mips/deoptimizer-mips.cc | 122 -------------------------------- src/mips/frames-mips.h | 16 +++++ src/x64/deoptimizer-x64.cc | 120 ------------------------------- src/x64/frames-x64.h | 16 +++++ 9 files changed, 197 insertions(+), 477 deletions(-) diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc index 28b0f0dfd..3753318bf 100644 --- a/src/arm/deoptimizer-arm.cc +++ b/src/arm/deoptimizer-arm.cc @@ -537,128 +537,6 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, - int frame_index) { - Builtins* builtins = isolate_->builtins(); - Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (FLAG_trace_deopt) { - PrintF(" translating construct stub => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = 8 * 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, function); - output_frame->SetFrameType(StackFrame::CONSTRUCT); - - // Construct stub 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 (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; 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::CONSTRUCT)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n", - top_address + output_offset, output_offset, value); - } - - // The output frame reflects a JSConstructStubGeneric frame. - output_offset -= kPointerSize; - value = reinterpret_cast(construct_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\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); - } - - // Constructor function being invoked by the stub. - output_offset -= kPointerSize; - value = reinterpret_cast(function); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; constructor function\n", - top_address + output_offset, output_offset, value); - } - - // The newly allocated object was passed as receiver in the artificial - // constructor stub environment created by HEnvironment::CopyForInlining(). - output_offset -= kPointerSize; - value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n", - top_address + output_offset, output_offset, value); - } - - ASSERT(0 == output_offset); - - uint32_t pc = reinterpret_cast( - construct_stub->instruction_start() + - isolate_->heap()->construct_stub_deopt_pc_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/arm/frames-arm.h b/src/arm/frames-arm.h index ee9fc0e44..30f4057fa 100644 --- a/src/arm/frames-arm.h +++ b/src/arm/frames-arm.h @@ -149,14 +149,30 @@ class JavaScriptFrameConstants : public AllStatic { class ArgumentsAdaptorFrameConstants : public AllStatic { public: + // FP-relative. static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset; + static const int kFrameSize = StandardFrameConstants::kFixedFrameSize + kPointerSize; }; +class ConstructFrameConstants : public AllStatic { + public: + // FP-relative. + static const int kImplicitReceiverOffset = -6 * kPointerSize; + static const int kConstructorOffset = -5 * kPointerSize; + static const int kLengthOffset = -4 * kPointerSize; + static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; + + static const int kFrameSize = + StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize; +}; + + class InternalFrameConstants : public AllStatic { public: + // FP-relative. static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; }; diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index c0b594554..21ffe07b6 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -922,6 +922,139 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, } +void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, + int frame_index) { + Builtins* builtins = isolate_->builtins(); + Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); + JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); + unsigned height = iterator->Next(); + unsigned height_in_bytes = height * kPointerSize; + if (trace_) { + PrintF(" translating construct stub => height=%d\n", height_in_bytes); + } + + unsigned fixed_frame_size = ConstructFrameConstants::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::CONSTRUCT); + + // Construct stub 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); + } + + // 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 + %d] <- 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::CONSTRUCT)); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; function (construct sentinel)\n", + top_address + output_offset, output_offset, value); + } + + // The output frame reflects a JSConstructStubGeneric frame. + output_offset -= kPointerSize; + value = reinterpret_cast(construct_stub); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; code object\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); + } + + // Constructor function being invoked by the stub (only present on some + // architectures, indicated by kConstructorOffset). + if (ConstructFrameConstants::kConstructorOffset != kMinInt) { + output_offset -= kPointerSize; + value = reinterpret_cast(function); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; constructor function\n", + top_address + output_offset, output_offset, value); + } + } + + // The newly allocated object was passed as receiver in the artificial + // constructor stub environment created by HEnvironment::CopyForInlining(). + output_offset -= kPointerSize; + value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); + output_frame->SetFrameSlot(output_offset, value); + if (trace_) { + PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" + V8PRIxPTR " ; allocated receiver\n", + top_address + output_offset, output_offset, value); + } + + ASSERT(0 == output_offset); + + intptr_t pc = reinterpret_cast( + construct_stub->instruction_start() + + isolate_->heap()->construct_stub_deopt_pc_offset()->value()); + output_frame->SetPc(pc); +} + + void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, int frame_index, bool is_setter_stub_frame) { diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc index 2f2430c85..667f1319c 100644 --- a/src/ia32/deoptimizer-ia32.cc +++ b/src/ia32/deoptimizer-ia32.cc @@ -643,119 +643,6 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, - int frame_index) { - Builtins* builtins = isolate_->builtins(); - Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (trace_) { - PrintF(" translating construct stub => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = 7 * 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, function); - output_frame->SetFrameType(StackFrame::CONSTRUCT); - - // Construct stub 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); - } - - // 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%08x: [top + %d] <- 0x%08x ; 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::CONSTRUCT)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n", - top_address + output_offset, output_offset, value); - } - - // The output frame reflects a JSConstructStubGeneric frame. - output_offset -= kPointerSize; - value = reinterpret_cast(construct_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\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); - } - - // The newly allocated object was passed as receiver in the artificial - // constructor stub environment created by HEnvironment::CopyForInlining(). - output_offset -= kPointerSize; - value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n", - top_address + output_offset, output_offset, value); - } - - ASSERT(0 == output_offset); - - uint32_t pc = reinterpret_cast( - construct_stub->instruction_start() + - isolate_->heap()->construct_stub_deopt_pc_offset()->value()); - output_frame->SetPc(pc); -} - - void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, int frame_index) { BailoutId node_id = BailoutId(iterator->Next()); diff --git a/src/ia32/frames-ia32.h b/src/ia32/frames-ia32.h index 5bd102a6a..c59b1664a 100644 --- a/src/ia32/frames-ia32.h +++ b/src/ia32/frames-ia32.h @@ -114,14 +114,30 @@ class JavaScriptFrameConstants : public AllStatic { class ArgumentsAdaptorFrameConstants : public AllStatic { public: + // FP-relative. static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset; + static const int kFrameSize = StandardFrameConstants::kFixedFrameSize + kPointerSize; }; +class ConstructFrameConstants : public AllStatic { + public: + // FP-relative. + static const int kImplicitReceiverOffset = -5 * kPointerSize; + static const int kConstructorOffset = kMinInt; + static const int kLengthOffset = -4 * kPointerSize; + static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; + + static const int kFrameSize = + StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize; +}; + + class InternalFrameConstants : public AllStatic { public: + // FP-relative. static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; }; diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc index 09c69c765..c315670b6 100644 --- a/src/mips/deoptimizer-mips.cc +++ b/src/mips/deoptimizer-mips.cc @@ -531,128 +531,6 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, - int frame_index) { - Builtins* builtins = isolate_->builtins(); - Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (FLAG_trace_deopt) { - PrintF(" translating construct stub => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = 8 * 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, function); - output_frame->SetFrameType(StackFrame::CONSTRUCT); - - // Construct stub 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 (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; 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::CONSTRUCT)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; function (construct sentinel)\n", - top_address + output_offset, output_offset, value); - } - - // The output frame reflects a JSConstructStubGeneric frame. - output_offset -= kPointerSize; - value = reinterpret_cast(construct_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; code object\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); - } - - // Constructor function being invoked by the stub. - output_offset -= kPointerSize; - value = reinterpret_cast(function); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; constructor function\n", - top_address + output_offset, output_offset, value); - } - - // The newly allocated object was passed as receiver in the artificial - // constructor stub environment created by HEnvironment::CopyForInlining(). - output_offset -= kPointerSize; - value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08x: [top + %d] <- 0x%08x ; allocated receiver\n", - top_address + output_offset, output_offset, value); - } - - ASSERT(0 == output_offset); - - uint32_t pc = reinterpret_cast( - construct_stub->instruction_start() + - isolate_->heap()->construct_stub_deopt_pc_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/mips/frames-mips.h b/src/mips/frames-mips.h index 188e7d15c..1568ce66e 100644 --- a/src/mips/frames-mips.h +++ b/src/mips/frames-mips.h @@ -208,14 +208,30 @@ class JavaScriptFrameConstants : public AllStatic { class ArgumentsAdaptorFrameConstants : public AllStatic { public: + // FP-relative. static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset; + static const int kFrameSize = StandardFrameConstants::kFixedFrameSize + kPointerSize; }; +class ConstructFrameConstants : public AllStatic { + public: + // FP-relative. + static const int kImplicitReceiverOffset = -6 * kPointerSize; + static const int kConstructorOffset = -5 * kPointerSize; + static const int kLengthOffset = -4 * kPointerSize; + static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; + + static const int kFrameSize = + StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize; +}; + + class InternalFrameConstants : public AllStatic { public: + // FP-relative. static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; }; diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc index 8e776f9bf..5aa46f379 100644 --- a/src/x64/deoptimizer-x64.cc +++ b/src/x64/deoptimizer-x64.cc @@ -535,126 +535,6 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, } -void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, - int frame_index) { - Builtins* builtins = isolate_->builtins(); - Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); - JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); - unsigned height = iterator->Next(); - unsigned height_in_bytes = height * kPointerSize; - if (trace_) { - PrintF(" translating construct stub => height=%d\n", height_in_bytes); - } - - unsigned fixed_frame_size = 7 * 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, function); - output_frame->SetFrameType(StackFrame::CONSTRUCT); - - // Construct stub 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); - } - - // 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 + %d] <- 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::CONSTRUCT)); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; function (construct sentinel)\n", - top_address + output_offset, output_offset, value); - } - - // The output frame reflects a JSConstructStubGeneric frame. - output_offset -= kPointerSize; - value = reinterpret_cast(construct_stub); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; code object\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); - } - - // The newly allocated object was passed as receiver in the artificial - // constructor stub environment created by HEnvironment::CopyForInlining(). - output_offset -= kPointerSize; - value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); - output_frame->SetFrameSlot(output_offset, value); - if (trace_) { - PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" - V8PRIxPTR " ; allocated receiver\n", - top_address + output_offset, output_offset, value); - } - - ASSERT(0 == output_offset); - - intptr_t pc = reinterpret_cast( - construct_stub->instruction_start() + - isolate_->heap()->construct_stub_deopt_pc_offset()->value()); - output_frame->SetPc(pc); -} - - void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, int frame_index) { BailoutId node_id = BailoutId(iterator->Next()); diff --git a/src/x64/frames-x64.h b/src/x64/frames-x64.h index c9092afa3..53c345906 100644 --- a/src/x64/frames-x64.h +++ b/src/x64/frames-x64.h @@ -100,14 +100,30 @@ class JavaScriptFrameConstants : public AllStatic { class ArgumentsAdaptorFrameConstants : public AllStatic { public: + // FP-relative. static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset; + static const int kFrameSize = StandardFrameConstants::kFixedFrameSize + kPointerSize; }; +class ConstructFrameConstants : public AllStatic { + public: + // FP-relative. + static const int kImplicitReceiverOffset = -5 * kPointerSize; + static const int kConstructorOffset = kMinInt; + static const int kLengthOffset = -4 * kPointerSize; + static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; + + static const int kFrameSize = + StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize; +}; + + class InternalFrameConstants : public AllStatic { public: + // FP-relative. static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; }; -- 2.34.1