Commit 957d872b authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[deoptimizer] Refactor translation opcodes and array builder

The final CL of this chain, this extracts translation opcodes into the
TranslationOpcode class, and merges logic for TranslationArray
creation into TranslationArrayBuilder.

Drive-by: Pull TranslationArray printing logic into
translation-state.cc.

Bug: v8:11332
Change-Id: Ia4bbb6cdd15ea3318dfb9b7edb6eb881530dda54
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2642254
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72278}
parent 107629d1
......@@ -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",
......
......@@ -985,8 +985,8 @@ Handle<DeoptimizationData> CodeGenerator::GenerateDeoptimizationData() {
Handle<DeoptimizationData> data =
DeoptimizationData::New(isolate(), deopt_count, AllocationType::kOld);
Handle<ByteArray> translation_array =
translations_.CreateByteArray(isolate()->factory());
Handle<TranslationArray> 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<int>(nested->size()));
}
translations_.BeginCapturedObject(static_cast<int>(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<int>(desc->id()));
}
translations_.DuplicateObject(static_cast<int>(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<SharedFunctionInfo> shared_info;
......@@ -1178,35 +1161,35 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
return_offset = static_cast<int>(state_combine.GetOffsetToPokeAt());
return_count = static_cast<int>(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<int>(descriptor->GetFrameCount()),
static_cast<int>(descriptor->GetJSFrameCount()),
update_feedback_count, zone());
const int update_feedback_count = entry.feedback().IsValid() ? 1 : 0;
const int translation_index = translations_.BeginTranslation(
static_cast<int>(descriptor->GetFrameCount()),
static_cast<int>(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<DeoptimizationExit>(
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);
}
}
}
......
......@@ -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<DeoptimizationExit*>* exits);
......@@ -444,7 +442,7 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
ZoneDeque<DeoptimizationLiteral> deoptimization_literals_;
size_t inlined_function_count_ = 0;
TranslationBuffer translations_;
TranslationArrayBuilder translations_;
int handler_table_offset_ = 0;
int last_lazy_deopt_pc_ = 0;
......
......@@ -7,7 +7,7 @@
#include <vector>
#include "src/deoptimizer/translations.h"
#include "src/deoptimizer/translated-state.h"
namespace v8 {
namespace internal {
......
......@@ -7,10 +7,11 @@
#include <vector>
#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"
......
......@@ -4,10 +4,12 @@
#include "src/deoptimizer/translated-state.h"
#include <iomanip>
#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<CreateArgumentsType>(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<Translation::Opcode>(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<int>(frame.values_.size());
Translation::Opcode opcode =
static_cast<Translation::Opcode>(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<CreateArgumentsType>(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<int>(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<intptr_t*>(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<Translation::Opcode>(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<Translation::Opcode>(
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) {
......
......@@ -8,6 +8,7 @@
#include <stack>
#include <vector>
#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
......
......@@ -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<uint32_t>(is_negative ? -value : value) << 1) |
static_cast<uint32_t>(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<TranslationArray> TranslationArrayBuilder::ToTranslationArray(
Factory* factory) {
Handle<TranslationArray> 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<uint8_t>(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
......@@ -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<int>(contents_.size()); }
Handle<TranslationArray> 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<wasm::ValueType::Kind> 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<int32_t>(opcode)); }
Zone* zone() const { return zone_; }
ZoneChunkList<uint8_t> contents_;
Zone* const zone_;
};
} // namespace internal
} // namespace v8
......
// 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<TranslationOpcode>(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<int>(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<int>(o)];
}
#undef TRANSLATION_OPCODE_LIST
} // namespace internal
} // namespace v8
#endif // V8_DEOPTIMIZER_TRANSLATION_OPCODE_H_
// 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<uint32_t>(is_negative ? -value : value) << 1) |
static_cast<uint32_t>(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<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
Handle<ByteArray> 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<uint8_t>(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
// 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 <stack>
#include <vector>
#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<int>(contents_.size()); }
void Add(int32_t value);
Handle<ByteArray> CreateByteArray(Factory* factory);
private:
ZoneChunkList<uint8_t> 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_
......@@ -1644,8 +1644,8 @@ void OptimizedFrame::GetFunctions(
TranslationArrayIterator it(data.TranslationByteArray(),
data.TranslationIndex(deopt_index).value());
Translation::Opcode opcode = static_cast<Translation::Opcode>(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<Translation::Opcode>(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));
}
}
}
......
......@@ -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<Translation::Opcode>(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<Translation::Opcode>(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<CreateArgumentsType>(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());
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment