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

Unified Diff: src/deoptimizer.cc

Issue 2692753004: [turbofan] escape analysis supports arguments object and rest elements (Closed)
Patch Set: handle the case where Deoptimizer::function_ is a Smi Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/deoptimizer.h ('k') | src/interface-descriptors.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/deoptimizer.cc
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 8dfe0e181c6b292bede5e1a7d8331d2ca57ac27f..89a06c2d353f95ddeacd527ce297d18e7a120884 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -511,7 +511,7 @@ Code* Deoptimizer::FindOptimizedCode(JSFunction* function) {
void Deoptimizer::PrintFunctionName() {
- if (function_ != nullptr && function_->IsJSFunction()) {
+ if (function_->IsHeapObject() && function_->IsJSFunction()) {
function_->ShortPrint(trace_scope_->file());
} else {
PrintF(trace_scope_->file(),
@@ -708,7 +708,10 @@ void Deoptimizer::DoComputeOutputFrames() {
translated_state_.Init(
input_->GetFramePointerAddress(), &state_iterator,
input_data->LiteralArray(), input_->GetRegisterValues(),
- trace_scope_ == nullptr ? nullptr : trace_scope_->file());
+ trace_scope_ == nullptr ? nullptr : trace_scope_->file(),
+ function_->IsHeapObject()
+ ? function_->shared()->internal_formal_parameter_count()
+ : 0);
// Do the input frame to output frame(s) translation.
size_t count = translated_state_.frames().size();
@@ -2399,6 +2402,10 @@ void Translation::BeginArgumentsObject(int args_length) {
buffer_->Add(args_length);
}
+void Translation::ArgumentsElements(bool is_rest) {
+ buffer_->Add(ARGUMENTS_ELEMENTS);
+ buffer_->Add(is_rest);
+}
void Translation::BeginCapturedObject(int length) {
buffer_->Add(CAPTURED_OBJECT);
@@ -2532,6 +2539,8 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
case INTERPRETED_FRAME:
case CONSTRUCT_STUB_FRAME:
return 3;
+ case ARGUMENTS_ELEMENTS:
+ return 1;
}
FATAL("Unexpected translation type");
return -1;
@@ -2790,7 +2799,6 @@ TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container,
return slot;
}
-
// static
TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container,
int length,
@@ -3300,6 +3308,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
case Translation::BEGIN:
case Translation::DUPLICATED_OBJECT:
case Translation::ARGUMENTS_OBJECT:
+ case Translation::ARGUMENTS_ELEMENTS:
case Translation::CAPTURED_OBJECT:
case Translation::REGISTER:
case Translation::INT32_REGISTER:
@@ -3335,16 +3344,74 @@ void TranslatedFrame::AdvanceIterator(
}
}
+// Creates translated values for an arguments backing store, or the backing
+// store for the rest parameters if {is_rest} is true. The TranslatedValue
+// objects for the fields are not read from the TranslationIterator, but instead
+// created on-the-fly based on dynamic information in the optimized frame.
+void TranslatedState::CreateArgumentsElementsTranslatedValues(
+ int frame_index, Address input_frame_pointer, bool is_rest) {
+ TranslatedFrame& frame = frames_[frame_index];
+
+ Address parent_frame_pointer = *reinterpret_cast<Address*>(
+ input_frame_pointer + StandardFrameConstants::kCallerFPOffset);
+ intptr_t parent_frame_type = Memory::intptr_at(
+ parent_frame_pointer + CommonFrameConstants::kContextOrFrameTypeOffset);
+ int length;
+ Address arguments_frame;
+ if (parent_frame_type ==
+ StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)) {
+ length = Smi::cast(*reinterpret_cast<Object**>(
+ parent_frame_pointer +
+ ArgumentsAdaptorFrameConstants::kLengthOffset))
+ ->value();
+ arguments_frame = parent_frame_pointer;
+ } else {
+ length = formal_parameter_count_;
+ arguments_frame = input_frame_pointer;
+ }
+
+ if (is_rest) {
+ // If the actual number of arguments is less than the number of formal
+ // parameters, we have zero rest parameters.
+ length = std::max(0, length - formal_parameter_count_);
+ }
+
+ int object_index = static_cast<int>(object_positions_.size());
+ int value_index = static_cast<int>(frame.values_.size());
+ object_positions_.push_back({frame_index, value_index});
+ frame.Add(TranslatedValue::NewDeferredObject(
+ this, length + FixedArray::kHeaderSize / kPointerSize, object_index));
+
+ frame.Add(
+ TranslatedValue::NewTagged(this, isolate_->heap()->fixed_array_map()));
+ frame.Add(TranslatedValue::NewInt32(this, length));
+
+ for (int i = length - 1; i >= 0; --i) {
+ Address argument_slot = arguments_frame +
+ CommonFrameConstants::kFixedFrameSizeAboveFp +
+ i * kPointerSize;
+ frame.Add(TranslatedValue::NewTagged(
+ this, *reinterpret_cast<Object**>(argument_slot)));
+ }
+}
-// We can't intermix stack decoding and allocations because
-// deoptimization infrastracture is not GC safe.
+// We can't intermix stack decoding and allocations because the deoptimization
+// infrastracture is not GC safe.
// Thus we build a temporary structure in malloced space.
-TranslatedValue TranslatedState::CreateNextTranslatedValue(
- int frame_index, int value_index, TranslationIterator* iterator,
- FixedArray* literal_array, Address fp, RegisterValues* registers,
- FILE* trace_file) {
+// The TranslatedValue objects created correspond to the static translation
+// instructions from the TranslationIterator, except for
+// Translation::ARGUMENTS_ELEMENTS, where the number and values of the
+// FixedArray elements depend on dynamic information from the optimized frame.
+// Returns the number of expected nested translations from the
+// TranslationIterator.
+int TranslatedState::CreateNextTranslatedValue(
+ int frame_index, TranslationIterator* iterator, FixedArray* literal_array,
+ Address fp, RegisterValues* registers, FILE* trace_file) {
disasm::NameConverter converter;
+ TranslatedFrame& frame = frames_[frame_index];
+ int value_index = static_cast<int>(frame.values_.size());
+
Translation::Opcode opcode =
static_cast<Translation::Opcode>(iterator->Next());
switch (opcode) {
@@ -3366,18 +3433,30 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
PrintF(trace_file, "duplicated object #%d", object_id);
}
object_positions_.push_back(object_positions_[object_id]);
- return TranslatedValue::NewDuplicateObject(this, object_id);
+ TranslatedValue translated_value =
+ TranslatedValue::NewDuplicateObject(this, object_id);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::ARGUMENTS_OBJECT: {
int arg_count = iterator->Next();
int object_index = static_cast<int>(object_positions_.size());
if (trace_file != nullptr) {
- PrintF(trace_file, "argumets object #%d (length = %d)", object_index,
+ PrintF(trace_file, "arguments object #%d (length = %d)", object_index,
arg_count);
}
object_positions_.push_back({frame_index, value_index});
- return TranslatedValue::NewArgumentsObject(this, arg_count, object_index);
+ TranslatedValue translated_value =
+ TranslatedValue::NewArgumentsObject(this, arg_count, object_index);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
+ }
+
+ case Translation::ARGUMENTS_ELEMENTS: {
+ bool is_rest = iterator->Next();
+ CreateArgumentsElementsTranslatedValues(frame_index, fp, is_rest);
+ return 0;
}
case Translation::CAPTURED_OBJECT: {
@@ -3388,78 +3467,121 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
field_count);
}
object_positions_.push_back({frame_index, value_index});
- return TranslatedValue::NewDeferredObject(this, field_count,
- object_index);
+ TranslatedValue translated_value =
+ TranslatedValue::NewDeferredObject(this, field_count, object_index);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::REGISTER: {
int input_reg = iterator->Next();
- if (registers == nullptr) return TranslatedValue::NewInvalid(this);
+ if (registers == nullptr) {
+ TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
+ }
intptr_t value = registers->GetRegister(input_reg);
if (trace_file != nullptr) {
PrintF(trace_file, "0x%08" V8PRIxPTR " ; %s ", value,
converter.NameOfCPURegister(input_reg));
reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
}
- return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
+ TranslatedValue translated_value =
+ TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::INT32_REGISTER: {
int input_reg = iterator->Next();
- if (registers == nullptr) return TranslatedValue::NewInvalid(this);
+ if (registers == nullptr) {
+ TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
+ }
intptr_t value = registers->GetRegister(input_reg);
if (trace_file != nullptr) {
PrintF(trace_file, "%" V8PRIdPTR " ; %s ", value,
converter.NameOfCPURegister(input_reg));
}
- return TranslatedValue::NewInt32(this, static_cast<int32_t>(value));
+ TranslatedValue translated_value =
+ TranslatedValue::NewInt32(this, static_cast<int32_t>(value));
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::UINT32_REGISTER: {
int input_reg = iterator->Next();
- if (registers == nullptr) return TranslatedValue::NewInvalid(this);
+ if (registers == nullptr) {
+ TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
+ }
intptr_t value = registers->GetRegister(input_reg);
if (trace_file != nullptr) {
PrintF(trace_file, "%" V8PRIuPTR " ; %s (uint)", value,
converter.NameOfCPURegister(input_reg));
reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
}
- return TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value));
+ TranslatedValue translated_value =
+ TranslatedValue::NewUInt32(this, static_cast<uint32_t>(value));
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::BOOL_REGISTER: {
int input_reg = iterator->Next();
- if (registers == nullptr) return TranslatedValue::NewInvalid(this);
+ if (registers == nullptr) {
+ TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
+ }
intptr_t value = registers->GetRegister(input_reg);
if (trace_file != nullptr) {
PrintF(trace_file, "%" V8PRIdPTR " ; %s (bool)", value,
converter.NameOfCPURegister(input_reg));
}
- return TranslatedValue::NewBool(this, static_cast<uint32_t>(value));
+ TranslatedValue translated_value =
+ TranslatedValue::NewBool(this, static_cast<uint32_t>(value));
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::FLOAT_REGISTER: {
int input_reg = iterator->Next();
- if (registers == nullptr) return TranslatedValue::NewInvalid(this);
+ if (registers == nullptr) {
+ TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
+ }
Float32 value = registers->GetFloatRegister(input_reg);
if (trace_file != nullptr) {
PrintF(trace_file, "%e ; %s (float)", value.get_scalar(),
RegisterConfiguration::Crankshaft()->GetFloatRegisterName(
input_reg));
}
- return TranslatedValue::NewFloat(this, value);
+ TranslatedValue translated_value = TranslatedValue::NewFloat(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::DOUBLE_REGISTER: {
int input_reg = iterator->Next();
- if (registers == nullptr) return TranslatedValue::NewInvalid(this);
+ if (registers == nullptr) {
+ TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
+ }
Float64 value = registers->GetDoubleRegister(input_reg);
if (trace_file != nullptr) {
PrintF(trace_file, "%e ; %s (double)", value.get_scalar(),
RegisterConfiguration::Crankshaft()->GetDoubleRegisterName(
input_reg));
}
- return TranslatedValue::NewDouble(this, value);
+ TranslatedValue translated_value =
+ TranslatedValue::NewDouble(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::STACK_SLOT: {
@@ -3471,7 +3593,10 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
}
- return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
+ TranslatedValue translated_value =
+ TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value));
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::INT32_STACK_SLOT: {
@@ -3483,7 +3608,9 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
static_cast<int32_t>(value), slot_offset < 0 ? '-' : '+',
std::abs(slot_offset));
}
- return TranslatedValue::NewInt32(this, value);
+ TranslatedValue translated_value = TranslatedValue::NewInt32(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::UINT32_STACK_SLOT: {
@@ -3494,7 +3621,10 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value,
slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
}
- return TranslatedValue::NewUInt32(this, value);
+ TranslatedValue translated_value =
+ TranslatedValue::NewUInt32(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::BOOL_STACK_SLOT: {
@@ -3505,7 +3635,9 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value,
slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
}
- return TranslatedValue::NewBool(this, value);
+ TranslatedValue translated_value = TranslatedValue::NewBool(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::FLOAT_STACK_SLOT: {
@@ -3516,7 +3648,9 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
PrintF(trace_file, "%e ; (float) [fp %c %d] ", value.get_scalar(),
slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
}
- return TranslatedValue::NewFloat(this, value);
+ TranslatedValue translated_value = TranslatedValue::NewFloat(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::DOUBLE_STACK_SLOT: {
@@ -3527,7 +3661,10 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
PrintF(trace_file, "%e ; (double) [fp %c %d] ", value.get_scalar(),
slot_offset < 0 ? '-' : '+', std::abs(slot_offset));
}
- return TranslatedValue::NewDouble(this, value);
+ TranslatedValue translated_value =
+ TranslatedValue::NewDouble(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
case Translation::LITERAL: {
@@ -3539,12 +3676,18 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
reinterpret_cast<Object*>(value)->ShortPrint(trace_file);
}
- return TranslatedValue::NewTagged(this, value);
+ TranslatedValue translated_value =
+ TranslatedValue::NewTagged(this, value);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
}
FATAL("We should never get here - unexpected deopt info.");
- return TranslatedValue(nullptr, TranslatedValue::kInvalid);
+ TranslatedValue translated_value =
+ TranslatedValue(nullptr, TranslatedValue::kInvalid);
+ frame.Add(translated_value);
+ return translated_value.GetChildrenCount();
}
@@ -3559,7 +3702,8 @@ TranslatedState::TranslatedState(JavaScriptFrame* frame)
TranslationIterator it(data->TranslationByteArray(),
data->TranslationIndex(deopt_index)->value());
Init(frame->fp(), &it, data->LiteralArray(), nullptr /* registers */,
- nullptr /* trace file */);
+ nullptr /* trace file */,
+ frame->function()->shared()->internal_formal_parameter_count());
}
@@ -3568,13 +3712,14 @@ TranslatedState::TranslatedState()
stack_frame_pointer_(nullptr),
has_adapted_arguments_(false) {}
-
void TranslatedState::Init(Address input_frame_pointer,
TranslationIterator* iterator,
FixedArray* literal_array, RegisterValues* registers,
- FILE* trace_file) {
+ FILE* trace_file, int formal_parameter_count) {
DCHECK(frames_.empty());
+ formal_parameter_count_ = formal_parameter_count;
+
isolate_ = literal_array->GetIsolate();
// Read out the 'header' translation.
Translation::Opcode opcode =
@@ -3589,7 +3734,7 @@ void TranslatedState::Init(Address input_frame_pointer,
std::stack<int> nested_counts;
// Read the frames
- for (int i = 0; i < count; i++) {
+ for (int frame_index = 0; frame_index < count; frame_index++) {
// Read the frame descriptor.
frames_.push_back(CreateNextTranslatedFrame(
iterator, literal_array, input_frame_pointer, trace_file));
@@ -3612,10 +3757,9 @@ void TranslatedState::Init(Address input_frame_pointer,
}
}
- TranslatedValue value = CreateNextTranslatedValue(
- i, static_cast<int>(frame.values_.size()), iterator, literal_array,
- input_frame_pointer, registers, trace_file);
- frame.Add(value);
+ int nested_count =
+ CreateNextTranslatedValue(frame_index, iterator, literal_array,
+ input_frame_pointer, registers, trace_file);
if (trace_file != nullptr) {
PrintF(trace_file, "\n");
@@ -3623,10 +3767,9 @@ void TranslatedState::Init(Address input_frame_pointer,
// Update the value count and resolve the nesting.
values_to_process--;
- int children_count = value.GetChildrenCount();
- if (children_count > 0) {
+ if (nested_count > 0) {
nested_counts.push(values_to_process);
- values_to_process = children_count;
+ values_to_process = nested_count;
} else {
while (values_to_process == 0 && !nested_counts.empty()) {
values_to_process = nested_counts.top();
« no previous file with comments | « src/deoptimizer.h ('k') | src/interface-descriptors.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698