| 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();
|
|
|