Index: src/frames.cc |
diff --git a/src/frames.cc b/src/frames.cc |
index 9591011f3d0ee6b18816c1e6ee53fb221346cc09..644a0b3ec7391a6d5e7658b98e8bbec885eb1c8f 100644 |
--- a/src/frames.cc |
+++ b/src/frames.cc |
@@ -884,93 +884,56 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames) { |
return JavaScriptFrame::Summarize(frames); |
} |
- int deopt_index = Safepoint::kNoDeoptimizationIndex; |
- DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); |
- FixedArray* literal_array = data->LiteralArray(); |
- |
- // BUG(3243555): Since we don't have a lazy-deopt registered at |
- // throw-statements, we can't use the translation at the call-site of |
- // throw. An entry with no deoptimization index indicates a call-site |
- // without a lazy-deopt. As a consequence we are not allowed to inline |
- // functions containing throw. |
- DCHECK(deopt_index != Safepoint::kNoDeoptimizationIndex); |
- |
- TranslationIterator it(data->TranslationByteArray(), |
- data->TranslationIndex(deopt_index)->value()); |
- Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
- DCHECK(opcode == Translation::BEGIN); |
- it.Next(); // Drop frame count. |
- int jsframe_count = it.Next(); |
- |
// We create the summary in reverse order because the frames |
// in the deoptimization translation are ordered bottom-to-top. |
+ TranslatedState state(this); |
Jarin
2015/06/09 12:32:53
I am wondering whether we should put this in no-al
|
bool is_constructor = IsConstructor(); |
- int i = jsframe_count; |
- while (i > 0) { |
- opcode = static_cast<Translation::Opcode>(it.Next()); |
- if (opcode == Translation::JS_FRAME) { |
- i--; |
- BailoutId ast_id = BailoutId(it.Next()); |
- JSFunction* function = LiteralAt(literal_array, it.Next()); |
- it.Next(); // Skip height. |
- |
- // The translation commands are ordered and the receiver is always |
- // at the first position. |
- // If we are at a call, the receiver is always in a stack slot. |
- // Otherwise we are not guaranteed to get the receiver value. |
- opcode = static_cast<Translation::Opcode>(it.Next()); |
- int index = it.Next(); |
- |
- // Get the correct receiver in the optimized frame. |
- Object* receiver = NULL; |
- if (opcode == Translation::LITERAL) { |
- receiver = data->LiteralArray()->get(index); |
- } else if (opcode == Translation::STACK_SLOT) { |
- // Positive index means the value is spilled to the locals |
- // area. Negative means it is stored in the incoming parameter |
- // area. |
- if (index >= 0) { |
- receiver = GetExpression(index); |
- } else { |
- // Index -1 overlaps with last parameter, -n with the first parameter, |
- // (-n - 1) with the receiver with n being the number of parameters |
- // of the outermost, optimized frame. |
- int parameter_count = ComputeParametersCount(); |
- int parameter_index = index + parameter_count; |
- receiver = (parameter_index == -1) |
- ? this->receiver() |
- : this->GetParameter(parameter_index); |
+ for (TranslatedFrame const& frame : state) { |
+ switch (frame.kind()) { |
+ case TranslatedFrame::kFunction: { |
+ BailoutId const ast_id = frame.node_id(); |
+ JSFunction* const function = frame.raw_function(); |
+ |
+ // Get the correct receiver in the optimized frame. |
+ Object* receiver = frame.front().GetRawValue(); |
+ if (receiver == isolate()->heap()->arguments_marker()) { |
+ // TODO(jarin): Materializing a captured object (or duplicated |
+ // object) is hard, we return undefined for now. This breaks the |
+ // produced stack trace, as constructor frames aren't marked as |
+ // such anymore. |
+ receiver = isolate()->heap()->undefined_value(); |
} |
- } else { |
- // The receiver is not in a stack slot nor in a literal. We give up. |
- // TODO(3029): Materializing a captured object (or duplicated |
- // object) is hard, we return undefined for now. This breaks the |
- // produced stack trace, as constructor frames aren't marked as |
- // such anymore. |
- receiver = isolate()->heap()->undefined_value(); |
+ |
+ Code* code = function->shared()->code(); |
+ DeoptimizationOutputData* output_data = |
+ DeoptimizationOutputData::cast(code->deoptimization_data()); |
+ unsigned entry = |
+ Deoptimizer::GetOutputInfo(output_data, ast_id, function->shared()); |
+ unsigned pc_offset = |
+ FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; |
+ DCHECK(pc_offset > 0); |
+ |
+ FrameSummary summary(receiver, function, code, pc_offset, |
+ is_constructor); |
+ frames->Add(summary); |
+ is_constructor = false; |
+ break; |
} |
- Code* code = function->shared()->code(); |
- DeoptimizationOutputData* output_data = |
- DeoptimizationOutputData::cast(code->deoptimization_data()); |
- unsigned entry = Deoptimizer::GetOutputInfo(output_data, |
- ast_id, |
- function->shared()); |
- unsigned pc_offset = |
- FullCodeGenerator::PcField::decode(entry) + Code::kHeaderSize; |
- DCHECK(pc_offset > 0); |
- |
- FrameSummary summary(receiver, function, code, pc_offset, is_constructor); |
- frames->Add(summary); |
- is_constructor = false; |
- } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) { |
- // The next encountered JS_FRAME will be marked as a constructor call. |
- it.Skip(Translation::NumberOfOperandsFor(opcode)); |
- DCHECK(!is_constructor); |
- is_constructor = true; |
- } else { |
- // Skip over operands to advance to the next opcode. |
- it.Skip(Translation::NumberOfOperandsFor(opcode)); |
+ case TranslatedFrame::kConstructStub: { |
+ // The next encountered JS_FRAME will be marked as a constructor call. |
+ DCHECK(!is_constructor); |
+ is_constructor = true; |
+ break; |
+ } |
+ |
+ case TranslatedFrame::kInvalid: |
+ UNREACHABLE(); |
+ case TranslatedFrame::kArgumentsAdaptor: |
+ case TranslatedFrame::kCompiledStub: |
+ case TranslatedFrame::kGetter: |
+ case TranslatedFrame::kSetter: |
+ break; |
} |
} |
DCHECK(!is_constructor); |
@@ -1024,30 +987,10 @@ void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) { |
return JavaScriptFrame::GetFunctions(functions); |
} |
- int deopt_index = Safepoint::kNoDeoptimizationIndex; |
- DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index); |
- FixedArray* literal_array = data->LiteralArray(); |
- |
- TranslationIterator it(data->TranslationByteArray(), |
- data->TranslationIndex(deopt_index)->value()); |
- Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); |
- DCHECK(opcode == Translation::BEGIN); |
- it.Next(); // Drop frame count. |
- int jsframe_count = it.Next(); |
- |
- // We insert the frames in reverse order because the frames |
- // in the deoptimization translation are ordered bottom-to-top. |
- while (jsframe_count > 0) { |
- opcode = static_cast<Translation::Opcode>(it.Next()); |
- if (opcode == Translation::JS_FRAME) { |
- jsframe_count--; |
- it.Next(); // Skip ast id. |
- JSFunction* function = LiteralAt(literal_array, it.Next()); |
- it.Next(); // Skip height. |
- functions->Add(function); |
- } else { |
- // Skip over operands to advance to the next opcode. |
- it.Skip(Translation::NumberOfOperandsFor(opcode)); |
+ TranslatedState state(this); |
+ for (TranslatedFrame const& frame : state) { |
+ if (frame.kind() == TranslatedFrame::kFunction) { |
+ functions->Add(frame.raw_function()); |
} |
} |
} |