[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/translated-state.h",
|
||||||
"src/deoptimizer/translation-array.cc",
|
"src/deoptimizer/translation-array.cc",
|
||||||
"src/deoptimizer/translation-array.h",
|
"src/deoptimizer/translation-array.h",
|
||||||
"src/deoptimizer/translations.cc",
|
"src/deoptimizer/translation-opcode.h",
|
||||||
"src/deoptimizer/translations.h",
|
|
||||||
"src/diagnostics/basic-block-profiler.cc",
|
"src/diagnostics/basic-block-profiler.cc",
|
||||||
"src/diagnostics/basic-block-profiler.h",
|
"src/diagnostics/basic-block-profiler.h",
|
||||||
"src/diagnostics/code-tracer.h",
|
"src/diagnostics/code-tracer.h",
|
||||||
|
@ -985,8 +985,8 @@ Handle<DeoptimizationData> CodeGenerator::GenerateDeoptimizationData() {
|
|||||||
Handle<DeoptimizationData> data =
|
Handle<DeoptimizationData> data =
|
||||||
DeoptimizationData::New(isolate(), deopt_count, AllocationType::kOld);
|
DeoptimizationData::New(isolate(), deopt_count, AllocationType::kOld);
|
||||||
|
|
||||||
Handle<ByteArray> translation_array =
|
Handle<TranslationArray> translation_array =
|
||||||
translations_.CreateByteArray(isolate()->factory());
|
translations_.ToTranslationArray(isolate()->factory());
|
||||||
|
|
||||||
data->SetTranslationByteArray(*translation_array);
|
data->SetTranslationByteArray(*translation_array);
|
||||||
data->SetInlinedFunctionCount(
|
data->SetInlinedFunctionCount(
|
||||||
@ -1094,66 +1094,49 @@ DeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry(
|
|||||||
|
|
||||||
void CodeGenerator::TranslateStateValueDescriptor(
|
void CodeGenerator::TranslateStateValueDescriptor(
|
||||||
StateValueDescriptor* desc, StateValueList* nested,
|
StateValueDescriptor* desc, StateValueList* nested,
|
||||||
Translation* translation, InstructionOperandIterator* iter) {
|
InstructionOperandIterator* iter) {
|
||||||
// Note:
|
|
||||||
// If translation is null, we just skip the relevant instruction operands.
|
|
||||||
if (desc->IsNested()) {
|
if (desc->IsNested()) {
|
||||||
if (translation != nullptr) {
|
translations_.BeginCapturedObject(static_cast<int>(nested->size()));
|
||||||
translation->BeginCapturedObject(static_cast<int>(nested->size()));
|
|
||||||
}
|
|
||||||
for (auto field : *nested) {
|
for (auto field : *nested) {
|
||||||
TranslateStateValueDescriptor(field.desc, field.nested, translation,
|
TranslateStateValueDescriptor(field.desc, field.nested, iter);
|
||||||
iter);
|
|
||||||
}
|
}
|
||||||
} else if (desc->IsArgumentsElements()) {
|
} else if (desc->IsArgumentsElements()) {
|
||||||
if (translation != nullptr) {
|
translations_.ArgumentsElements(desc->arguments_type());
|
||||||
translation->ArgumentsElements(desc->arguments_type());
|
|
||||||
}
|
|
||||||
} else if (desc->IsArgumentsLength()) {
|
} else if (desc->IsArgumentsLength()) {
|
||||||
if (translation != nullptr) {
|
translations_.ArgumentsLength();
|
||||||
translation->ArgumentsLength();
|
|
||||||
}
|
|
||||||
} else if (desc->IsDuplicate()) {
|
} else if (desc->IsDuplicate()) {
|
||||||
if (translation != nullptr) {
|
translations_.DuplicateObject(static_cast<int>(desc->id()));
|
||||||
translation->DuplicateObject(static_cast<int>(desc->id()));
|
|
||||||
}
|
|
||||||
} else if (desc->IsPlain()) {
|
} else if (desc->IsPlain()) {
|
||||||
InstructionOperand* op = iter->Advance();
|
InstructionOperand* op = iter->Advance();
|
||||||
if (translation != nullptr) {
|
AddTranslationForOperand(iter->instruction(), op, desc->type());
|
||||||
AddTranslationForOperand(translation, iter->instruction(), op,
|
|
||||||
desc->type());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
DCHECK(desc->IsOptimizedOut());
|
DCHECK(desc->IsOptimizedOut());
|
||||||
if (translation != nullptr) {
|
|
||||||
if (optimized_out_literal_id_ == -1) {
|
if (optimized_out_literal_id_ == -1) {
|
||||||
optimized_out_literal_id_ = DefineDeoptimizationLiteral(
|
optimized_out_literal_id_ = DefineDeoptimizationLiteral(
|
||||||
DeoptimizationLiteral(isolate()->factory()->optimized_out()));
|
DeoptimizationLiteral(isolate()->factory()->optimized_out()));
|
||||||
}
|
}
|
||||||
translation->StoreLiteral(optimized_out_literal_id_);
|
translations_.StoreLiteral(optimized_out_literal_id_);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenerator::TranslateFrameStateDescriptorOperands(
|
void CodeGenerator::TranslateFrameStateDescriptorOperands(
|
||||||
FrameStateDescriptor* desc, InstructionOperandIterator* iter,
|
FrameStateDescriptor* desc, InstructionOperandIterator* iter) {
|
||||||
Translation* translation) {
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
StateValueList* values = desc->GetStateValueDescriptors();
|
StateValueList* values = desc->GetStateValueDescriptors();
|
||||||
for (StateValueList::iterator it = values->begin(); it != values->end();
|
for (StateValueList::iterator it = values->begin(); it != values->end();
|
||||||
++it, ++index) {
|
++it, ++index) {
|
||||||
TranslateStateValueDescriptor((*it).desc, (*it).nested, translation, iter);
|
TranslateStateValueDescriptor((*it).desc, (*it).nested, iter);
|
||||||
}
|
}
|
||||||
DCHECK_EQ(desc->GetSize(), index);
|
DCHECK_EQ(desc->GetSize(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenerator::BuildTranslationForFrameStateDescriptor(
|
void CodeGenerator::BuildTranslationForFrameStateDescriptor(
|
||||||
FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
|
FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
|
||||||
Translation* translation, OutputFrameStateCombine state_combine) {
|
OutputFrameStateCombine state_combine) {
|
||||||
// Outer-most state must be added to translation first.
|
// Outer-most state must be added to translation first.
|
||||||
if (descriptor->outer_state() != nullptr) {
|
if (descriptor->outer_state() != nullptr) {
|
||||||
BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter,
|
BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter,
|
||||||
translation, state_combine);
|
state_combine);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SharedFunctionInfo> shared_info;
|
Handle<SharedFunctionInfo> shared_info;
|
||||||
@ -1178,35 +1161,35 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
|
|||||||
return_offset = static_cast<int>(state_combine.GetOffsetToPokeAt());
|
return_offset = static_cast<int>(state_combine.GetOffsetToPokeAt());
|
||||||
return_count = static_cast<int>(iter->instruction()->OutputCount());
|
return_count = static_cast<int>(iter->instruction()->OutputCount());
|
||||||
}
|
}
|
||||||
translation->BeginInterpretedFrame(bailout_id, shared_info_id, height,
|
translations_.BeginInterpretedFrame(bailout_id, shared_info_id, height,
|
||||||
return_offset, return_count);
|
return_offset, return_count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FrameStateType::kArgumentsAdaptor:
|
case FrameStateType::kArgumentsAdaptor:
|
||||||
translation->BeginArgumentsAdaptorFrame(shared_info_id, height);
|
translations_.BeginArgumentsAdaptorFrame(shared_info_id, height);
|
||||||
break;
|
break;
|
||||||
case FrameStateType::kConstructStub:
|
case FrameStateType::kConstructStub:
|
||||||
DCHECK(bailout_id.IsValidForConstructStub());
|
DCHECK(bailout_id.IsValidForConstructStub());
|
||||||
translation->BeginConstructStubFrame(bailout_id, shared_info_id, height);
|
translations_.BeginConstructStubFrame(bailout_id, shared_info_id, height);
|
||||||
break;
|
break;
|
||||||
case FrameStateType::kBuiltinContinuation: {
|
case FrameStateType::kBuiltinContinuation: {
|
||||||
translation->BeginBuiltinContinuationFrame(bailout_id, shared_info_id,
|
translations_.BeginBuiltinContinuationFrame(bailout_id, shared_info_id,
|
||||||
height);
|
height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FrameStateType::kJavaScriptBuiltinContinuation: {
|
case FrameStateType::kJavaScriptBuiltinContinuation: {
|
||||||
translation->BeginJavaScriptBuiltinContinuationFrame(
|
translations_.BeginJavaScriptBuiltinContinuationFrame(
|
||||||
bailout_id, shared_info_id, height);
|
bailout_id, shared_info_id, height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FrameStateType::kJavaScriptBuiltinContinuationWithCatch: {
|
case FrameStateType::kJavaScriptBuiltinContinuationWithCatch: {
|
||||||
translation->BeginJavaScriptBuiltinContinuationWithCatchFrame(
|
translations_.BeginJavaScriptBuiltinContinuationWithCatchFrame(
|
||||||
bailout_id, shared_info_id, height);
|
bailout_id, shared_info_id, height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslateFrameStateDescriptorOperands(descriptor, iter, translation);
|
TranslateFrameStateDescriptorOperands(descriptor, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeoptimizationExit* CodeGenerator::BuildTranslation(
|
DeoptimizationExit* CodeGenerator::BuildTranslation(
|
||||||
@ -1217,23 +1200,21 @@ DeoptimizationExit* CodeGenerator::BuildTranslation(
|
|||||||
FrameStateDescriptor* const descriptor = entry.descriptor();
|
FrameStateDescriptor* const descriptor = entry.descriptor();
|
||||||
frame_state_offset++;
|
frame_state_offset++;
|
||||||
|
|
||||||
int update_feedback_count = entry.feedback().IsValid() ? 1 : 0;
|
const int update_feedback_count = entry.feedback().IsValid() ? 1 : 0;
|
||||||
Translation translation(&translations_,
|
const int translation_index = translations_.BeginTranslation(
|
||||||
static_cast<int>(descriptor->GetFrameCount()),
|
static_cast<int>(descriptor->GetFrameCount()),
|
||||||
static_cast<int>(descriptor->GetJSFrameCount()),
|
static_cast<int>(descriptor->GetJSFrameCount()), update_feedback_count);
|
||||||
update_feedback_count, zone());
|
|
||||||
if (entry.feedback().IsValid()) {
|
if (entry.feedback().IsValid()) {
|
||||||
DeoptimizationLiteral literal =
|
DeoptimizationLiteral literal =
|
||||||
DeoptimizationLiteral(entry.feedback().vector);
|
DeoptimizationLiteral(entry.feedback().vector);
|
||||||
int literal_id = DefineDeoptimizationLiteral(literal);
|
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);
|
InstructionOperandIterator iter(instr, frame_state_offset);
|
||||||
BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation,
|
BuildTranslationForFrameStateDescriptor(descriptor, &iter, state_combine);
|
||||||
state_combine);
|
|
||||||
|
|
||||||
DeoptimizationExit* const exit = zone()->New<DeoptimizationExit>(
|
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());
|
pc_offset, entry.kind(), entry.reason());
|
||||||
|
|
||||||
if (!Deoptimizer::kSupportsFixedDeoptExitSizes) {
|
if (!Deoptimizer::kSupportsFixedDeoptExitSizes) {
|
||||||
@ -1253,21 +1234,20 @@ DeoptimizationExit* CodeGenerator::BuildTranslation(
|
|||||||
return exit;
|
return exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenerator::AddTranslationForOperand(Translation* translation,
|
void CodeGenerator::AddTranslationForOperand(Instruction* instr,
|
||||||
Instruction* instr,
|
|
||||||
InstructionOperand* op,
|
InstructionOperand* op,
|
||||||
MachineType type) {
|
MachineType type) {
|
||||||
if (op->IsStackSlot()) {
|
if (op->IsStackSlot()) {
|
||||||
if (type.representation() == MachineRepresentation::kBit) {
|
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() ||
|
} else if (type == MachineType::Int8() || type == MachineType::Int16() ||
|
||||||
type == MachineType::Int32()) {
|
type == MachineType::Int32()) {
|
||||||
translation->StoreInt32StackSlot(LocationOperand::cast(op)->index());
|
translations_.StoreInt32StackSlot(LocationOperand::cast(op)->index());
|
||||||
} else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
|
} else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
|
||||||
type == MachineType::Uint32()) {
|
type == MachineType::Uint32()) {
|
||||||
translation->StoreUint32StackSlot(LocationOperand::cast(op)->index());
|
translations_.StoreUint32StackSlot(LocationOperand::cast(op)->index());
|
||||||
} else if (type == MachineType::Int64()) {
|
} else if (type == MachineType::Int64()) {
|
||||||
translation->StoreInt64StackSlot(LocationOperand::cast(op)->index());
|
translations_.StoreInt64StackSlot(LocationOperand::cast(op)->index());
|
||||||
} else {
|
} else {
|
||||||
#if defined(V8_COMPRESS_POINTERS)
|
#if defined(V8_COMPRESS_POINTERS)
|
||||||
CHECK(MachineRepresentation::kTagged == type.representation() ||
|
CHECK(MachineRepresentation::kTagged == type.representation() ||
|
||||||
@ -1275,27 +1255,27 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
|
|||||||
#else
|
#else
|
||||||
CHECK(MachineRepresentation::kTagged == type.representation());
|
CHECK(MachineRepresentation::kTagged == type.representation());
|
||||||
#endif
|
#endif
|
||||||
translation->StoreStackSlot(LocationOperand::cast(op)->index());
|
translations_.StoreStackSlot(LocationOperand::cast(op)->index());
|
||||||
}
|
}
|
||||||
} else if (op->IsFPStackSlot()) {
|
} else if (op->IsFPStackSlot()) {
|
||||||
if (type.representation() == MachineRepresentation::kFloat64) {
|
if (type.representation() == MachineRepresentation::kFloat64) {
|
||||||
translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index());
|
translations_.StoreDoubleStackSlot(LocationOperand::cast(op)->index());
|
||||||
} else {
|
} else {
|
||||||
CHECK_EQ(MachineRepresentation::kFloat32, type.representation());
|
CHECK_EQ(MachineRepresentation::kFloat32, type.representation());
|
||||||
translation->StoreFloatStackSlot(LocationOperand::cast(op)->index());
|
translations_.StoreFloatStackSlot(LocationOperand::cast(op)->index());
|
||||||
}
|
}
|
||||||
} else if (op->IsRegister()) {
|
} else if (op->IsRegister()) {
|
||||||
InstructionOperandConverter converter(this, instr);
|
InstructionOperandConverter converter(this, instr);
|
||||||
if (type.representation() == MachineRepresentation::kBit) {
|
if (type.representation() == MachineRepresentation::kBit) {
|
||||||
translation->StoreBoolRegister(converter.ToRegister(op));
|
translations_.StoreBoolRegister(converter.ToRegister(op));
|
||||||
} else if (type == MachineType::Int8() || type == MachineType::Int16() ||
|
} else if (type == MachineType::Int8() || type == MachineType::Int16() ||
|
||||||
type == MachineType::Int32()) {
|
type == MachineType::Int32()) {
|
||||||
translation->StoreInt32Register(converter.ToRegister(op));
|
translations_.StoreInt32Register(converter.ToRegister(op));
|
||||||
} else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
|
} else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
|
||||||
type == MachineType::Uint32()) {
|
type == MachineType::Uint32()) {
|
||||||
translation->StoreUint32Register(converter.ToRegister(op));
|
translations_.StoreUint32Register(converter.ToRegister(op));
|
||||||
} else if (type == MachineType::Int64()) {
|
} else if (type == MachineType::Int64()) {
|
||||||
translation->StoreInt64Register(converter.ToRegister(op));
|
translations_.StoreInt64Register(converter.ToRegister(op));
|
||||||
} else {
|
} else {
|
||||||
#if defined(V8_COMPRESS_POINTERS)
|
#if defined(V8_COMPRESS_POINTERS)
|
||||||
CHECK(MachineRepresentation::kTagged == type.representation() ||
|
CHECK(MachineRepresentation::kTagged == type.representation() ||
|
||||||
@ -1303,15 +1283,15 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
|
|||||||
#else
|
#else
|
||||||
CHECK(MachineRepresentation::kTagged == type.representation());
|
CHECK(MachineRepresentation::kTagged == type.representation());
|
||||||
#endif
|
#endif
|
||||||
translation->StoreRegister(converter.ToRegister(op));
|
translations_.StoreRegister(converter.ToRegister(op));
|
||||||
}
|
}
|
||||||
} else if (op->IsFPRegister()) {
|
} else if (op->IsFPRegister()) {
|
||||||
InstructionOperandConverter converter(this, instr);
|
InstructionOperandConverter converter(this, instr);
|
||||||
if (type.representation() == MachineRepresentation::kFloat64) {
|
if (type.representation() == MachineRepresentation::kFloat64) {
|
||||||
translation->StoreDoubleRegister(converter.ToDoubleRegister(op));
|
translations_.StoreDoubleRegister(converter.ToDoubleRegister(op));
|
||||||
} else {
|
} else {
|
||||||
CHECK_EQ(MachineRepresentation::kFloat32, type.representation());
|
CHECK_EQ(MachineRepresentation::kFloat32, type.representation());
|
||||||
translation->StoreFloatRegister(converter.ToFloatRegister(op));
|
translations_.StoreFloatRegister(converter.ToFloatRegister(op));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CHECK(op->IsImmediate());
|
CHECK(op->IsImmediate());
|
||||||
@ -1390,10 +1370,10 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
|
|||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
if (literal.object().equals(info()->closure())) {
|
if (literal.object().equals(info()->closure())) {
|
||||||
translation->StoreJSFrameFunction();
|
translations_.StoreJSFrameFunction();
|
||||||
} else {
|
} else {
|
||||||
int literal_id = DefineDeoptimizationLiteral(literal);
|
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);
|
OutputFrameStateCombine state_combine);
|
||||||
void BuildTranslationForFrameStateDescriptor(
|
void BuildTranslationForFrameStateDescriptor(
|
||||||
FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
|
FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
|
||||||
Translation* translation, OutputFrameStateCombine state_combine);
|
OutputFrameStateCombine state_combine);
|
||||||
void TranslateStateValueDescriptor(StateValueDescriptor* desc,
|
void TranslateStateValueDescriptor(StateValueDescriptor* desc,
|
||||||
StateValueList* nested,
|
StateValueList* nested,
|
||||||
Translation* translation,
|
|
||||||
InstructionOperandIterator* iter);
|
InstructionOperandIterator* iter);
|
||||||
void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
|
void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
|
||||||
InstructionOperandIterator* iter,
|
InstructionOperandIterator* iter);
|
||||||
Translation* translation);
|
void AddTranslationForOperand(Instruction* instr, InstructionOperand* op,
|
||||||
void AddTranslationForOperand(Translation* translation, Instruction* instr,
|
MachineType type);
|
||||||
InstructionOperand* op, MachineType type);
|
|
||||||
void MarkLazyDeoptSite();
|
void MarkLazyDeoptSite();
|
||||||
|
|
||||||
void PrepareForDeoptimizationExits(ZoneDeque<DeoptimizationExit*>* exits);
|
void PrepareForDeoptimizationExits(ZoneDeque<DeoptimizationExit*>* exits);
|
||||||
@ -444,7 +442,7 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
|
|||||||
ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
|
ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
|
||||||
ZoneDeque<DeoptimizationLiteral> deoptimization_literals_;
|
ZoneDeque<DeoptimizationLiteral> deoptimization_literals_;
|
||||||
size_t inlined_function_count_ = 0;
|
size_t inlined_function_count_ = 0;
|
||||||
TranslationBuffer translations_;
|
TranslationArrayBuilder translations_;
|
||||||
int handler_table_offset_ = 0;
|
int handler_table_offset_ = 0;
|
||||||
int last_lazy_deopt_pc_ = 0;
|
int last_lazy_deopt_pc_ = 0;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/deoptimizer/translations.h"
|
#include "src/deoptimizer/translated-state.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -7,10 +7,11 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/builtins/builtins.h"
|
||||||
#include "src/codegen/source-position.h"
|
#include "src/codegen/source-position.h"
|
||||||
#include "src/deoptimizer/deoptimize-reason.h"
|
#include "src/deoptimizer/deoptimize-reason.h"
|
||||||
#include "src/deoptimizer/frame-description.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/diagnostics/code-tracer.h"
|
||||||
#include "src/objects/js-function.h"
|
#include "src/objects/js-function.h"
|
||||||
|
|
||||||
|
@ -4,10 +4,12 @@
|
|||||||
|
|
||||||
#include "src/deoptimizer/translated-state.h"
|
#include "src/deoptimizer/translated-state.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include "src/base/memory.h"
|
#include "src/base/memory.h"
|
||||||
#include "src/deoptimizer/deoptimizer.h"
|
#include "src/deoptimizer/deoptimizer.h"
|
||||||
#include "src/deoptimizer/materialized-object-store.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/diagnostics/disasm.h"
|
||||||
#include "src/execution/frames.h"
|
#include "src/execution/frames.h"
|
||||||
#include "src/execution/isolate.h"
|
#include "src/execution/isolate.h"
|
||||||
@ -26,6 +28,229 @@ using base::ReadUnalignedValue;
|
|||||||
|
|
||||||
namespace internal {
|
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
|
// static
|
||||||
TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container,
|
TranslatedValue TranslatedValue::NewDeferredObject(TranslatedState* container,
|
||||||
int length,
|
int length,
|
||||||
@ -455,10 +680,9 @@ void TranslatedFrame::Handlify() {
|
|||||||
TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
||||||
TranslationArrayIterator* iterator, FixedArray literal_array, Address fp,
|
TranslationArrayIterator* iterator, FixedArray literal_array, Address fp,
|
||||||
FILE* trace_file) {
|
FILE* trace_file) {
|
||||||
Translation::Opcode opcode =
|
TranslationOpcode opcode = TranslationOpcodeFromInt(iterator->Next());
|
||||||
static_cast<Translation::Opcode>(iterator->Next());
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Translation::INTERPRETED_FRAME: {
|
case TranslationOpcode::INTERPRETED_FRAME: {
|
||||||
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
||||||
SharedFunctionInfo shared_info =
|
SharedFunctionInfo shared_info =
|
||||||
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
||||||
@ -480,7 +704,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
|||||||
return_value_count);
|
return_value_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::ARGUMENTS_ADAPTOR_FRAME: {
|
case TranslationOpcode::ARGUMENTS_ADAPTOR_FRAME: {
|
||||||
SharedFunctionInfo shared_info =
|
SharedFunctionInfo shared_info =
|
||||||
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
||||||
int height = iterator->Next();
|
int height = iterator->Next();
|
||||||
@ -492,7 +716,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
|||||||
return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height);
|
return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::CONSTRUCT_STUB_FRAME: {
|
case TranslationOpcode::CONSTRUCT_STUB_FRAME: {
|
||||||
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
||||||
SharedFunctionInfo shared_info =
|
SharedFunctionInfo shared_info =
|
||||||
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
||||||
@ -507,7 +731,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
|||||||
height);
|
height);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::BUILTIN_CONTINUATION_FRAME: {
|
case TranslationOpcode::BUILTIN_CONTINUATION_FRAME: {
|
||||||
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
||||||
SharedFunctionInfo shared_info =
|
SharedFunctionInfo shared_info =
|
||||||
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
||||||
@ -523,7 +747,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
|||||||
shared_info, height);
|
shared_info, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: {
|
case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: {
|
||||||
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
||||||
SharedFunctionInfo shared_info =
|
SharedFunctionInfo shared_info =
|
||||||
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
||||||
@ -538,7 +762,8 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
|||||||
return TranslatedFrame::JavaScriptBuiltinContinuationFrame(
|
return TranslatedFrame::JavaScriptBuiltinContinuationFrame(
|
||||||
bytecode_offset, shared_info, height);
|
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());
|
BytecodeOffset bytecode_offset = BytecodeOffset(iterator->Next());
|
||||||
SharedFunctionInfo shared_info =
|
SharedFunctionInfo shared_info =
|
||||||
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
SharedFunctionInfo::cast(literal_array.get(iterator->Next()));
|
||||||
@ -554,31 +779,30 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
|
|||||||
return TranslatedFrame::JavaScriptBuiltinContinuationWithCatchFrame(
|
return TranslatedFrame::JavaScriptBuiltinContinuationWithCatchFrame(
|
||||||
bytecode_offset, shared_info, height);
|
bytecode_offset, shared_info, height);
|
||||||
}
|
}
|
||||||
case Translation::UPDATE_FEEDBACK:
|
case TranslationOpcode::UPDATE_FEEDBACK:
|
||||||
case Translation::BEGIN:
|
case TranslationOpcode::BEGIN:
|
||||||
case Translation::DUPLICATED_OBJECT:
|
case TranslationOpcode::DUPLICATED_OBJECT:
|
||||||
case Translation::ARGUMENTS_ELEMENTS:
|
case TranslationOpcode::ARGUMENTS_ELEMENTS:
|
||||||
case Translation::ARGUMENTS_LENGTH:
|
case TranslationOpcode::ARGUMENTS_LENGTH:
|
||||||
case Translation::CAPTURED_OBJECT:
|
case TranslationOpcode::CAPTURED_OBJECT:
|
||||||
case Translation::REGISTER:
|
case TranslationOpcode::REGISTER:
|
||||||
case Translation::INT32_REGISTER:
|
case TranslationOpcode::INT32_REGISTER:
|
||||||
case Translation::INT64_REGISTER:
|
case TranslationOpcode::INT64_REGISTER:
|
||||||
case Translation::UINT32_REGISTER:
|
case TranslationOpcode::UINT32_REGISTER:
|
||||||
case Translation::BOOL_REGISTER:
|
case TranslationOpcode::BOOL_REGISTER:
|
||||||
case Translation::FLOAT_REGISTER:
|
case TranslationOpcode::FLOAT_REGISTER:
|
||||||
case Translation::DOUBLE_REGISTER:
|
case TranslationOpcode::DOUBLE_REGISTER:
|
||||||
case Translation::STACK_SLOT:
|
case TranslationOpcode::STACK_SLOT:
|
||||||
case Translation::INT32_STACK_SLOT:
|
case TranslationOpcode::INT32_STACK_SLOT:
|
||||||
case Translation::INT64_STACK_SLOT:
|
case TranslationOpcode::INT64_STACK_SLOT:
|
||||||
case Translation::UINT32_STACK_SLOT:
|
case TranslationOpcode::UINT32_STACK_SLOT:
|
||||||
case Translation::BOOL_STACK_SLOT:
|
case TranslationOpcode::BOOL_STACK_SLOT:
|
||||||
case Translation::FLOAT_STACK_SLOT:
|
case TranslationOpcode::FLOAT_STACK_SLOT:
|
||||||
case Translation::DOUBLE_STACK_SLOT:
|
case TranslationOpcode::DOUBLE_STACK_SLOT:
|
||||||
case Translation::LITERAL:
|
case TranslationOpcode::LITERAL:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
FATAL("We should never get here - unexpected deopt info.");
|
UNREACHABLE();
|
||||||
return TranslatedFrame::InvalidFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@ -656,7 +880,7 @@ void TranslatedState::CreateArgumentsElementsTranslatedValues(
|
|||||||
// Thus we build a temporary structure in malloced space.
|
// Thus we build a temporary structure in malloced space.
|
||||||
// The TranslatedValue objects created correspond to the static translation
|
// The TranslatedValue objects created correspond to the static translation
|
||||||
// instructions from the TranslationArrayIterator, except for
|
// 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.
|
// FixedArray elements depend on dynamic information from the optimized frame.
|
||||||
// Returns the number of expected nested translations from the
|
// Returns the number of expected nested translations from the
|
||||||
// TranslationArrayIterator.
|
// TranslationArrayIterator.
|
||||||
@ -669,21 +893,20 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
TranslatedFrame& frame = frames_[frame_index];
|
TranslatedFrame& frame = frames_[frame_index];
|
||||||
int value_index = static_cast<int>(frame.values_.size());
|
int value_index = static_cast<int>(frame.values_.size());
|
||||||
|
|
||||||
Translation::Opcode opcode =
|
TranslationOpcode opcode = TranslationOpcodeFromInt(iterator->Next());
|
||||||
static_cast<Translation::Opcode>(iterator->Next());
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Translation::BEGIN:
|
case TranslationOpcode::BEGIN:
|
||||||
case Translation::INTERPRETED_FRAME:
|
case TranslationOpcode::INTERPRETED_FRAME:
|
||||||
case Translation::ARGUMENTS_ADAPTOR_FRAME:
|
case TranslationOpcode::ARGUMENTS_ADAPTOR_FRAME:
|
||||||
case Translation::CONSTRUCT_STUB_FRAME:
|
case TranslationOpcode::CONSTRUCT_STUB_FRAME:
|
||||||
case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME:
|
case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME:
|
||||||
case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME:
|
case TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME:
|
||||||
case Translation::BUILTIN_CONTINUATION_FRAME:
|
case TranslationOpcode::BUILTIN_CONTINUATION_FRAME:
|
||||||
case Translation::UPDATE_FEEDBACK:
|
case TranslationOpcode::UPDATE_FEEDBACK:
|
||||||
// Peeled off before getting here.
|
// Peeled off before getting here.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Translation::DUPLICATED_OBJECT: {
|
case TranslationOpcode::DUPLICATED_OBJECT: {
|
||||||
int object_id = iterator->Next();
|
int object_id = iterator->Next();
|
||||||
if (trace_file != nullptr) {
|
if (trace_file != nullptr) {
|
||||||
PrintF(trace_file, "duplicated object #%d", object_id);
|
PrintF(trace_file, "duplicated object #%d", object_id);
|
||||||
@ -695,7 +918,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::ARGUMENTS_ELEMENTS: {
|
case TranslationOpcode::ARGUMENTS_ELEMENTS: {
|
||||||
CreateArgumentsType arguments_type =
|
CreateArgumentsType arguments_type =
|
||||||
static_cast<CreateArgumentsType>(iterator->Next());
|
static_cast<CreateArgumentsType>(iterator->Next());
|
||||||
CreateArgumentsElementsTranslatedValues(frame_index, fp, arguments_type,
|
CreateArgumentsElementsTranslatedValues(frame_index, fp, arguments_type,
|
||||||
@ -703,7 +926,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::ARGUMENTS_LENGTH: {
|
case TranslationOpcode::ARGUMENTS_LENGTH: {
|
||||||
if (trace_file != nullptr) {
|
if (trace_file != nullptr) {
|
||||||
PrintF(trace_file, "arguments length field (length = %d)",
|
PrintF(trace_file, "arguments length field (length = %d)",
|
||||||
actual_argument_count_);
|
actual_argument_count_);
|
||||||
@ -712,7 +935,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::CAPTURED_OBJECT: {
|
case TranslationOpcode::CAPTURED_OBJECT: {
|
||||||
int field_count = iterator->Next();
|
int field_count = iterator->Next();
|
||||||
int object_index = static_cast<int>(object_positions_.size());
|
int object_index = static_cast<int>(object_positions_.size());
|
||||||
if (trace_file != nullptr) {
|
if (trace_file != nullptr) {
|
||||||
@ -726,7 +949,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::REGISTER: {
|
case TranslationOpcode::REGISTER: {
|
||||||
int input_reg = iterator->Next();
|
int input_reg = iterator->Next();
|
||||||
if (registers == nullptr) {
|
if (registers == nullptr) {
|
||||||
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
||||||
@ -746,7 +969,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::INT32_REGISTER: {
|
case TranslationOpcode::INT32_REGISTER: {
|
||||||
int input_reg = iterator->Next();
|
int input_reg = iterator->Next();
|
||||||
if (registers == nullptr) {
|
if (registers == nullptr) {
|
||||||
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
||||||
@ -764,7 +987,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::INT64_REGISTER: {
|
case TranslationOpcode::INT64_REGISTER: {
|
||||||
int input_reg = iterator->Next();
|
int input_reg = iterator->Next();
|
||||||
if (registers == nullptr) {
|
if (registers == nullptr) {
|
||||||
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
||||||
@ -782,7 +1005,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::UINT32_REGISTER: {
|
case TranslationOpcode::UINT32_REGISTER: {
|
||||||
int input_reg = iterator->Next();
|
int input_reg = iterator->Next();
|
||||||
if (registers == nullptr) {
|
if (registers == nullptr) {
|
||||||
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
||||||
@ -800,7 +1023,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::BOOL_REGISTER: {
|
case TranslationOpcode::BOOL_REGISTER: {
|
||||||
int input_reg = iterator->Next();
|
int input_reg = iterator->Next();
|
||||||
if (registers == nullptr) {
|
if (registers == nullptr) {
|
||||||
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
||||||
@ -818,7 +1041,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::FLOAT_REGISTER: {
|
case TranslationOpcode::FLOAT_REGISTER: {
|
||||||
int input_reg = iterator->Next();
|
int input_reg = iterator->Next();
|
||||||
if (registers == nullptr) {
|
if (registers == nullptr) {
|
||||||
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
||||||
@ -835,7 +1058,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::DOUBLE_REGISTER: {
|
case TranslationOpcode::DOUBLE_REGISTER: {
|
||||||
int input_reg = iterator->Next();
|
int input_reg = iterator->Next();
|
||||||
if (registers == nullptr) {
|
if (registers == nullptr) {
|
||||||
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
TranslatedValue translated_value = TranslatedValue::NewInvalid(this);
|
||||||
@ -853,7 +1076,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::STACK_SLOT: {
|
case TranslationOpcode::STACK_SLOT: {
|
||||||
int slot_offset =
|
int slot_offset =
|
||||||
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
||||||
intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
|
intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
|
||||||
@ -870,7 +1093,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::INT32_STACK_SLOT: {
|
case TranslationOpcode::INT32_STACK_SLOT: {
|
||||||
int slot_offset =
|
int slot_offset =
|
||||||
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
||||||
uint32_t value = GetUInt32Slot(fp, slot_offset);
|
uint32_t value = GetUInt32Slot(fp, slot_offset);
|
||||||
@ -884,7 +1107,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::INT64_STACK_SLOT: {
|
case TranslationOpcode::INT64_STACK_SLOT: {
|
||||||
int slot_offset =
|
int slot_offset =
|
||||||
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
||||||
uint64_t value = GetUInt64Slot(fp, slot_offset);
|
uint64_t value = GetUInt64Slot(fp, slot_offset);
|
||||||
@ -898,7 +1121,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::UINT32_STACK_SLOT: {
|
case TranslationOpcode::UINT32_STACK_SLOT: {
|
||||||
int slot_offset =
|
int slot_offset =
|
||||||
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
||||||
uint32_t value = GetUInt32Slot(fp, slot_offset);
|
uint32_t value = GetUInt32Slot(fp, slot_offset);
|
||||||
@ -912,7 +1135,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::BOOL_STACK_SLOT: {
|
case TranslationOpcode::BOOL_STACK_SLOT: {
|
||||||
int slot_offset =
|
int slot_offset =
|
||||||
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
||||||
uint32_t value = GetUInt32Slot(fp, slot_offset);
|
uint32_t value = GetUInt32Slot(fp, slot_offset);
|
||||||
@ -925,7 +1148,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::FLOAT_STACK_SLOT: {
|
case TranslationOpcode::FLOAT_STACK_SLOT: {
|
||||||
int slot_offset =
|
int slot_offset =
|
||||||
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
||||||
Float32 value = GetFloatSlot(fp, slot_offset);
|
Float32 value = GetFloatSlot(fp, slot_offset);
|
||||||
@ -938,7 +1161,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::DOUBLE_STACK_SLOT: {
|
case TranslationOpcode::DOUBLE_STACK_SLOT: {
|
||||||
int slot_offset =
|
int slot_offset =
|
||||||
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
|
||||||
Float64 value = GetDoubleSlot(fp, slot_offset);
|
Float64 value = GetDoubleSlot(fp, slot_offset);
|
||||||
@ -952,7 +1175,7 @@ int TranslatedState::CreateNextTranslatedValue(
|
|||||||
return translated_value.GetChildrenCount();
|
return translated_value.GetChildrenCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Translation::LITERAL: {
|
case TranslationOpcode::LITERAL: {
|
||||||
int literal_index = iterator->Next();
|
int literal_index = iterator->Next();
|
||||||
Object value = literal_array.get(literal_index);
|
Object value = literal_array.get(literal_index);
|
||||||
if (trace_file != nullptr) {
|
if (trace_file != nullptr) {
|
||||||
@ -1009,9 +1232,8 @@ void TranslatedState::Init(Isolate* isolate, Address input_frame_pointer,
|
|||||||
isolate_ = isolate;
|
isolate_ = isolate;
|
||||||
|
|
||||||
// Read out the 'header' translation.
|
// Read out the 'header' translation.
|
||||||
Translation::Opcode opcode =
|
TranslationOpcode opcode = TranslationOpcodeFromInt(iterator->Next());
|
||||||
static_cast<Translation::Opcode>(iterator->Next());
|
CHECK(opcode == TranslationOpcode::BEGIN);
|
||||||
CHECK(opcode == Translation::BEGIN);
|
|
||||||
|
|
||||||
int count = iterator->Next();
|
int count = iterator->Next();
|
||||||
frames_.reserve(count);
|
frames_.reserve(count);
|
||||||
@ -1072,8 +1294,8 @@ void TranslatedState::Init(Isolate* isolate, Address input_frame_pointer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK(!iterator->HasNext() || static_cast<Translation::Opcode>(
|
CHECK(!iterator->HasNext() ||
|
||||||
iterator->Next()) == Translation::BEGIN);
|
TranslationOpcodeFromInt(iterator->Next()) == TranslationOpcode::BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslatedState::Prepare(Address stack_frame_pointer) {
|
void TranslatedState::Prepare(Address stack_frame_pointer) {
|
||||||
@ -1790,7 +2012,8 @@ bool TranslatedState::DoUpdateFeedback() {
|
|||||||
void TranslatedState::ReadUpdateFeedback(TranslationArrayIterator* iterator,
|
void TranslatedState::ReadUpdateFeedback(TranslationArrayIterator* iterator,
|
||||||
FixedArray literal_array,
|
FixedArray literal_array,
|
||||||
FILE* trace_file) {
|
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_vector_ = FeedbackVector::cast(literal_array.get(iterator->Next()));
|
||||||
feedback_slot_ = FeedbackSlot(iterator->Next());
|
feedback_slot_ = FeedbackSlot(iterator->Next());
|
||||||
if (trace_file != nullptr) {
|
if (trace_file != nullptr) {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/deoptimizer/translation-array.h"
|
||||||
#include "src/objects/feedback-vector.h"
|
#include "src/objects/feedback-vector.h"
|
||||||
#include "src/objects/heap-object.h"
|
#include "src/objects/heap-object.h"
|
||||||
#include "src/objects/shared-function-info.h"
|
#include "src/objects/shared-function-info.h"
|
||||||
@ -19,7 +20,14 @@ namespace internal {
|
|||||||
|
|
||||||
class RegisterValues;
|
class RegisterValues;
|
||||||
class TranslatedState;
|
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
|
// The Translated{Value,Frame,State} class hierarchy are a set of utility
|
||||||
// functions to work with the combination of translations (built from a
|
// functions to work with the combination of translations (built from a
|
||||||
|
@ -35,5 +35,235 @@ bool TranslationArrayIterator::HasNext() const {
|
|||||||
return index_ < buffer_.length();
|
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 internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -5,13 +5,19 @@
|
|||||||
#ifndef V8_DEOPTIMIZER_TRANSLATION_ARRAY_H_
|
#ifndef V8_DEOPTIMIZER_TRANSLATION_ARRAY_H_
|
||||||
#define 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/objects/fixed-array.h"
|
||||||
|
#include "src/wasm/value-type.h"
|
||||||
|
#include "src/zone/zone-chunk-list.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
class Factory;
|
||||||
|
|
||||||
// The TranslationArray is the on-heap representation of translations created
|
// 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
|
// translation array specifies how to transform an optimized frame back into
|
||||||
// one or more unoptimized frames.
|
// one or more unoptimized frames.
|
||||||
// TODO(jgruber): Consider a real type instead of this type alias.
|
// TODO(jgruber): Consider a real type instead of this type alias.
|
||||||
@ -34,6 +40,73 @@ class TranslationArrayIterator {
|
|||||||
int index_;
|
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 internal
|
||||||
} // namespace v8
|
} // 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(),
|
TranslationArrayIterator it(data.TranslationByteArray(),
|
||||||
data.TranslationIndex(deopt_index).value());
|
data.TranslationIndex(deopt_index).value());
|
||||||
Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
|
TranslationOpcode opcode = TranslationOpcodeFromInt(it.Next());
|
||||||
DCHECK_EQ(Translation::BEGIN, opcode);
|
DCHECK_EQ(TranslationOpcode::BEGIN, opcode);
|
||||||
it.Next(); // Skip frame count.
|
it.Next(); // Skip frame count.
|
||||||
int jsframe_count = it.Next();
|
int jsframe_count = it.Next();
|
||||||
it.Next(); // Skip update feedback count.
|
it.Next(); // Skip update feedback count.
|
||||||
@ -1653,11 +1653,11 @@ void OptimizedFrame::GetFunctions(
|
|||||||
// We insert the frames in reverse order because the frames
|
// We insert the frames in reverse order because the frames
|
||||||
// in the deoptimization translation are ordered bottom-to-top.
|
// in the deoptimization translation are ordered bottom-to-top.
|
||||||
while (jsframe_count != 0) {
|
while (jsframe_count != 0) {
|
||||||
opcode = static_cast<Translation::Opcode>(it.Next());
|
opcode = TranslationOpcodeFromInt(it.Next());
|
||||||
if (opcode == Translation::INTERPRETED_FRAME ||
|
if (opcode == TranslationOpcode::INTERPRETED_FRAME ||
|
||||||
opcode == Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME ||
|
opcode == TranslationOpcode::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME ||
|
||||||
opcode ==
|
opcode == TranslationOpcode::
|
||||||
Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) {
|
JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH_FRAME) {
|
||||||
it.Next(); // Skip bailout id.
|
it.Next(); // Skip bailout id.
|
||||||
jsframe_count--;
|
jsframe_count--;
|
||||||
|
|
||||||
@ -1666,10 +1666,10 @@ void OptimizedFrame::GetFunctions(
|
|||||||
functions->push_back(SharedFunctionInfo::cast(shared));
|
functions->push_back(SharedFunctionInfo::cast(shared));
|
||||||
|
|
||||||
// Skip over remaining operands to advance to the next opcode.
|
// Skip over remaining operands to advance to the next opcode.
|
||||||
it.Skip(Translation::NumberOfOperandsFor(opcode) - 2);
|
it.Skip(TranslationOpcodeOperandCount(opcode) - 2);
|
||||||
} else {
|
} else {
|
||||||
// Skip over operands to advance to the next opcode.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
disasm::NameConverter converter;
|
|
||||||
int const inlined_function_count = InlinedFunctionCount().value();
|
int const inlined_function_count = InlinedFunctionCount().value();
|
||||||
os << "Inlined functions (count = " << inlined_function_count << ")\n";
|
os << "Inlined functions (count = " << inlined_function_count << ")\n";
|
||||||
for (int id = 0; id < inlined_function_count; ++id) {
|
for (int id = 0; id < inlined_function_count; ++id) {
|
||||||
@ -467,203 +466,9 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print details of the frame translation.
|
TranslationArrayPrintSingleFrame(os, TranslationByteArray(),
|
||||||
int translation_index = TranslationIndex(i).value();
|
TranslationIndex(i).value(),
|
||||||
TranslationArrayIterator iterator(TranslationByteArray(),
|
LiteralArray());
|
||||||
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";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user