diff --git a/BUILD.gn b/BUILD.gn index ce72eabe96..85f62d7c92 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -2644,8 +2644,7 @@ v8_source_set("v8_base_without_compiler") { "src/deoptimizer/translated-state.h", "src/deoptimizer/translation-array.cc", "src/deoptimizer/translation-array.h", - "src/deoptimizer/translations.cc", - "src/deoptimizer/translations.h", + "src/deoptimizer/translation-opcode.h", "src/diagnostics/basic-block-profiler.cc", "src/diagnostics/basic-block-profiler.h", "src/diagnostics/code-tracer.h", diff --git a/src/compiler/backend/code-generator.cc b/src/compiler/backend/code-generator.cc index de52edae11..63471752d9 100644 --- a/src/compiler/backend/code-generator.cc +++ b/src/compiler/backend/code-generator.cc @@ -985,8 +985,8 @@ Handle CodeGenerator::GenerateDeoptimizationData() { Handle data = DeoptimizationData::New(isolate(), deopt_count, AllocationType::kOld); - Handle translation_array = - translations_.CreateByteArray(isolate()->factory()); + Handle translation_array = + translations_.ToTranslationArray(isolate()->factory()); data->SetTranslationByteArray(*translation_array); data->SetInlinedFunctionCount( @@ -1094,66 +1094,49 @@ DeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry( void CodeGenerator::TranslateStateValueDescriptor( StateValueDescriptor* desc, StateValueList* nested, - Translation* translation, InstructionOperandIterator* iter) { - // Note: - // If translation is null, we just skip the relevant instruction operands. + InstructionOperandIterator* iter) { if (desc->IsNested()) { - if (translation != nullptr) { - translation->BeginCapturedObject(static_cast(nested->size())); - } + translations_.BeginCapturedObject(static_cast(nested->size())); for (auto field : *nested) { - TranslateStateValueDescriptor(field.desc, field.nested, translation, - iter); + TranslateStateValueDescriptor(field.desc, field.nested, iter); } } else if (desc->IsArgumentsElements()) { - if (translation != nullptr) { - translation->ArgumentsElements(desc->arguments_type()); - } + translations_.ArgumentsElements(desc->arguments_type()); } else if (desc->IsArgumentsLength()) { - if (translation != nullptr) { - translation->ArgumentsLength(); - } + translations_.ArgumentsLength(); } else if (desc->IsDuplicate()) { - if (translation != nullptr) { - translation->DuplicateObject(static_cast(desc->id())); - } + translations_.DuplicateObject(static_cast(desc->id())); } else if (desc->IsPlain()) { InstructionOperand* op = iter->Advance(); - if (translation != nullptr) { - AddTranslationForOperand(translation, iter->instruction(), op, - desc->type()); - } + AddTranslationForOperand(iter->instruction(), op, desc->type()); } else { DCHECK(desc->IsOptimizedOut()); - if (translation != nullptr) { if (optimized_out_literal_id_ == -1) { optimized_out_literal_id_ = DefineDeoptimizationLiteral( DeoptimizationLiteral(isolate()->factory()->optimized_out())); } - translation->StoreLiteral(optimized_out_literal_id_); - } + translations_.StoreLiteral(optimized_out_literal_id_); } } void CodeGenerator::TranslateFrameStateDescriptorOperands( - FrameStateDescriptor* desc, InstructionOperandIterator* iter, - Translation* translation) { + FrameStateDescriptor* desc, InstructionOperandIterator* iter) { size_t index = 0; StateValueList* values = desc->GetStateValueDescriptors(); for (StateValueList::iterator it = values->begin(); it != values->end(); ++it, ++index) { - TranslateStateValueDescriptor((*it).desc, (*it).nested, translation, iter); + TranslateStateValueDescriptor((*it).desc, (*it).nested, iter); } DCHECK_EQ(desc->GetSize(), index); } void CodeGenerator::BuildTranslationForFrameStateDescriptor( FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, - Translation* translation, OutputFrameStateCombine state_combine) { + OutputFrameStateCombine state_combine) { // Outer-most state must be added to translation first. if (descriptor->outer_state() != nullptr) { BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, - translation, state_combine); + state_combine); } Handle shared_info; @@ -1178,35 +1161,35 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor( return_offset = static_cast(state_combine.GetOffsetToPokeAt()); return_count = static_cast(iter->instruction()->OutputCount()); } - translation->BeginInterpretedFrame(bailout_id, shared_info_id, height, - return_offset, return_count); + translations_.BeginInterpretedFrame(bailout_id, shared_info_id, height, + return_offset, return_count); break; } case FrameStateType::kArgumentsAdaptor: - translation->BeginArgumentsAdaptorFrame(shared_info_id, height); + translations_.BeginArgumentsAdaptorFrame(shared_info_id, height); break; case FrameStateType::kConstructStub: DCHECK(bailout_id.IsValidForConstructStub()); - translation->BeginConstructStubFrame(bailout_id, shared_info_id, height); + translations_.BeginConstructStubFrame(bailout_id, shared_info_id, height); break; case FrameStateType::kBuiltinContinuation: { - translation->BeginBuiltinContinuationFrame(bailout_id, shared_info_id, - height); + translations_.BeginBuiltinContinuationFrame(bailout_id, shared_info_id, + height); break; } case FrameStateType::kJavaScriptBuiltinContinuation: { - translation->BeginJavaScriptBuiltinContinuationFrame( + translations_.BeginJavaScriptBuiltinContinuationFrame( bailout_id, shared_info_id, height); break; } case FrameStateType::kJavaScriptBuiltinContinuationWithCatch: { - translation->BeginJavaScriptBuiltinContinuationWithCatchFrame( + translations_.BeginJavaScriptBuiltinContinuationWithCatchFrame( bailout_id, shared_info_id, height); break; } } - TranslateFrameStateDescriptorOperands(descriptor, iter, translation); + TranslateFrameStateDescriptorOperands(descriptor, iter); } DeoptimizationExit* CodeGenerator::BuildTranslation( @@ -1217,23 +1200,21 @@ DeoptimizationExit* CodeGenerator::BuildTranslation( FrameStateDescriptor* const descriptor = entry.descriptor(); frame_state_offset++; - int update_feedback_count = entry.feedback().IsValid() ? 1 : 0; - Translation translation(&translations_, - static_cast(descriptor->GetFrameCount()), - static_cast(descriptor->GetJSFrameCount()), - update_feedback_count, zone()); + const int update_feedback_count = entry.feedback().IsValid() ? 1 : 0; + const int translation_index = translations_.BeginTranslation( + static_cast(descriptor->GetFrameCount()), + static_cast(descriptor->GetJSFrameCount()), update_feedback_count); if (entry.feedback().IsValid()) { DeoptimizationLiteral literal = DeoptimizationLiteral(entry.feedback().vector); int literal_id = DefineDeoptimizationLiteral(literal); - translation.AddUpdateFeedback(literal_id, entry.feedback().slot.ToInt()); + translations_.AddUpdateFeedback(literal_id, entry.feedback().slot.ToInt()); } InstructionOperandIterator iter(instr, frame_state_offset); - BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation, - state_combine); + BuildTranslationForFrameStateDescriptor(descriptor, &iter, state_combine); DeoptimizationExit* const exit = zone()->New( - current_source_position_, descriptor->bailout_id(), translation.index(), + current_source_position_, descriptor->bailout_id(), translation_index, pc_offset, entry.kind(), entry.reason()); if (!Deoptimizer::kSupportsFixedDeoptExitSizes) { @@ -1253,21 +1234,20 @@ DeoptimizationExit* CodeGenerator::BuildTranslation( return exit; } -void CodeGenerator::AddTranslationForOperand(Translation* translation, - Instruction* instr, +void CodeGenerator::AddTranslationForOperand(Instruction* instr, InstructionOperand* op, MachineType type) { if (op->IsStackSlot()) { if (type.representation() == MachineRepresentation::kBit) { - translation->StoreBoolStackSlot(LocationOperand::cast(op)->index()); + translations_.StoreBoolStackSlot(LocationOperand::cast(op)->index()); } else if (type == MachineType::Int8() || type == MachineType::Int16() || type == MachineType::Int32()) { - translation->StoreInt32StackSlot(LocationOperand::cast(op)->index()); + translations_.StoreInt32StackSlot(LocationOperand::cast(op)->index()); } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || type == MachineType::Uint32()) { - translation->StoreUint32StackSlot(LocationOperand::cast(op)->index()); + translations_.StoreUint32StackSlot(LocationOperand::cast(op)->index()); } else if (type == MachineType::Int64()) { - translation->StoreInt64StackSlot(LocationOperand::cast(op)->index()); + translations_.StoreInt64StackSlot(LocationOperand::cast(op)->index()); } else { #if defined(V8_COMPRESS_POINTERS) CHECK(MachineRepresentation::kTagged == type.representation() || @@ -1275,27 +1255,27 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, #else CHECK(MachineRepresentation::kTagged == type.representation()); #endif - translation->StoreStackSlot(LocationOperand::cast(op)->index()); + translations_.StoreStackSlot(LocationOperand::cast(op)->index()); } } else if (op->IsFPStackSlot()) { if (type.representation() == MachineRepresentation::kFloat64) { - translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index()); + translations_.StoreDoubleStackSlot(LocationOperand::cast(op)->index()); } else { CHECK_EQ(MachineRepresentation::kFloat32, type.representation()); - translation->StoreFloatStackSlot(LocationOperand::cast(op)->index()); + translations_.StoreFloatStackSlot(LocationOperand::cast(op)->index()); } } else if (op->IsRegister()) { InstructionOperandConverter converter(this, instr); if (type.representation() == MachineRepresentation::kBit) { - translation->StoreBoolRegister(converter.ToRegister(op)); + translations_.StoreBoolRegister(converter.ToRegister(op)); } else if (type == MachineType::Int8() || type == MachineType::Int16() || type == MachineType::Int32()) { - translation->StoreInt32Register(converter.ToRegister(op)); + translations_.StoreInt32Register(converter.ToRegister(op)); } else if (type == MachineType::Uint8() || type == MachineType::Uint16() || type == MachineType::Uint32()) { - translation->StoreUint32Register(converter.ToRegister(op)); + translations_.StoreUint32Register(converter.ToRegister(op)); } else if (type == MachineType::Int64()) { - translation->StoreInt64Register(converter.ToRegister(op)); + translations_.StoreInt64Register(converter.ToRegister(op)); } else { #if defined(V8_COMPRESS_POINTERS) CHECK(MachineRepresentation::kTagged == type.representation() || @@ -1303,15 +1283,15 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, #else CHECK(MachineRepresentation::kTagged == type.representation()); #endif - translation->StoreRegister(converter.ToRegister(op)); + translations_.StoreRegister(converter.ToRegister(op)); } } else if (op->IsFPRegister()) { InstructionOperandConverter converter(this, instr); if (type.representation() == MachineRepresentation::kFloat64) { - translation->StoreDoubleRegister(converter.ToDoubleRegister(op)); + translations_.StoreDoubleRegister(converter.ToDoubleRegister(op)); } else { CHECK_EQ(MachineRepresentation::kFloat32, type.representation()); - translation->StoreFloatRegister(converter.ToFloatRegister(op)); + translations_.StoreFloatRegister(converter.ToFloatRegister(op)); } } else { CHECK(op->IsImmediate()); @@ -1390,10 +1370,10 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation, UNREACHABLE(); } if (literal.object().equals(info()->closure())) { - translation->StoreJSFrameFunction(); + translations_.StoreJSFrameFunction(); } else { int literal_id = DefineDeoptimizationLiteral(literal); - translation->StoreLiteral(literal_id); + translations_.StoreLiteral(literal_id); } } } diff --git a/src/compiler/backend/code-generator.h b/src/compiler/backend/code-generator.h index 1c828b2e3a..965fbd8296 100644 --- a/src/compiler/backend/code-generator.h +++ b/src/compiler/backend/code-generator.h @@ -394,16 +394,14 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler { OutputFrameStateCombine state_combine); void BuildTranslationForFrameStateDescriptor( FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, - Translation* translation, OutputFrameStateCombine state_combine); + OutputFrameStateCombine state_combine); void TranslateStateValueDescriptor(StateValueDescriptor* desc, StateValueList* nested, - Translation* translation, InstructionOperandIterator* iter); void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc, - InstructionOperandIterator* iter, - Translation* translation); - void AddTranslationForOperand(Translation* translation, Instruction* instr, - InstructionOperand* op, MachineType type); + InstructionOperandIterator* iter); + void AddTranslationForOperand(Instruction* instr, InstructionOperand* op, + MachineType type); void MarkLazyDeoptSite(); void PrepareForDeoptimizationExits(ZoneDeque* exits); @@ -444,7 +442,7 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler { ZoneDeque deoptimization_exits_; ZoneDeque deoptimization_literals_; size_t inlined_function_count_ = 0; - TranslationBuffer translations_; + TranslationArrayBuilder translations_; int handler_table_offset_ = 0; int last_lazy_deopt_pc_ = 0; diff --git a/src/deoptimizer/deoptimized-frame-info.h b/src/deoptimizer/deoptimized-frame-info.h index 4458e34585..cb0c48d110 100644 --- a/src/deoptimizer/deoptimized-frame-info.h +++ b/src/deoptimizer/deoptimized-frame-info.h @@ -7,7 +7,7 @@ #include -#include "src/deoptimizer/translations.h" +#include "src/deoptimizer/translated-state.h" namespace v8 { namespace internal { diff --git a/src/deoptimizer/deoptimizer.h b/src/deoptimizer/deoptimizer.h index 8a1b7305ae..93f61e4cea 100644 --- a/src/deoptimizer/deoptimizer.h +++ b/src/deoptimizer/deoptimizer.h @@ -7,10 +7,11 @@ #include +#include "src/builtins/builtins.h" #include "src/codegen/source-position.h" #include "src/deoptimizer/deoptimize-reason.h" #include "src/deoptimizer/frame-description.h" -#include "src/deoptimizer/translations.h" +#include "src/deoptimizer/translated-state.h" #include "src/diagnostics/code-tracer.h" #include "src/objects/js-function.h" diff --git a/src/deoptimizer/translated-state.cc b/src/deoptimizer/translated-state.cc index cbd33c3561..8300ce1484 100644 --- a/src/deoptimizer/translated-state.cc +++ b/src/deoptimizer/translated-state.cc @@ -4,10 +4,12 @@ #include "src/deoptimizer/translated-state.h" +#include + #include "src/base/memory.h" #include "src/deoptimizer/deoptimizer.h" #include "src/deoptimizer/materialized-object-store.h" -#include "src/deoptimizer/translations.h" +#include "src/deoptimizer/translation-opcode.h" #include "src/diagnostics/disasm.h" #include "src/execution/frames.h" #include "src/execution/isolate.h" @@ -26,6 +28,229 @@ using base::ReadUnalignedValue; namespace internal { +void TranslationArrayPrintSingleFrame(std::ostream& os, + TranslationArray translation_array, + int translation_index, + FixedArray literal_array) { + DisallowGarbageCollection gc_oh_noes; + TranslationArrayIterator iterator(translation_array, translation_index); + disasm::NameConverter converter; + + TranslationOpcode opcode = TranslationOpcodeFromInt(iterator.Next()); + DCHECK(TranslationOpcode::BEGIN == opcode); + int frame_count = iterator.Next(); + int jsframe_count = iterator.Next(); + int update_feedback_count = iterator.Next(); + os << " " << TranslationOpcodeToString(opcode) + << " {frame count=" << frame_count << ", js frame count=" << jsframe_count + << ", update_feedback_count=" << update_feedback_count << "}\n"; + + while (iterator.HasNext()) { + opcode = TranslationOpcodeFromInt(iterator.Next()); + if (opcode == TranslationOpcode::BEGIN) break; + + os << std::setw(31) << " " << TranslationOpcodeToString(opcode) << " "; + + switch (opcode) { + case TranslationOpcode::BEGIN: + UNREACHABLE(); + break; + + case TranslationOpcode::INTERPRETED_FRAME: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 5); + int bytecode_offset = iterator.Next(); + int shared_info_id = iterator.Next(); + unsigned height = iterator.Next(); + int return_value_offset = iterator.Next(); + int return_value_count = iterator.Next(); + Object shared_info = literal_array.get(shared_info_id); + os << "{bytecode_offset=" << bytecode_offset << ", function=" + << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() + << ", height=" << height << ", retval=@" << return_value_offset + << "(#" << return_value_count << ")}"; + break; + } + + case TranslationOpcode::CONSTRUCT_STUB_FRAME: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 3); + int bailout_id = iterator.Next(); + int shared_info_id = iterator.Next(); + Object shared_info = literal_array.get(shared_info_id); + unsigned height = iterator.Next(); + os << "{bailout_id=" << bailout_id << ", function=" + << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() + << ", height=" << height << "}"; + break; + } + + case TranslationOpcode::BUILTIN_CONTINUATION_FRAME: + case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: + case TranslationOpcode:: + JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 3); + int bailout_id = iterator.Next(); + int shared_info_id = iterator.Next(); + Object shared_info = literal_array.get(shared_info_id); + unsigned height = iterator.Next(); + os << "{bailout_id=" << bailout_id << ", function=" + << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() + << ", height=" << height << "}"; + break; + } + + case TranslationOpcode::ARGUMENTS_ADAPTOR_FRAME: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 2); + int shared_info_id = iterator.Next(); + Object shared_info = literal_array.get(shared_info_id); + unsigned height = iterator.Next(); + os << "{function=" + << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() + << ", height=" << height << "}"; + break; + } + + case TranslationOpcode::REGISTER: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int reg_code = iterator.Next(); + os << "{input=" << converter.NameOfCPURegister(reg_code) << "}"; + break; + } + + case TranslationOpcode::INT32_REGISTER: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int reg_code = iterator.Next(); + os << "{input=" << converter.NameOfCPURegister(reg_code) << " (int32)}"; + break; + } + + case TranslationOpcode::INT64_REGISTER: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int reg_code = iterator.Next(); + os << "{input=" << converter.NameOfCPURegister(reg_code) << " (int64)}"; + break; + } + + case TranslationOpcode::UINT32_REGISTER: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int reg_code = iterator.Next(); + os << "{input=" << converter.NameOfCPURegister(reg_code) + << " (uint32)}"; + break; + } + + case TranslationOpcode::BOOL_REGISTER: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int reg_code = iterator.Next(); + os << "{input=" << converter.NameOfCPURegister(reg_code) << " (bool)}"; + break; + } + + case TranslationOpcode::FLOAT_REGISTER: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int reg_code = iterator.Next(); + os << "{input=" << FloatRegister::from_code(reg_code) << "}"; + break; + } + + case TranslationOpcode::DOUBLE_REGISTER: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int reg_code = iterator.Next(); + os << "{input=" << DoubleRegister::from_code(reg_code) << "}"; + break; + } + + case TranslationOpcode::STACK_SLOT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int input_slot_index = iterator.Next(); + os << "{input=" << input_slot_index << "}"; + break; + } + + case TranslationOpcode::INT32_STACK_SLOT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int input_slot_index = iterator.Next(); + os << "{input=" << input_slot_index << " (int32)}"; + break; + } + + case TranslationOpcode::INT64_STACK_SLOT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int input_slot_index = iterator.Next(); + os << "{input=" << input_slot_index << " (int64)}"; + break; + } + + case TranslationOpcode::UINT32_STACK_SLOT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int input_slot_index = iterator.Next(); + os << "{input=" << input_slot_index << " (uint32)}"; + break; + } + + case TranslationOpcode::BOOL_STACK_SLOT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int input_slot_index = iterator.Next(); + os << "{input=" << input_slot_index << " (bool)}"; + break; + } + + case TranslationOpcode::FLOAT_STACK_SLOT: + case TranslationOpcode::DOUBLE_STACK_SLOT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int input_slot_index = iterator.Next(); + os << "{input=" << input_slot_index << "}"; + break; + } + + case TranslationOpcode::LITERAL: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int literal_index = iterator.Next(); + Object literal_value = literal_array.get(literal_index); + os << "{literal_id=" << literal_index << " (" << Brief(literal_value) + << ")}"; + break; + } + + case TranslationOpcode::DUPLICATED_OBJECT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int object_index = iterator.Next(); + os << "{object_index=" << object_index << "}"; + break; + } + + case TranslationOpcode::ARGUMENTS_ELEMENTS: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + CreateArgumentsType arguments_type = + static_cast(iterator.Next()); + os << "{arguments_type=" << arguments_type << "}"; + break; + } + case TranslationOpcode::ARGUMENTS_LENGTH: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 0); + os << "{arguments_length}"; + break; + } + + case TranslationOpcode::CAPTURED_OBJECT: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); + int args_length = iterator.Next(); + os << "{length=" << args_length << "}"; + break; + } + + case TranslationOpcode::UPDATE_FEEDBACK: { + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 2); + int literal_index = iterator.Next(); + FeedbackSlot slot(iterator.Next()); + os << "{feedback={vector_index=" << literal_index << ", slot=" << slot + << "}}"; + break; + } + } + os << "\n"; + } +} + // static TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container, int length, @@ -455,10 +680,9 @@ void TranslatedFrame::Handlify() { TranslatedFrame TranslatedState::CreateNextTranslatedFrame( TranslationArrayIterator* iterator, FixedArray literal_array, Address fp, FILE* trace_file) { - Translation::Opcode opcode = - static_cast(iterator->Next()); + TranslationOpcode opcode = TranslationOpcodeFromInt(iterator->Next()); switch (opcode) { - case Translation::INTERPRETED_FRAME: { + case TranslationOpcode::INTERPRETED_FRAME: { BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next()); SharedFunctionInfo shared_info = SharedFunctionInfo::cast(literal_array.get(iterator->Next())); @@ -480,7 +704,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame( return_value_count); } - case Translation::ARGUMENTS_ADAPTOR_FRAME: { + case TranslationOpcode::ARGUMENTS_ADAPTOR_FRAME: { SharedFunctionInfo shared_info = SharedFunctionInfo::cast(literal_array.get(iterator->Next())); int height = iterator->Next(); @@ -492,7 +716,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame( return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height); } - case Translation::CONSTRUCT_STUB_FRAME: { + case TranslationOpcode::CONSTRUCT_STUB_FRAME: { BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next()); SharedFunctionInfo shared_info = SharedFunctionInfo::cast(literal_array.get(iterator->Next())); @@ -507,7 +731,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame( height); } - case Translation::BUILTIN_CONTINUATION_FRAME: { + case TranslationOpcode::BUILTIN_CONTINUATION_FRAME: { BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next()); SharedFunctionInfo shared_info = SharedFunctionInfo::cast(literal_array.get(iterator->Next())); @@ -523,7 +747,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame( shared_info, height); } - case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: { + case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: { BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next()); SharedFunctionInfo shared_info = SharedFunctionInfo::cast(literal_array.get(iterator->Next())); @@ -538,7 +762,8 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame( return TranslatedFrame::JavaScriptBuiltinContinuationFrame( bytecode_offset, shared_info, height); } - case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: { + + case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: { BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next()); SharedFunctionInfo shared_info = SharedFunctionInfo::cast(literal_array.get(iterator->Next())); @@ -554,31 +779,30 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame( return TranslatedFrame::JavaScriptBuiltinContinuationWithCatchFrame( bytecode_offset, shared_info, height); } - case Translation::UPDATE_FEEDBACK: - case Translation::BEGIN: - case Translation::DUPLICATED_OBJECT: - case Translation::ARGUMENTS_ELEMENTS: - case Translation::ARGUMENTS_LENGTH: - case Translation::CAPTURED_OBJECT: - case Translation::REGISTER: - case Translation::INT32_REGISTER: - case Translation::INT64_REGISTER: - case Translation::UINT32_REGISTER: - case Translation::BOOL_REGISTER: - case Translation::FLOAT_REGISTER: - case Translation::DOUBLE_REGISTER: - case Translation::STACK_SLOT: - case Translation::INT32_STACK_SLOT: - case Translation::INT64_STACK_SLOT: - case Translation::UINT32_STACK_SLOT: - case Translation::BOOL_STACK_SLOT: - case Translation::FLOAT_STACK_SLOT: - case Translation::DOUBLE_STACK_SLOT: - case Translation::LITERAL: + case TranslationOpcode::UPDATE_FEEDBACK: + case TranslationOpcode::BEGIN: + case TranslationOpcode::DUPLICATED_OBJECT: + case TranslationOpcode::ARGUMENTS_ELEMENTS: + case TranslationOpcode::ARGUMENTS_LENGTH: + case TranslationOpcode::CAPTURED_OBJECT: + case TranslationOpcode::REGISTER: + case TranslationOpcode::INT32_REGISTER: + case TranslationOpcode::INT64_REGISTER: + case TranslationOpcode::UINT32_REGISTER: + case TranslationOpcode::BOOL_REGISTER: + case TranslationOpcode::FLOAT_REGISTER: + case TranslationOpcode::DOUBLE_REGISTER: + case TranslationOpcode::STACK_SLOT: + case TranslationOpcode::INT32_STACK_SLOT: + case TranslationOpcode::INT64_STACK_SLOT: + case TranslationOpcode::UINT32_STACK_SLOT: + case TranslationOpcode::BOOL_STACK_SLOT: + case TranslationOpcode::FLOAT_STACK_SLOT: + case TranslationOpcode::DOUBLE_STACK_SLOT: + case TranslationOpcode::LITERAL: break; } - FATAL("We should never get here - unexpected deopt info."); - return TranslatedFrame::InvalidFrame(); + UNREACHABLE(); } // static @@ -656,7 +880,7 @@ void TranslatedState::CreateArgumentsElementsTranslatedValues( // Thus we build a temporary structure in malloced space. // The TranslatedValue objects created correspond to the static translation // instructions from the TranslationArrayIterator, except for -// Translation::ARGUMENTS_ELEMENTS, where the number and values of the +// TranslationOpcode::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 // TranslationArrayIterator. @@ -669,21 +893,20 @@ int TranslatedState::CreateNextTranslatedValue( TranslatedFrame& frame = frames_[frame_index]; int value_index = static_cast(frame.values_.size()); - Translation::Opcode opcode = - static_cast(iterator->Next()); + TranslationOpcode opcode = TranslationOpcodeFromInt(iterator->Next()); switch (opcode) { - case Translation::BEGIN: - case Translation::INTERPRETED_FRAME: - case Translation::ARGUMENTS_ADAPTOR_FRAME: - case Translation::CONSTRUCT_STUB_FRAME: - case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: - case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: - case Translation::BUILTIN_CONTINUATION_FRAME: - case Translation::UPDATE_FEEDBACK: + case TranslationOpcode::BEGIN: + case TranslationOpcode::INTERPRETED_FRAME: + case TranslationOpcode::ARGUMENTS_ADAPTOR_FRAME: + case TranslationOpcode::CONSTRUCT_STUB_FRAME: + case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: + case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: + case TranslationOpcode::BUILTIN_CONTINUATION_FRAME: + case TranslationOpcode::UPDATE_FEEDBACK: // Peeled off before getting here. break; - case Translation::DUPLICATED_OBJECT: { + case TranslationOpcode::DUPLICATED_OBJECT: { int object_id = iterator->Next(); if (trace_file != nullptr) { PrintF(trace_file, "duplicated object #%d", object_id); @@ -695,7 +918,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::ARGUMENTS_ELEMENTS: { + case TranslationOpcode::ARGUMENTS_ELEMENTS: { CreateArgumentsType arguments_type = static_cast(iterator->Next()); CreateArgumentsElementsTranslatedValues(frame_index, fp, arguments_type, @@ -703,7 +926,7 @@ int TranslatedState::CreateNextTranslatedValue( return 0; } - case Translation::ARGUMENTS_LENGTH: { + case TranslationOpcode::ARGUMENTS_LENGTH: { if (trace_file != nullptr) { PrintF(trace_file, "arguments length field (length = %d)", actual_argument_count_); @@ -712,7 +935,7 @@ int TranslatedState::CreateNextTranslatedValue( return 0; } - case Translation::CAPTURED_OBJECT: { + case TranslationOpcode::CAPTURED_OBJECT: { int field_count = iterator->Next(); int object_index = static_cast(object_positions_.size()); if (trace_file != nullptr) { @@ -726,7 +949,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::REGISTER: { + case TranslationOpcode::REGISTER: { int input_reg = iterator->Next(); if (registers == nullptr) { TranslatedValue translated_value = TranslatedValue::NewInvalid(this); @@ -746,7 +969,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::INT32_REGISTER: { + case TranslationOpcode::INT32_REGISTER: { int input_reg = iterator->Next(); if (registers == nullptr) { TranslatedValue translated_value = TranslatedValue::NewInvalid(this); @@ -764,7 +987,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::INT64_REGISTER: { + case TranslationOpcode::INT64_REGISTER: { int input_reg = iterator->Next(); if (registers == nullptr) { TranslatedValue translated_value = TranslatedValue::NewInvalid(this); @@ -782,7 +1005,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::UINT32_REGISTER: { + case TranslationOpcode::UINT32_REGISTER: { int input_reg = iterator->Next(); if (registers == nullptr) { TranslatedValue translated_value = TranslatedValue::NewInvalid(this); @@ -800,7 +1023,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::BOOL_REGISTER: { + case TranslationOpcode::BOOL_REGISTER: { int input_reg = iterator->Next(); if (registers == nullptr) { TranslatedValue translated_value = TranslatedValue::NewInvalid(this); @@ -818,7 +1041,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::FLOAT_REGISTER: { + case TranslationOpcode::FLOAT_REGISTER: { int input_reg = iterator->Next(); if (registers == nullptr) { TranslatedValue translated_value = TranslatedValue::NewInvalid(this); @@ -835,7 +1058,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::DOUBLE_REGISTER: { + case TranslationOpcode::DOUBLE_REGISTER: { int input_reg = iterator->Next(); if (registers == nullptr) { TranslatedValue translated_value = TranslatedValue::NewInvalid(this); @@ -853,7 +1076,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::STACK_SLOT: { + case TranslationOpcode::STACK_SLOT: { int slot_offset = OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); intptr_t value = *(reinterpret_cast(fp + slot_offset)); @@ -870,7 +1093,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::INT32_STACK_SLOT: { + case TranslationOpcode::INT32_STACK_SLOT: { int slot_offset = OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); uint32_t value = GetUInt32Slot(fp, slot_offset); @@ -884,7 +1107,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::INT64_STACK_SLOT: { + case TranslationOpcode::INT64_STACK_SLOT: { int slot_offset = OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); uint64_t value = GetUInt64Slot(fp, slot_offset); @@ -898,7 +1121,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::UINT32_STACK_SLOT: { + case TranslationOpcode::UINT32_STACK_SLOT: { int slot_offset = OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); uint32_t value = GetUInt32Slot(fp, slot_offset); @@ -912,7 +1135,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::BOOL_STACK_SLOT: { + case TranslationOpcode::BOOL_STACK_SLOT: { int slot_offset = OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); uint32_t value = GetUInt32Slot(fp, slot_offset); @@ -925,7 +1148,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::FLOAT_STACK_SLOT: { + case TranslationOpcode::FLOAT_STACK_SLOT: { int slot_offset = OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); Float32 value = GetFloatSlot(fp, slot_offset); @@ -938,7 +1161,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::DOUBLE_STACK_SLOT: { + case TranslationOpcode::DOUBLE_STACK_SLOT: { int slot_offset = OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next()); Float64 value = GetDoubleSlot(fp, slot_offset); @@ -952,7 +1175,7 @@ int TranslatedState::CreateNextTranslatedValue( return translated_value.GetChildrenCount(); } - case Translation::LITERAL: { + case TranslationOpcode::LITERAL: { int literal_index = iterator->Next(); Object value = literal_array.get(literal_index); if (trace_file != nullptr) { @@ -1009,9 +1232,8 @@ void TranslatedState::Init(Isolate* isolate, Address input_frame_pointer, isolate_ = isolate; // Read out the 'header' translation. - Translation::Opcode opcode = - static_cast(iterator->Next()); - CHECK(opcode == Translation::BEGIN); + TranslationOpcode opcode = TranslationOpcodeFromInt(iterator->Next()); + CHECK(opcode == TranslationOpcode::BEGIN); int count = iterator->Next(); frames_.reserve(count); @@ -1072,8 +1294,8 @@ void TranslatedState::Init(Isolate* isolate, Address input_frame_pointer, } } - CHECK(!iterator->HasNext() || static_cast( - iterator->Next()) == Translation::BEGIN); + CHECK(!iterator->HasNext() || + TranslationOpcodeFromInt(iterator->Next()) == TranslationOpcode::BEGIN); } void TranslatedState::Prepare(Address stack_frame_pointer) { @@ -1790,7 +2012,8 @@ bool TranslatedState::DoUpdateFeedback() { void TranslatedState::ReadUpdateFeedback(TranslationArrayIterator* iterator, FixedArray literal_array, FILE* trace_file) { - CHECK_EQ(Translation::UPDATE_FEEDBACK, iterator->Next()); + CHECK_EQ(TranslationOpcode::UPDATE_FEEDBACK, + TranslationOpcodeFromInt(iterator->Next())); feedback_vector_ = FeedbackVector::cast(literal_array.get(iterator->Next())); feedback_slot_ = FeedbackSlot(iterator->Next()); if (trace_file != nullptr) { diff --git a/src/deoptimizer/translated-state.h b/src/deoptimizer/translated-state.h index 253145d3d6..300fe54345 100644 --- a/src/deoptimizer/translated-state.h +++ b/src/deoptimizer/translated-state.h @@ -8,6 +8,7 @@ #include #include +#include "src/deoptimizer/translation-array.h" #include "src/objects/feedback-vector.h" #include "src/objects/heap-object.h" #include "src/objects/shared-function-info.h" @@ -19,7 +20,14 @@ namespace internal { class RegisterValues; class TranslatedState; -class TranslationArrayIterator; + +// TODO(jgruber): This duplicates decoding logic already present in +// TranslatedState/TranslatedFrame. Deduplicate into one class, e.g. by basing +// printing off TranslatedFrame. +void TranslationArrayPrintSingleFrame(std::ostream& os, + TranslationArray translation_array, + int translation_index, + FixedArray literal_array); // The Translated{Value,Frame,State} class hierarchy are a set of utility // functions to work with the combination of translations (built from a diff --git a/src/deoptimizer/translation-array.cc b/src/deoptimizer/translation-array.cc index 4320158952..584a83dc11 100644 --- a/src/deoptimizer/translation-array.cc +++ b/src/deoptimizer/translation-array.cc @@ -35,5 +35,235 @@ bool TranslationArrayIterator::HasNext() const { return index_ < buffer_.length(); } +void TranslationArrayBuilder::Add(int32_t value) { + // This wouldn't handle kMinInt correctly if it ever encountered it. + DCHECK_NE(value, kMinInt); + // Encode the sign bit in the least significant bit. + bool is_negative = (value < 0); + uint32_t bits = (static_cast(is_negative ? -value : value) << 1) | + static_cast(is_negative); + // Encode the individual bytes using the least significant bit of + // each byte to indicate whether or not more bytes follow. + do { + uint32_t next = bits >> 7; + contents_.push_back(((bits << 1) & 0xFF) | (next != 0)); + bits = next; + } while (bits != 0); +} + +Handle TranslationArrayBuilder::ToTranslationArray( + Factory* factory) { + Handle result = + factory->NewByteArray(Size(), AllocationType::kOld); + contents_.CopyTo(result->GetDataStartAddress()); + return result; +} + +void TranslationArrayBuilder::BeginBuiltinContinuationFrame( + BytecodeOffset bytecode_offset, int literal_id, unsigned height) { + auto opcode = TranslationOpcode::BUILTIN_CONTINUATION_FRAME; + Add(opcode); + Add(bytecode_offset.ToInt()); + Add(literal_id); + Add(height); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 3); +} + +void TranslationArrayBuilder::BeginJavaScriptBuiltinContinuationFrame( + BytecodeOffset bytecode_offset, int literal_id, unsigned height) { + auto opcode = TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME; + Add(opcode); + Add(bytecode_offset.ToInt()); + Add(literal_id); + Add(height); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 3); +} + +void TranslationArrayBuilder::BeginJavaScriptBuiltinContinuationWithCatchFrame( + BytecodeOffset bytecode_offset, int literal_id, unsigned height) { + auto opcode = + TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME; + Add(opcode); + Add(bytecode_offset.ToInt()); + Add(literal_id); + Add(height); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 3); +} + +void TranslationArrayBuilder::BeginConstructStubFrame( + BytecodeOffset bytecode_offset, int literal_id, unsigned height) { + auto opcode = TranslationOpcode::CONSTRUCT_STUB_FRAME; + Add(opcode); + Add(bytecode_offset.ToInt()); + Add(literal_id); + Add(height); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 3); +} + +void TranslationArrayBuilder::BeginArgumentsAdaptorFrame(int literal_id, + unsigned height) { + auto opcode = TranslationOpcode::ARGUMENTS_ADAPTOR_FRAME; + Add(opcode); + Add(literal_id); + Add(height); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 2); +} + +void TranslationArrayBuilder::BeginInterpretedFrame( + BytecodeOffset bytecode_offset, int literal_id, unsigned height, + int return_value_offset, int return_value_count) { + auto opcode = TranslationOpcode::INTERPRETED_FRAME; + Add(opcode); + Add(bytecode_offset.ToInt()); + Add(literal_id); + Add(height); + Add(return_value_offset); + Add(return_value_count); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 5); +} + +void TranslationArrayBuilder::ArgumentsElements(CreateArgumentsType type) { + auto opcode = TranslationOpcode::ARGUMENTS_ELEMENTS; + Add(opcode); + Add(static_cast(type)); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::ArgumentsLength() { + auto opcode = TranslationOpcode::ARGUMENTS_LENGTH; + Add(opcode); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 0); +} + +void TranslationArrayBuilder::BeginCapturedObject(int length) { + auto opcode = TranslationOpcode::CAPTURED_OBJECT; + Add(opcode); + Add(length); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::DuplicateObject(int object_index) { + auto opcode = TranslationOpcode::DUPLICATED_OBJECT; + Add(opcode); + Add(object_index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreRegister(Register reg) { + auto opcode = TranslationOpcode::REGISTER; + Add(opcode); + Add(reg.code()); +} + +void TranslationArrayBuilder::StoreInt32Register(Register reg) { + auto opcode = TranslationOpcode::INT32_REGISTER; + Add(opcode); + Add(reg.code()); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreInt64Register(Register reg) { + auto opcode = TranslationOpcode::INT64_REGISTER; + Add(opcode); + Add(reg.code()); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreUint32Register(Register reg) { + auto opcode = TranslationOpcode::UINT32_REGISTER; + Add(opcode); + Add(reg.code()); +} + +void TranslationArrayBuilder::StoreBoolRegister(Register reg) { + auto opcode = TranslationOpcode::BOOL_REGISTER; + Add(opcode); + Add(reg.code()); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreFloatRegister(FloatRegister reg) { + auto opcode = TranslationOpcode::FLOAT_REGISTER; + Add(opcode); + Add(reg.code()); +} + +void TranslationArrayBuilder::StoreDoubleRegister(DoubleRegister reg) { + auto opcode = TranslationOpcode::DOUBLE_REGISTER; + Add(opcode); + Add(reg.code()); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreStackSlot(int index) { + auto opcode = TranslationOpcode::STACK_SLOT; + Add(opcode); + Add(index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreInt32StackSlot(int index) { + auto opcode = TranslationOpcode::INT32_STACK_SLOT; + Add(opcode); + Add(index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreInt64StackSlot(int index) { + auto opcode = TranslationOpcode::INT64_STACK_SLOT; + Add(opcode); + Add(index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreUint32StackSlot(int index) { + auto opcode = TranslationOpcode::UINT32_STACK_SLOT; + Add(opcode); + Add(index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreBoolStackSlot(int index) { + auto opcode = TranslationOpcode::BOOL_STACK_SLOT; + Add(opcode); + Add(index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreFloatStackSlot(int index) { + auto opcode = TranslationOpcode::FLOAT_STACK_SLOT; + Add(opcode); + Add(index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreDoubleStackSlot(int index) { + auto opcode = TranslationOpcode::DOUBLE_STACK_SLOT; + Add(opcode); + Add(index); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::StoreLiteral(int literal_id) { + auto opcode = TranslationOpcode::LITERAL; + Add(opcode); + Add(literal_id); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 1); +} + +void TranslationArrayBuilder::AddUpdateFeedback(int vector_literal, int slot) { + auto opcode = TranslationOpcode::UPDATE_FEEDBACK; + Add(opcode); + Add(vector_literal); + Add(slot); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 2); +} + +void TranslationArrayBuilder::StoreJSFrameFunction() { + StoreStackSlot((StandardFrameConstants::kCallerPCOffset - + StandardFrameConstants::kFunctionOffset) / + kSystemPointerSize); +} + } // namespace internal } // namespace v8 diff --git a/src/deoptimizer/translation-array.h b/src/deoptimizer/translation-array.h index 9ebeff909b..259846e784 100644 --- a/src/deoptimizer/translation-array.h +++ b/src/deoptimizer/translation-array.h @@ -5,13 +5,19 @@ #ifndef V8_DEOPTIMIZER_TRANSLATION_ARRAY_H_ #define V8_DEOPTIMIZER_TRANSLATION_ARRAY_H_ +#include "src/codegen/register-arch.h" +#include "src/deoptimizer/translation-opcode.h" #include "src/objects/fixed-array.h" +#include "src/wasm/value-type.h" +#include "src/zone/zone-chunk-list.h" namespace v8 { namespace internal { +class Factory; + // The TranslationArray is the on-heap representation of translations created -// during code generation in a (zone-allocated) TranslationBuffer. The +// during code generation in a (zone-allocated) TranslationArrayBuilder. The // translation array specifies how to transform an optimized frame back into // one or more unoptimized frames. // TODO(jgruber): Consider a real type instead of this type alias. @@ -34,6 +40,73 @@ class TranslationArrayIterator { int index_; }; +class TranslationArrayBuilder { + public: + explicit TranslationArrayBuilder(Zone* zone) : contents_(zone), zone_(zone) {} + + int Size() const { return static_cast(contents_.size()); } + + Handle ToTranslationArray(Factory* factory); + + int BeginTranslation(int frame_count, int jsframe_count, + int update_feedback_count) { + int start_index = Size(); + auto opcode = TranslationOpcode::BEGIN; + Add(opcode); + Add(frame_count); + Add(jsframe_count); + Add(update_feedback_count); + DCHECK_EQ(TranslationOpcodeOperandCount(opcode), 3); + return start_index; + } + + void BeginInterpretedFrame(BytecodeOffset bytecode_offset, int literal_id, + unsigned height, int return_value_offset, + int return_value_count); + void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); + void BeginConstructStubFrame(BytecodeOffset bailout_id, int literal_id, + unsigned height); + void BeginBuiltinContinuationFrame(BytecodeOffset bailout_id, int literal_id, + unsigned height); + void BeginJSToWasmBuiltinContinuationFrame( + BytecodeOffset bailout_id, int literal_id, unsigned height, + base::Optional return_type); + void BeginJavaScriptBuiltinContinuationFrame(BytecodeOffset bailout_id, + int literal_id, unsigned height); + void BeginJavaScriptBuiltinContinuationWithCatchFrame( + BytecodeOffset bailout_id, int literal_id, unsigned height); + void ArgumentsElements(CreateArgumentsType type); + void ArgumentsLength(); + void BeginCapturedObject(int length); + void AddUpdateFeedback(int vector_literal, int slot); + void DuplicateObject(int object_index); + void StoreRegister(Register reg); + void StoreInt32Register(Register reg); + void StoreInt64Register(Register reg); + void StoreUint32Register(Register reg); + void StoreBoolRegister(Register reg); + void StoreFloatRegister(FloatRegister reg); + void StoreDoubleRegister(DoubleRegister reg); + void StoreStackSlot(int index); + void StoreInt32StackSlot(int index); + void StoreInt64StackSlot(int index); + void StoreUint32StackSlot(int index); + void StoreBoolStackSlot(int index); + void StoreFloatStackSlot(int index); + void StoreDoubleStackSlot(int index); + void StoreLiteral(int literal_id); + void StoreJSFrameFunction(); + + private: + void Add(int32_t value); + void Add(TranslationOpcode opcode) { Add(static_cast(opcode)); } + + Zone* zone() const { return zone_; } + + ZoneChunkList contents_; + Zone* const zone_; +}; + } // namespace internal } // namespace v8 diff --git a/src/deoptimizer/translation-opcode.h b/src/deoptimizer/translation-opcode.h new file mode 100644 index 0000000000..3bccd14cc5 --- /dev/null +++ b/src/deoptimizer/translation-opcode.h @@ -0,0 +1,70 @@ +// Copyright 2021 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_DEOPTIMIZER_TRANSLATION_OPCODE_H_ +#define V8_DEOPTIMIZER_TRANSLATION_OPCODE_H_ + +namespace v8 { +namespace internal { + +// V(name, operand_count) +#define TRANSLATION_OPCODE_LIST(V) \ + V(ARGUMENTS_ADAPTOR_FRAME, 2) \ + V(ARGUMENTS_ELEMENTS, 1) \ + V(ARGUMENTS_LENGTH, 0) \ + V(BEGIN, 3) \ + V(BOOL_REGISTER, 1) \ + V(BOOL_STACK_SLOT, 1) \ + V(BUILTIN_CONTINUATION_FRAME, 3) \ + V(CAPTURED_OBJECT, 1) \ + V(CONSTRUCT_STUB_FRAME, 3) \ + V(DOUBLE_REGISTER, 1) \ + V(DOUBLE_STACK_SLOT, 1) \ + V(DUPLICATED_OBJECT, 1) \ + V(FLOAT_REGISTER, 1) \ + V(FLOAT_STACK_SLOT, 1) \ + V(INT32_REGISTER, 1) \ + V(INT32_STACK_SLOT, 1) \ + V(INT64_REGISTER, 1) \ + V(INT64_STACK_SLOT, 1) \ + V(INTERPRETED_FRAME, 5) \ + V(JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME, 3) \ + V(JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME, 3) \ + V(LITERAL, 1) \ + V(REGISTER, 1) \ + V(STACK_SLOT, 1) \ + V(UINT32_REGISTER, 1) \ + V(UINT32_STACK_SLOT, 1) \ + V(UPDATE_FEEDBACK, 2) + +enum class TranslationOpcode { +#define CASE(name, ...) name, + TRANSLATION_OPCODE_LIST(CASE) +#undef CASE +}; + +constexpr TranslationOpcode TranslationOpcodeFromInt(int i) { + return static_cast(i); +} + +inline int TranslationOpcodeOperandCount(TranslationOpcode o) { +#define CASE(name, operand_count) operand_count, + static const int counts[] = {TRANSLATION_OPCODE_LIST(CASE)}; +#undef CASE + return counts[static_cast(o)]; +} + +inline const char* TranslationOpcodeToString(TranslationOpcode o) { +#define CASE(name, ...) #name, + static const char* const names[] = {TRANSLATION_OPCODE_LIST(CASE)}; +#undef CASE + return names[static_cast(o)]; +} + +#undef TRANSLATION_OPCODE_LIST + +} // namespace internal +} // namespace v8 + +#endif // V8_DEOPTIMIZER_TRANSLATION_OPCODE_H_ diff --git a/src/deoptimizer/translations.cc b/src/deoptimizer/translations.cc deleted file mode 100644 index b4e39aa9af..0000000000 --- a/src/deoptimizer/translations.cc +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2021 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/deoptimizer/translations.h" - -#include "src/execution/frames.h" -#include "src/execution/isolate.h" -#include "src/heap/factory.h" -#include "src/objects/fixed-array-inl.h" -#include "src/objects/oddball.h" - -namespace v8 { -namespace internal { - -void TranslationBuffer::Add(int32_t value) { - // This wouldn't handle kMinInt correctly if it ever encountered it. - DCHECK_NE(value, kMinInt); - // Encode the sign bit in the least significant bit. - bool is_negative = (value < 0); - uint32_t bits = (static_cast(is_negative ? -value : value) << 1) | - static_cast(is_negative); - // Encode the individual bytes using the least significant bit of - // each byte to indicate whether or not more bytes follow. - do { - uint32_t next = bits >> 7; - contents_.push_back(((bits << 1) & 0xFF) | (next != 0)); - bits = next; - } while (bits != 0); -} - -Handle TranslationBuffer::CreateByteArray(Factory* factory) { - Handle result = - factory->NewByteArray(CurrentIndex(), AllocationType::kOld); - contents_.CopyTo(result->GetDataStartAddress()); - return result; -} - -void Translation::BeginBuiltinContinuationFrame(BytecodeOffset bytecode_offset, - int literal_id, - unsigned height) { - buffer_->Add(BUILTIN_CONTINUATION_FRAME); - buffer_->Add(bytecode_offset.ToInt()); - buffer_->Add(literal_id); - buffer_->Add(height); -} - -void Translation::BeginJavaScriptBuiltinContinuationFrame( - BytecodeOffset bytecode_offset, int literal_id, unsigned height) { - buffer_->Add(JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME); - buffer_->Add(bytecode_offset.ToInt()); - buffer_->Add(literal_id); - buffer_->Add(height); -} - -void Translation::BeginJavaScriptBuiltinContinuationWithCatchFrame( - BytecodeOffset bytecode_offset, int literal_id, unsigned height) { - buffer_->Add(JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME); - buffer_->Add(bytecode_offset.ToInt()); - buffer_->Add(literal_id); - buffer_->Add(height); -} - -void Translation::BeginConstructStubFrame(BytecodeOffset bytecode_offset, - int literal_id, unsigned height) { - buffer_->Add(CONSTRUCT_STUB_FRAME); - buffer_->Add(bytecode_offset.ToInt()); - buffer_->Add(literal_id); - buffer_->Add(height); -} - -void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) { - buffer_->Add(ARGUMENTS_ADAPTOR_FRAME); - buffer_->Add(literal_id); - buffer_->Add(height); -} - -void Translation::BeginInterpretedFrame(BytecodeOffset bytecode_offset, - int literal_id, unsigned height, - int return_value_offset, - int return_value_count) { - buffer_->Add(INTERPRETED_FRAME); - buffer_->Add(bytecode_offset.ToInt()); - buffer_->Add(literal_id); - buffer_->Add(height); - buffer_->Add(return_value_offset); - buffer_->Add(return_value_count); -} - -void Translation::ArgumentsElements(CreateArgumentsType type) { - buffer_->Add(ARGUMENTS_ELEMENTS); - buffer_->Add(static_cast(type)); -} - -void Translation::ArgumentsLength() { buffer_->Add(ARGUMENTS_LENGTH); } - -void Translation::BeginCapturedObject(int length) { - buffer_->Add(CAPTURED_OBJECT); - buffer_->Add(length); -} - -void Translation::DuplicateObject(int object_index) { - buffer_->Add(DUPLICATED_OBJECT); - buffer_->Add(object_index); -} - -void Translation::StoreRegister(Register reg) { - buffer_->Add(REGISTER); - buffer_->Add(reg.code()); -} - -void Translation::StoreInt32Register(Register reg) { - buffer_->Add(INT32_REGISTER); - buffer_->Add(reg.code()); -} - -void Translation::StoreInt64Register(Register reg) { - buffer_->Add(INT64_REGISTER); - buffer_->Add(reg.code()); -} - -void Translation::StoreUint32Register(Register reg) { - buffer_->Add(UINT32_REGISTER); - buffer_->Add(reg.code()); -} - -void Translation::StoreBoolRegister(Register reg) { - buffer_->Add(BOOL_REGISTER); - buffer_->Add(reg.code()); -} - -void Translation::StoreFloatRegister(FloatRegister reg) { - buffer_->Add(FLOAT_REGISTER); - buffer_->Add(reg.code()); -} - -void Translation::StoreDoubleRegister(DoubleRegister reg) { - buffer_->Add(DOUBLE_REGISTER); - buffer_->Add(reg.code()); -} - -void Translation::StoreStackSlot(int index) { - buffer_->Add(STACK_SLOT); - buffer_->Add(index); -} - -void Translation::StoreInt32StackSlot(int index) { - buffer_->Add(INT32_STACK_SLOT); - buffer_->Add(index); -} - -void Translation::StoreInt64StackSlot(int index) { - buffer_->Add(INT64_STACK_SLOT); - buffer_->Add(index); -} - -void Translation::StoreUint32StackSlot(int index) { - buffer_->Add(UINT32_STACK_SLOT); - buffer_->Add(index); -} - -void Translation::StoreBoolStackSlot(int index) { - buffer_->Add(BOOL_STACK_SLOT); - buffer_->Add(index); -} - -void Translation::StoreFloatStackSlot(int index) { - buffer_->Add(FLOAT_STACK_SLOT); - buffer_->Add(index); -} - -void Translation::StoreDoubleStackSlot(int index) { - buffer_->Add(DOUBLE_STACK_SLOT); - buffer_->Add(index); -} - -void Translation::StoreLiteral(int literal_id) { - buffer_->Add(LITERAL); - buffer_->Add(literal_id); -} - -void Translation::AddUpdateFeedback(int vector_literal, int slot) { - buffer_->Add(UPDATE_FEEDBACK); - buffer_->Add(vector_literal); - buffer_->Add(slot); -} - -void Translation::StoreJSFrameFunction() { - StoreStackSlot((StandardFrameConstants::kCallerPCOffset - - StandardFrameConstants::kFunctionOffset) / - kSystemPointerSize); -} - -int Translation::NumberOfOperandsFor(Opcode opcode) { - switch (opcode) { - case ARGUMENTS_LENGTH: - return 0; - case DUPLICATED_OBJECT: - case ARGUMENTS_ELEMENTS: - case CAPTURED_OBJECT: - case REGISTER: - case INT32_REGISTER: - case INT64_REGISTER: - case UINT32_REGISTER: - case BOOL_REGISTER: - case FLOAT_REGISTER: - case DOUBLE_REGISTER: - case STACK_SLOT: - case INT32_STACK_SLOT: - case INT64_STACK_SLOT: - case UINT32_STACK_SLOT: - case BOOL_STACK_SLOT: - case FLOAT_STACK_SLOT: - case DOUBLE_STACK_SLOT: - case LITERAL: - return 1; - case ARGUMENTS_ADAPTOR_FRAME: - case UPDATE_FEEDBACK: - return 2; - case BEGIN: - case CONSTRUCT_STUB_FRAME: - case BUILTIN_CONTINUATION_FRAME: - case JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: - case JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: - return 3; - case INTERPRETED_FRAME: - return 5; - } - FATAL("Unexpected translation type"); - return -1; -} - -#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) - -const char* Translation::StringFor(Opcode opcode) { -#define TRANSLATION_OPCODE_CASE(item) \ - case item: \ - return #item; - switch (opcode) { TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE) } -#undef TRANSLATION_OPCODE_CASE - UNREACHABLE(); -} - -#endif - -} // namespace internal -} // namespace v8 diff --git a/src/deoptimizer/translations.h b/src/deoptimizer/translations.h deleted file mode 100644 index cbd846d577..0000000000 --- a/src/deoptimizer/translations.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2021 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_DEOPTIMIZER_TRANSLATIONS_H_ -#define V8_DEOPTIMIZER_TRANSLATIONS_H_ - -#include -#include - -#include "src/builtins/builtins.h" -#include "src/codegen/register-arch.h" -#include "src/deoptimizer/translated-state.h" -#include "src/objects/fixed-array.h" -#include "src/wasm/value-type.h" -#include "src/zone/zone-chunk-list.h" - -namespace v8 { -namespace internal { - -class Factory; - -class TranslationBuffer { - public: - explicit TranslationBuffer(Zone* zone) : contents_(zone) {} - - int CurrentIndex() const { return static_cast(contents_.size()); } - void Add(int32_t value); - - Handle CreateByteArray(Factory* factory); - - private: - ZoneChunkList contents_; -}; - -#define TRANSLATION_OPCODE_LIST(V) \ - V(BEGIN) \ - V(INTERPRETED_FRAME) \ - V(BUILTIN_CONTINUATION_FRAME) \ - V(JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME) \ - V(JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) \ - V(CONSTRUCT_STUB_FRAME) \ - V(ARGUMENTS_ADAPTOR_FRAME) \ - V(DUPLICATED_OBJECT) \ - V(ARGUMENTS_ELEMENTS) \ - V(ARGUMENTS_LENGTH) \ - V(CAPTURED_OBJECT) \ - V(REGISTER) \ - V(INT32_REGISTER) \ - V(INT64_REGISTER) \ - V(UINT32_REGISTER) \ - V(BOOL_REGISTER) \ - V(FLOAT_REGISTER) \ - V(DOUBLE_REGISTER) \ - V(STACK_SLOT) \ - V(INT32_STACK_SLOT) \ - V(INT64_STACK_SLOT) \ - V(UINT32_STACK_SLOT) \ - V(BOOL_STACK_SLOT) \ - V(FLOAT_STACK_SLOT) \ - V(DOUBLE_STACK_SLOT) \ - V(LITERAL) \ - V(UPDATE_FEEDBACK) - -class Translation { - public: -#define DECLARE_TRANSLATION_OPCODE_ENUM(item) item, - enum Opcode { - TRANSLATION_OPCODE_LIST(DECLARE_TRANSLATION_OPCODE_ENUM) LAST = LITERAL - }; -#undef DECLARE_TRANSLATION_OPCODE_ENUM - - Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count, - int update_feedback_count, Zone* zone) - : buffer_(buffer), index_(buffer->CurrentIndex()), zone_(zone) { - buffer_->Add(BEGIN); - buffer_->Add(frame_count); - buffer_->Add(jsframe_count); - buffer_->Add(update_feedback_count); - } - - int index() const { return index_; } - - // Commands. - void BeginInterpretedFrame(BytecodeOffset bytecode_offset, int literal_id, - unsigned height, int return_value_offset, - int return_value_count); - void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); - void BeginConstructStubFrame(BytecodeOffset bailout_id, int literal_id, - unsigned height); - void BeginBuiltinContinuationFrame(BytecodeOffset bailout_id, int literal_id, - unsigned height); - void BeginJavaScriptBuiltinContinuationFrame(BytecodeOffset bailout_id, - int literal_id, unsigned height); - void BeginJavaScriptBuiltinContinuationWithCatchFrame( - BytecodeOffset bailout_id, int literal_id, unsigned height); - void ArgumentsElements(CreateArgumentsType type); - void ArgumentsLength(); - void BeginCapturedObject(int length); - void AddUpdateFeedback(int vector_literal, int slot); - void DuplicateObject(int object_index); - void StoreRegister(Register reg); - void StoreInt32Register(Register reg); - void StoreInt64Register(Register reg); - void StoreUint32Register(Register reg); - void StoreBoolRegister(Register reg); - void StoreFloatRegister(FloatRegister reg); - void StoreDoubleRegister(DoubleRegister reg); - void StoreStackSlot(int index); - void StoreInt32StackSlot(int index); - void StoreInt64StackSlot(int index); - void StoreUint32StackSlot(int index); - void StoreBoolStackSlot(int index); - void StoreFloatStackSlot(int index); - void StoreDoubleStackSlot(int index); - void StoreLiteral(int literal_id); - void StoreJSFrameFunction(); - - Zone* zone() const { return zone_; } - - static int NumberOfOperandsFor(Opcode opcode); - -#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) - static const char* StringFor(Opcode opcode); -#endif - - private: - TranslationBuffer* buffer_; - int index_; - Zone* zone_; -}; - -} // namespace internal -} // namespace v8 - -#endif // V8_DEOPTIMIZER_TRANSLATIONS_H_ diff --git a/src/execution/frames.cc b/src/execution/frames.cc index bb7343ff68..fcec14ffb3 100644 --- a/src/execution/frames.cc +++ b/src/execution/frames.cc @@ -1644,8 +1644,8 @@ void OptimizedFrame::GetFunctions( TranslationArrayIterator it(data.TranslationByteArray(), data.TranslationIndex(deopt_index).value()); - Translation::Opcode opcode = static_cast(it.Next()); - DCHECK_EQ(Translation::BEGIN, opcode); + TranslationOpcode opcode = TranslationOpcodeFromInt(it.Next()); + DCHECK_EQ(TranslationOpcode::BEGIN, opcode); it.Next(); // Skip frame count. int jsframe_count = it.Next(); it.Next(); // Skip update feedback count. @@ -1653,11 +1653,11 @@ void OptimizedFrame::GetFunctions( // 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(it.Next()); - if (opcode == Translation::INTERPRETED_FRAME || - opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME || - opcode == - Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) { + opcode = TranslationOpcodeFromInt(it.Next()); + if (opcode == TranslationOpcode::INTERPRETED_FRAME || + opcode == TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME || + opcode == TranslationOpcode:: + JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) { it.Next(); // Skip bailout id. jsframe_count--; @@ -1666,10 +1666,10 @@ void OptimizedFrame::GetFunctions( functions->push_back(SharedFunctionInfo::cast(shared)); // Skip over remaining operands to advance to the next opcode. - it.Skip(Translation::NumberOfOperandsFor(opcode) - 2); + it.Skip(TranslationOpcodeOperandCount(opcode) - 2); } else { // Skip over operands to advance to the next opcode. - it.Skip(Translation::NumberOfOperandsFor(opcode)); + it.Skip(TranslationOpcodeOperandCount(opcode)); } } } diff --git a/src/objects/code.cc b/src/objects/code.cc index d1bee59e1b..a451346e6b 100644 --- a/src/objects/code.cc +++ b/src/objects/code.cc @@ -441,7 +441,6 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT return; } - disasm::NameConverter converter; int const inlined_function_count = InlinedFunctionCount().value(); os << "Inlined functions (count = " << inlined_function_count << ")\n"; for (int id = 0; id < inlined_function_count; ++id) { @@ -467,203 +466,9 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT continue; } - // Print details of the frame translation. - int translation_index = TranslationIndex(i).value(); - TranslationArrayIterator iterator(TranslationByteArray(), - translation_index); - Translation::Opcode opcode = - static_cast(iterator.Next()); - DCHECK(Translation::BEGIN == opcode); - int frame_count = iterator.Next(); - int jsframe_count = iterator.Next(); - int update_feedback_count = iterator.Next(); - os << " " << Translation::StringFor(opcode) - << " {frame count=" << frame_count - << ", js frame count=" << jsframe_count - << ", update_feedback_count=" << update_feedback_count << "}\n"; - - while (iterator.HasNext() && - Translation::BEGIN != - (opcode = static_cast(iterator.Next()))) { - os << std::setw(31) << " " << Translation::StringFor(opcode) << " "; - - switch (opcode) { - case Translation::BEGIN: - UNREACHABLE(); - break; - - case Translation::INTERPRETED_FRAME: { - int bytecode_offset = iterator.Next(); - int shared_info_id = iterator.Next(); - unsigned height = iterator.Next(); - int return_value_offset = iterator.Next(); - int return_value_count = iterator.Next(); - Object shared_info = LiteralArray().get(shared_info_id); - os << "{bytecode_offset=" << bytecode_offset << ", function=" - << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() - << ", height=" << height << ", retval=@" << return_value_offset - << "(#" << return_value_count << ")}"; - break; - } - - case Translation::CONSTRUCT_STUB_FRAME: { - int bailout_id = iterator.Next(); - int shared_info_id = iterator.Next(); - Object shared_info = LiteralArray().get(shared_info_id); - unsigned height = iterator.Next(); - os << "{bailout_id=" << bailout_id << ", function=" - << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() - << ", height=" << height << "}"; - break; - } - - case Translation::BUILTIN_CONTINUATION_FRAME: - case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: - case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME: { - int bailout_id = iterator.Next(); - int shared_info_id = iterator.Next(); - Object shared_info = LiteralArray().get(shared_info_id); - unsigned height = iterator.Next(); - os << "{bailout_id=" << bailout_id << ", function=" - << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() - << ", height=" << height << "}"; - break; - } - - case Translation::ARGUMENTS_ADAPTOR_FRAME: { - int shared_info_id = iterator.Next(); - Object shared_info = LiteralArray().get(shared_info_id); - unsigned height = iterator.Next(); - os << "{function=" - << SharedFunctionInfo::cast(shared_info).DebugNameCStr().get() - << ", height=" << height << "}"; - break; - } - - case Translation::REGISTER: { - int reg_code = iterator.Next(); - os << "{input=" << converter.NameOfCPURegister(reg_code) << "}"; - break; - } - - case Translation::INT32_REGISTER: { - int reg_code = iterator.Next(); - os << "{input=" << converter.NameOfCPURegister(reg_code) - << " (int32)}"; - break; - } - - case Translation::INT64_REGISTER: { - int reg_code = iterator.Next(); - os << "{input=" << converter.NameOfCPURegister(reg_code) - << " (int64)}"; - break; - } - - case Translation::UINT32_REGISTER: { - int reg_code = iterator.Next(); - os << "{input=" << converter.NameOfCPURegister(reg_code) - << " (uint32)}"; - break; - } - - case Translation::BOOL_REGISTER: { - int reg_code = iterator.Next(); - os << "{input=" << converter.NameOfCPURegister(reg_code) - << " (bool)}"; - break; - } - - case Translation::FLOAT_REGISTER: { - int reg_code = iterator.Next(); - os << "{input=" << FloatRegister::from_code(reg_code) << "}"; - break; - } - - case Translation::DOUBLE_REGISTER: { - int reg_code = iterator.Next(); - os << "{input=" << DoubleRegister::from_code(reg_code) << "}"; - break; - } - - case Translation::STACK_SLOT: { - int input_slot_index = iterator.Next(); - os << "{input=" << input_slot_index << "}"; - break; - } - - case Translation::INT32_STACK_SLOT: { - int input_slot_index = iterator.Next(); - os << "{input=" << input_slot_index << " (int32)}"; - break; - } - - case Translation::INT64_STACK_SLOT: { - int input_slot_index = iterator.Next(); - os << "{input=" << input_slot_index << " (int64)}"; - break; - } - - case Translation::UINT32_STACK_SLOT: { - int input_slot_index = iterator.Next(); - os << "{input=" << input_slot_index << " (uint32)}"; - break; - } - - case Translation::BOOL_STACK_SLOT: { - int input_slot_index = iterator.Next(); - os << "{input=" << input_slot_index << " (bool)}"; - break; - } - - case Translation::FLOAT_STACK_SLOT: - case Translation::DOUBLE_STACK_SLOT: { - int input_slot_index = iterator.Next(); - os << "{input=" << input_slot_index << "}"; - break; - } - - case Translation::LITERAL: { - int literal_index = iterator.Next(); - Object literal_value = LiteralArray().get(literal_index); - os << "{literal_id=" << literal_index << " (" << Brief(literal_value) - << ")}"; - break; - } - - case Translation::DUPLICATED_OBJECT: { - int object_index = iterator.Next(); - os << "{object_index=" << object_index << "}"; - break; - } - - case Translation::ARGUMENTS_ELEMENTS: { - CreateArgumentsType arguments_type = - static_cast(iterator.Next()); - os << "{arguments_type=" << arguments_type << "}"; - break; - } - case Translation::ARGUMENTS_LENGTH: { - os << "{arguments_length}"; - break; - } - - case Translation::CAPTURED_OBJECT: { - int args_length = iterator.Next(); - os << "{length=" << args_length << "}"; - break; - } - - case Translation::UPDATE_FEEDBACK: { - int literal_index = iterator.Next(); - FeedbackSlot slot(iterator.Next()); - os << "{feedback={vector_index=" << literal_index << ", slot=" << slot - << "}}"; - break; - } - } - os << "\n"; - } + TranslationArrayPrintSingleFrame(os, TranslationByteArray(), + TranslationIndex(i).value(), + LiteralArray()); } }