[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: Nico Hartmann <nicohartmann@chromium.org> Cr-Commit-Position: refs/heads/master@{#72278}
This commit is contained in:
parent
107629d1c7
commit
957d872bf5
3
BUILD.gn
3
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",
|
||||
|
@ -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
|
||||
|
||||
|
70
src/deoptimizer/translation-opcode.h
Normal file
70
src/deoptimizer/translation-opcode.h
Normal file
@ -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<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_
|
@ -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<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
|
@ -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 <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());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user