Commit 0dcb488c authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Build translation array on background

Move the translation array building to the "compile" rather than
"generate code" phase of maglev compilation, as a graph processor after
register allocation. This allows it to be done on a background thread.

Drive-by: Use the new OptimizedOut functionality of the translation
array builder.

Bug: v8:7700
Change-Id: If4202737f1eeb38281f306c23f408105c5fb0ef1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3811501Reviewed-by: 's avatarVictor Gomes <victorgomes@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82228}
parent e4d28751
......@@ -682,17 +682,13 @@ class MaglevCodeGeneratorImpl final {
}
private:
static constexpr int kOptimizedOutConstantIndex = 0;
MaglevCodeGeneratorImpl(MaglevCompilationInfo* compilation_info, Graph* graph)
: safepoint_table_builder_(compilation_info->zone(),
graph->tagged_stack_slots(),
graph->untagged_stack_slots()),
translation_array_builder_(compilation_info->zone()),
code_gen_state_(compilation_info, safepoint_table_builder()),
processor_(compilation_info, &code_gen_state_),
graph_(graph),
deopt_literals_(compilation_info->isolate()->heap()) {}
graph_(graph) {}
MaybeHandle<Code> Generate() {
EmitCode();
......@@ -705,13 +701,6 @@ class MaglevCodeGeneratorImpl final {
processor_.ProcessGraph(graph_);
EmitDeferredCode();
EmitDeopts();
// Add the bytecode to the deopt literals to make sure it's held strongly.
// TODO(leszeks): Do this fo inlined functions too.
GetDeoptLiteral(*code_gen_state_.compilation_info()
->toplevel_compilation_unit()
->bytecode()
.object());
}
void EmitDeferredCode() {
......@@ -726,20 +715,10 @@ class MaglevCodeGeneratorImpl final {
void EmitDeopts() {
deopt_exit_start_offset_ = __ pc_offset();
// We'll emit the optimized out constant a bunch of times, so to avoid
// looking it up in the literal map every time, add it now with the fixed
// offset 0.
int optimized_out_constant_index =
GetDeoptLiteral(ReadOnlyRoots(isolate()).optimized_out());
USE(optimized_out_constant_index);
DCHECK_EQ(kOptimizedOutConstantIndex, optimized_out_constant_index);
int deopt_index = 0;
__ RecordComment("-- Non-lazy deopts");
for (EagerDeoptInfo* deopt_info : code_gen_state_.eager_deopts()) {
EmitEagerDeopt(deopt_info);
// TODO(leszeks): Record source positions.
__ RecordDeoptReason(deopt_info->reason, 0, SourcePosition::Unknown(),
deopt_index);
......@@ -753,8 +732,6 @@ class MaglevCodeGeneratorImpl final {
__ RecordComment("-- Lazy deopts");
int last_updated_safepoint = 0;
for (LazyDeoptInfo* deopt_info : code_gen_state_.lazy_deopts()) {
EmitLazyDeopt(deopt_info);
__ bind(&deopt_info->deopt_entry_label);
__ CallForDeoptimization(Builtin::kDeoptimizationEntry_Lazy, deopt_index,
&deopt_info->deopt_entry_label,
......@@ -769,224 +746,6 @@ class MaglevCodeGeneratorImpl final {
}
}
const InputLocation* EmitDeoptFrame(const MaglevCompilationUnit& unit,
const CheckpointedInterpreterState& state,
const InputLocation* input_locations) {
if (state.parent) {
// Deopt input locations are in the order of deopt frame emission, so
// update the pointer after emitting the parent frame.
input_locations =
EmitDeoptFrame(*unit.caller(), *state.parent, input_locations);
}
// Returns are used for updating an accumulator or register after a lazy
// deopt.
const int return_offset = 0;
const int return_count = 0;
translation_array_builder_.BeginInterpretedFrame(
state.bytecode_position,
GetDeoptLiteral(*unit.shared_function_info().object()),
unit.register_count(), return_offset, return_count);
return EmitDeoptFrameValues(unit, state.register_frame, input_locations,
interpreter::Register::invalid_value());
}
void EmitEagerDeopt(EagerDeoptInfo* deopt_info) {
int frame_count = 1 + deopt_info->unit.inlining_depth();
int jsframe_count = frame_count;
int update_feedback_count = 0;
deopt_info->translation_index = translation_array_builder_.BeginTranslation(
frame_count, jsframe_count, update_feedback_count);
EmitDeoptFrame(deopt_info->unit, deopt_info->state,
deopt_info->input_locations);
}
void EmitLazyDeopt(LazyDeoptInfo* deopt_info) {
const MaglevCompilationUnit& unit = deopt_info->unit;
DCHECK_NULL(unit.caller());
DCHECK_EQ(unit.inlining_depth(), 0);
int frame_count = 1;
int jsframe_count = 1;
int update_feedback_count = 0;
deopt_info->translation_index = translation_array_builder_.BeginTranslation(
frame_count, jsframe_count, update_feedback_count);
// Return offsets are counted from the end of the translation frame, which
// is the array [parameters..., locals..., accumulator].
int return_offset;
if (deopt_info->result_location ==
interpreter::Register::virtual_accumulator()) {
return_offset = 0;
} else if (deopt_info->result_location.is_parameter()) {
// This is slightly tricky to reason about because of zero indexing and
// fence post errors. As an example, consider a frame with 2 locals and
// 2 parameters, where we want argument index 1 -- looking at the array
// in reverse order we have:
// [acc, r1, r0, a1, a0]
// ^
// and this calculation gives, correctly:
// 2 + 2 - 1 = 3
return_offset = unit.register_count() + unit.parameter_count() -
deopt_info->result_location.ToParameterIndex();
} else {
return_offset =
unit.register_count() - deopt_info->result_location.index();
}
// TODO(leszeks): Support lazy deopts with multiple return values.
int return_count = 1;
translation_array_builder_.BeginInterpretedFrame(
deopt_info->state.bytecode_position,
GetDeoptLiteral(*unit.shared_function_info().object()),
unit.register_count(), return_offset, return_count);
EmitDeoptFrameValues(unit, deopt_info->state.register_frame,
deopt_info->input_locations,
deopt_info->result_location);
}
void EmitDeoptStoreRegister(const compiler::AllocatedOperand& operand,
ValueRepresentation repr) {
switch (repr) {
case ValueRepresentation::kTagged:
translation_array_builder_.StoreRegister(operand.GetRegister());
break;
case ValueRepresentation::kInt32:
translation_array_builder_.StoreInt32Register(operand.GetRegister());
break;
case ValueRepresentation::kFloat64:
translation_array_builder_.StoreDoubleRegister(
operand.GetDoubleRegister());
break;
}
}
void EmitDeoptStoreStackSlot(const compiler::AllocatedOperand& operand,
ValueRepresentation repr) {
int stack_slot = DeoptStackSlotFromStackSlot(operand);
switch (repr) {
case ValueRepresentation::kTagged:
translation_array_builder_.StoreStackSlot(stack_slot);
break;
case ValueRepresentation::kInt32:
translation_array_builder_.StoreInt32StackSlot(stack_slot);
break;
case ValueRepresentation::kFloat64:
translation_array_builder_.StoreDoubleStackSlot(stack_slot);
break;
}
}
void EmitDeoptFrameSingleValue(ValueNode* value,
const InputLocation& input_location) {
if (input_location.operand().IsConstant()) {
translation_array_builder_.StoreLiteral(
GetDeoptLiteral(*value->Reify(isolate())));
} else {
const compiler::AllocatedOperand& operand =
compiler::AllocatedOperand::cast(input_location.operand());
ValueRepresentation repr = value->properties().value_representation();
if (operand.IsAnyRegister()) {
EmitDeoptStoreRegister(operand, repr);
} else {
EmitDeoptStoreStackSlot(operand, repr);
}
}
}
constexpr int DeoptStackSlotIndexFromFPOffset(int offset) {
return 1 - offset / kSystemPointerSize;
}
int DeoptStackSlotFromStackSlot(const compiler::AllocatedOperand& operand) {
return DeoptStackSlotIndexFromFPOffset(
code_gen_state_.GetFramePointerOffsetForStackSlot(operand));
}
const InputLocation* EmitDeoptFrameValues(
const MaglevCompilationUnit& compilation_unit,
const CompactInterpreterFrameState* checkpoint_state,
const InputLocation* input_locations,
interpreter::Register result_location) {
// Closure
if (compilation_unit.inlining_depth() == 0) {
int closure_index = DeoptStackSlotIndexFromFPOffset(
StandardFrameConstants::kFunctionOffset);
translation_array_builder_.StoreStackSlot(closure_index);
} else {
translation_array_builder_.StoreLiteral(
GetDeoptLiteral(*compilation_unit.function().object()));
}
// TODO(leszeks): The input locations array happens to be in the same order
// as parameters+context+locals+accumulator are accessed here. We should
// make this clearer and guard against this invariant failing.
const InputLocation* input_location = input_locations;
// Parameters
{
int i = 0;
checkpoint_state->ForEachParameter(
compilation_unit, [&](ValueNode* value, interpreter::Register reg) {
DCHECK_EQ(reg.ToParameterIndex(), i);
if (reg != result_location) {
EmitDeoptFrameSingleValue(value, *input_location);
} else {
translation_array_builder_.StoreLiteral(
kOptimizedOutConstantIndex);
}
i++;
input_location++;
});
}
// Context
ValueNode* value = checkpoint_state->context(compilation_unit);
EmitDeoptFrameSingleValue(value, *input_location);
input_location++;
// Locals
{
int i = 0;
checkpoint_state->ForEachLocal(
compilation_unit, [&](ValueNode* value, interpreter::Register reg) {
DCHECK_LE(i, reg.index());
if (reg == result_location) {
input_location++;
return;
}
while (i < reg.index()) {
translation_array_builder_.StoreLiteral(
kOptimizedOutConstantIndex);
i++;
}
DCHECK_EQ(i, reg.index());
EmitDeoptFrameSingleValue(value, *input_location);
i++;
input_location++;
});
while (i < compilation_unit.register_count()) {
translation_array_builder_.StoreLiteral(kOptimizedOutConstantIndex);
i++;
}
}
// Accumulator
{
if (checkpoint_state->liveness()->AccumulatorIsLive() &&
result_location != interpreter::Register::virtual_accumulator()) {
ValueNode* value = checkpoint_state->accumulator(compilation_unit);
EmitDeoptFrameSingleValue(value, *input_location);
} else {
translation_array_builder_.StoreLiteral(kOptimizedOutConstantIndex);
}
}
return input_location;
}
void EmitMetadata() {
// Final alignment before starting on the metadata section.
masm()->Align(Code::kMetadataAlignment);
......@@ -1018,7 +777,9 @@ class MaglevCodeGeneratorImpl final {
DeoptimizationData::New(isolate(), deopt_count, AllocationType::kOld);
Handle<TranslationArray> translation_array =
translation_array_builder_.ToTranslationArray(isolate()->factory());
code_gen_state_.compilation_info()
->translation_array_builder()
.ToTranslationArray(isolate()->factory());
data->SetTranslationByteArray(*translation_array);
// TODO(leszeks): Fix with the real inlined function count.
......@@ -1036,14 +797,22 @@ class MaglevCodeGeneratorImpl final {
->shared_function_info()
.object());
IdentityMap<int, base::DefaultAllocationPolicy>& deopt_literals =
code_gen_state_.compilation_info()->deopt_literals();
Handle<DeoptimizationLiteralArray> literals =
isolate()->factory()->NewDeoptimizationLiteralArray(
deopt_literals_.size());
deopt_literals.size() + 1);
IdentityMap<int, base::DefaultAllocationPolicy>::IteratableScope iterate(
&deopt_literals_);
&deopt_literals);
for (auto it = iterate.begin(); it != iterate.end(); ++it) {
literals->set(*it.entry(), it.key());
}
// Add the bytecode to the deopt literals to make sure it's held strongly.
// TODO(leszeks): Do this for inlined functions too.
literals->set(deopt_literals.size(), *code_gen_state_.compilation_info()
->toplevel_compilation_unit()
->bytecode()
.object());
data->SetLiteralArray(*literals);
// TODO(leszeks): Fix with the real inlining positions.
......@@ -1094,25 +863,11 @@ class MaglevCodeGeneratorImpl final {
MaglevSafepointTableBuilder* safepoint_table_builder() {
return &safepoint_table_builder_;
}
TranslationArrayBuilder* translation_array_builder() {
return &translation_array_builder_;
}
int GetDeoptLiteral(Object obj) {
IdentityMapFindResult<int> res = deopt_literals_.FindOrInsert(obj);
if (!res.already_exists) {
DCHECK_EQ(0, *res.entry);
*res.entry = deopt_literals_.size() - 1;
}
return *res.entry;
}
MaglevSafepointTableBuilder safepoint_table_builder_;
TranslationArrayBuilder translation_array_builder_;
MaglevCodeGenState code_gen_state_;
GraphProcessor<MaglevCodeGeneratingNodeProcessor> processor_;
Graph* const graph_;
IdentityMap<int, base::DefaultAllocationPolicy> deopt_literals_;
int deopt_exit_start_offset_ = -1;
};
......
......@@ -11,11 +11,17 @@
#include "src/handles/maybe-handles.h"
namespace v8 {
namespace base {
class DefaultAllocationPolicy;
}
namespace internal {
class Isolate;
class PersistentHandles;
class SharedFunctionInfo;
class TranslationArrayBuilder;
class Zone;
namespace compiler {
......@@ -62,6 +68,19 @@ class MaglevCompilationInfo final {
void set_graph(Graph* graph) { graph_ = graph; }
Graph* graph() const { return graph_; }
void set_translation_array_builder(
TranslationArrayBuilder* translation_array_builder,
IdentityMap<int, base::DefaultAllocationPolicy>* deopt_literals) {
translation_array_builder_ = translation_array_builder;
deopt_literals_ = deopt_literals;
}
TranslationArrayBuilder& translation_array_builder() const {
return *translation_array_builder_;
}
IdentityMap<int, base::DefaultAllocationPolicy>& deopt_literals() const {
return *deopt_literals_;
}
// Flag accessors (for thread-safe access to global flags).
// TODO(v8:7700): Consider caching these.
#define V(Name) \
......@@ -96,6 +115,9 @@ class MaglevCompilationInfo final {
// Produced off-thread during ExecuteJobImpl.
Graph* graph_ = nullptr;
TranslationArrayBuilder* translation_array_builder_ = nullptr;
IdentityMap<int, base::DefaultAllocationPolicy>* deopt_literals_ = nullptr;
#define V(Name) const bool Name##_;
MAGLEV_COMPILATION_FLAG_LIST(V)
#undef V
......
......@@ -22,6 +22,7 @@
#include "src/compiler/compilation-dependencies.h"
#include "src/compiler/heap-refs.h"
#include "src/compiler/js-heap-broker.h"
#include "src/deoptimizer/translation-array.h"
#include "src/execution/frames.h"
#include "src/ic/handler-configuration.h"
#include "src/maglev/maglev-basic-block.h"
......@@ -39,6 +40,7 @@
#include "src/maglev/maglev-vreg-allocator.h"
#include "src/objects/code-inl.h"
#include "src/objects/js-function.h"
#include "src/utils/identity-map.h"
#include "src/zone/zone.h"
namespace v8 {
......@@ -222,6 +224,290 @@ class UseMarkingProcessor {
std::vector<LoopUsedNodes> loop_used_nodes_;
};
class TranslationArrayProcessor {
public:
explicit TranslationArrayProcessor(LocalIsolate* local_isolate)
: local_isolate_(local_isolate) {}
void PreProcessGraph(MaglevCompilationInfo* compilation_info, Graph* graph) {
translation_array_builder_ =
compilation_info->zone()->New<TranslationArrayBuilder>(
compilation_info->zone());
deopt_literals_ =
compilation_info->zone()
->New<IdentityMap<int, base::DefaultAllocationPolicy>>(
local_isolate_->heap()->heap());
tagged_slots_ = graph->tagged_stack_slots();
}
void PostProcessGraph(MaglevCompilationInfo* compilation_info, Graph* graph) {
compilation_info->set_translation_array_builder(translation_array_builder_,
deopt_literals_);
}
void PreProcessBasicBlock(MaglevCompilationInfo*, BasicBlock* block) {}
void Process(NodeBase* node, const ProcessingState& state) {
if (node->properties().can_eager_deopt()) {
EmitEagerDeopt(node->eager_deopt_info());
}
if (node->properties().can_lazy_deopt()) {
EmitLazyDeopt(node->lazy_deopt_info());
}
}
private:
const InputLocation* EmitDeoptFrame(const MaglevCompilationUnit& unit,
const CheckpointedInterpreterState& state,
const InputLocation* input_locations) {
if (state.parent) {
// Deopt input locations are in the order of deopt frame emission, so
// update the pointer after emitting the parent frame.
input_locations =
EmitDeoptFrame(*unit.caller(), *state.parent, input_locations);
}
// Returns are used for updating an accumulator or register after a lazy
// deopt.
const int return_offset = 0;
const int return_count = 0;
translation_array_builder().BeginInterpretedFrame(
state.bytecode_position,
GetDeoptLiteral(*unit.shared_function_info().object()),
unit.register_count(), return_offset, return_count);
return EmitDeoptFrameValues(unit, state.register_frame, input_locations,
interpreter::Register::invalid_value());
}
void EmitEagerDeopt(EagerDeoptInfo* deopt_info) {
int frame_count = 1 + deopt_info->unit.inlining_depth();
int jsframe_count = frame_count;
int update_feedback_count = 0;
deopt_info->translation_index =
translation_array_builder().BeginTranslation(frame_count, jsframe_count,
update_feedback_count);
EmitDeoptFrame(deopt_info->unit, deopt_info->state,
deopt_info->input_locations);
}
void EmitLazyDeopt(LazyDeoptInfo* deopt_info) {
const MaglevCompilationUnit& unit = deopt_info->unit;
DCHECK_NULL(unit.caller());
DCHECK_EQ(unit.inlining_depth(), 0);
int frame_count = 1;
int jsframe_count = 1;
int update_feedback_count = 0;
deopt_info->translation_index =
translation_array_builder().BeginTranslation(frame_count, jsframe_count,
update_feedback_count);
// Return offsets are counted from the end of the translation frame, which
// is the array [parameters..., locals..., accumulator].
int return_offset;
if (deopt_info->result_location ==
interpreter::Register::virtual_accumulator()) {
return_offset = 0;
} else if (deopt_info->result_location.is_parameter()) {
// This is slightly tricky to reason about because of zero indexing and
// fence post errors. As an example, consider a frame with 2 locals and
// 2 parameters, where we want argument index 1 -- looking at the array
// in reverse order we have:
// [acc, r1, r0, a1, a0]
// ^
// and this calculation gives, correctly:
// 2 + 2 - 1 = 3
return_offset = unit.register_count() + unit.parameter_count() -
deopt_info->result_location.ToParameterIndex();
} else {
return_offset =
unit.register_count() - deopt_info->result_location.index();
}
// TODO(leszeks): Support lazy deopts with multiple return values.
int return_count = 1;
translation_array_builder().BeginInterpretedFrame(
deopt_info->state.bytecode_position,
GetDeoptLiteral(*unit.shared_function_info().object()),
unit.register_count(), return_offset, return_count);
EmitDeoptFrameValues(unit, deopt_info->state.register_frame,
deopt_info->input_locations,
deopt_info->result_location);
}
void EmitDeoptStoreRegister(const compiler::AllocatedOperand& operand,
ValueRepresentation repr) {
switch (repr) {
case ValueRepresentation::kTagged:
translation_array_builder().StoreRegister(operand.GetRegister());
break;
case ValueRepresentation::kInt32:
translation_array_builder().StoreInt32Register(operand.GetRegister());
break;
case ValueRepresentation::kFloat64:
translation_array_builder().StoreDoubleRegister(
operand.GetDoubleRegister());
break;
}
}
void EmitDeoptStoreStackSlot(const compiler::AllocatedOperand& operand,
ValueRepresentation repr) {
int stack_slot = DeoptStackSlotFromStackSlot(operand);
switch (repr) {
case ValueRepresentation::kTagged:
translation_array_builder().StoreStackSlot(stack_slot);
break;
case ValueRepresentation::kInt32:
translation_array_builder().StoreInt32StackSlot(stack_slot);
break;
case ValueRepresentation::kFloat64:
translation_array_builder().StoreDoubleStackSlot(stack_slot);
break;
}
}
void EmitDeoptFrameSingleValue(ValueNode* value,
const InputLocation& input_location) {
if (input_location.operand().IsConstant()) {
translation_array_builder().StoreLiteral(
GetDeoptLiteral(*value->Reify(local_isolate_)));
} else {
const compiler::AllocatedOperand& operand =
compiler::AllocatedOperand::cast(input_location.operand());
ValueRepresentation repr = value->properties().value_representation();
if (operand.IsAnyRegister()) {
EmitDeoptStoreRegister(operand, repr);
} else {
EmitDeoptStoreStackSlot(operand, repr);
}
}
}
constexpr int DeoptStackSlotIndexFromFPOffset(int offset) {
return 1 - offset / kSystemPointerSize;
}
inline int GetFramePointerOffsetForStackSlot(
const compiler::AllocatedOperand& operand) {
int index = operand.index();
if (operand.representation() != MachineRepresentation::kTagged) {
index += tagged_slots_;
}
return GetFramePointerOffsetForStackSlot(index);
}
inline constexpr int GetFramePointerOffsetForStackSlot(int index) {
return StandardFrameConstants::kExpressionsOffset -
index * kSystemPointerSize;
}
int DeoptStackSlotFromStackSlot(const compiler::AllocatedOperand& operand) {
return DeoptStackSlotIndexFromFPOffset(
GetFramePointerOffsetForStackSlot(operand));
}
const InputLocation* EmitDeoptFrameValues(
const MaglevCompilationUnit& compilation_unit,
const CompactInterpreterFrameState* checkpoint_state,
const InputLocation* input_locations,
interpreter::Register result_location) {
// Closure
if (compilation_unit.inlining_depth() == 0) {
int closure_index = DeoptStackSlotIndexFromFPOffset(
StandardFrameConstants::kFunctionOffset);
translation_array_builder().StoreStackSlot(closure_index);
} else {
translation_array_builder().StoreLiteral(
GetDeoptLiteral(*compilation_unit.function().object()));
}
// TODO(leszeks): The input locations array happens to be in the same order
// as parameters+context+locals+accumulator are accessed here. We should
// make this clearer and guard against this invariant failing.
const InputLocation* input_location = input_locations;
// Parameters
{
int i = 0;
checkpoint_state->ForEachParameter(
compilation_unit, [&](ValueNode* value, interpreter::Register reg) {
DCHECK_EQ(reg.ToParameterIndex(), i);
if (reg != result_location) {
EmitDeoptFrameSingleValue(value, *input_location);
} else {
translation_array_builder().StoreOptimizedOut();
}
i++;
input_location++;
});
}
// Context
ValueNode* value = checkpoint_state->context(compilation_unit);
EmitDeoptFrameSingleValue(value, *input_location);
input_location++;
// Locals
{
int i = 0;
checkpoint_state->ForEachLocal(
compilation_unit, [&](ValueNode* value, interpreter::Register reg) {
DCHECK_LE(i, reg.index());
if (reg == result_location) {
input_location++;
return;
}
while (i < reg.index()) {
translation_array_builder().StoreOptimizedOut();
i++;
}
DCHECK_EQ(i, reg.index());
EmitDeoptFrameSingleValue(value, *input_location);
i++;
input_location++;
});
while (i < compilation_unit.register_count()) {
translation_array_builder().StoreOptimizedOut();
i++;
}
}
// Accumulator
{
if (checkpoint_state->liveness()->AccumulatorIsLive() &&
result_location != interpreter::Register::virtual_accumulator()) {
ValueNode* value = checkpoint_state->accumulator(compilation_unit);
EmitDeoptFrameSingleValue(value, *input_location);
} else {
translation_array_builder().StoreOptimizedOut();
}
}
return input_location;
}
int GetDeoptLiteral(Object obj) {
IdentityMapFindResult<int> res = deopt_literals_->FindOrInsert(obj);
if (!res.already_exists) {
DCHECK_EQ(0, *res.entry);
*res.entry = deopt_literals_->size() - 1;
}
return *res.entry;
}
TranslationArrayBuilder& translation_array_builder() {
return *translation_array_builder_;
};
LocalIsolate* local_isolate_;
TranslationArrayBuilder* translation_array_builder_;
IdentityMap<int, base::DefaultAllocationPolicy>* deopt_literals_;
int tagged_slots_;
};
// static
void MaglevCompiler::Compile(LocalIsolate* local_isolate,
MaglevCompilationInfo* compilation_info) {
......@@ -294,6 +580,10 @@ void MaglevCompiler::Compile(LocalIsolate* local_isolate,
PrintGraph(std::cout, compilation_info, graph_builder.graph());
}
GraphProcessor<TranslationArrayProcessor> build_translation_array(
compilation_info, local_isolate);
build_translation_array.ProcessGraph(graph_builder.graph());
// Stash the compiled graph on the compilation info.
compilation_info->set_graph(graph_builder.graph());
}
......
......@@ -675,7 +675,7 @@ void ValueNode::DoLoadToRegister(MaglevCodeGenState* code_gen_state,
__ Movsd(reg, code_gen_state->GetStackSlot(
compiler::AllocatedOperand::cast(spill_slot())));
}
Handle<Object> ValueNode::Reify(Isolate* isolate) {
Handle<Object> ValueNode::Reify(LocalIsolate* isolate) {
switch (opcode()) {
#define V(Name) \
case Opcode::k##Name: \
......@@ -711,7 +711,7 @@ void SmiConstant::AllocateVreg(MaglevVregAllocationState* vreg_state) {
}
void SmiConstant::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {}
Handle<Object> SmiConstant::DoReify(Isolate* isolate) {
Handle<Object> SmiConstant::DoReify(LocalIsolate* isolate) {
return handle(value_, isolate);
}
void SmiConstant::DoLoadToRegister(MaglevCodeGenState* code_gen_state,
......@@ -728,8 +728,8 @@ void Float64Constant::AllocateVreg(MaglevVregAllocationState* vreg_state) {
}
void Float64Constant::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {}
Handle<Object> Float64Constant::DoReify(Isolate* isolate) {
return isolate->factory()->NewNumber(value_);
Handle<Object> Float64Constant::DoReify(LocalIsolate* isolate) {
return isolate->factory()->NewNumber<AllocationType::kOld>(value_);
}
void Float64Constant::DoLoadToRegister(MaglevCodeGenState* code_gen_state,
DoubleRegister reg) {
......@@ -749,7 +749,9 @@ void Constant::DoLoadToRegister(MaglevCodeGenState* code_gen_state,
Register reg) {
__ Move(reg, object_.object());
}
Handle<Object> Constant::DoReify(Isolate* isolate) { return object_.object(); }
Handle<Object> Constant::DoReify(LocalIsolate* isolate) {
return object_.object();
}
void Constant::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {
os << "(" << object_ << ")";
......@@ -942,7 +944,7 @@ void RootConstant::DoLoadToRegister(MaglevCodeGenState* code_gen_state,
Register reg) {
__ LoadRoot(reg, index());
}
Handle<Object> RootConstant::DoReify(Isolate* isolate) {
Handle<Object> RootConstant::DoReify(LocalIsolate* isolate) {
return isolate->root_handle(index());
}
void RootConstant::PrintParams(std::ostream& os,
......@@ -2181,8 +2183,8 @@ void Int32Constant::DoLoadToRegister(MaglevCodeGenState* code_gen_state,
Register reg) {
__ Move(reg, Immediate(value()));
}
Handle<Object> Int32Constant::DoReify(Isolate* isolate) {
return isolate->factory()->NewNumber(value());
Handle<Object> Int32Constant::DoReify(LocalIsolate* isolate) {
return isolate->factory()->NewNumber<AllocationType::kOld>(value());
}
void Int32Constant::PrintParams(std::ostream& os,
MaglevGraphLabeller* graph_labeller) const {
......
......@@ -901,7 +901,7 @@ class ValueNode : public Node {
void LoadToRegister(MaglevCodeGenState*, DoubleRegister);
void DoLoadToRegister(MaglevCodeGenState*, Register);
void DoLoadToRegister(MaglevCodeGenState*, DoubleRegister);
Handle<Object> Reify(Isolate* isolate);
Handle<Object> Reify(LocalIsolate* isolate);
void Spill(compiler::AllocatedOperand operand) {
#ifdef DEBUG
......@@ -1502,7 +1502,7 @@ class Int32Constant : public FixedInputValueNodeT<0, Int32Constant> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
void DoLoadToRegister(MaglevCodeGenState*, OutputRegister);
Handle<Object> DoReify(Isolate* isolate);
Handle<Object> DoReify(LocalIsolate* isolate);
private:
const int32_t value_;
......@@ -1530,7 +1530,7 @@ class Float64Constant : public FixedInputValueNodeT<0, Float64Constant> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
void DoLoadToRegister(MaglevCodeGenState*, OutputRegister);
Handle<Object> DoReify(Isolate* isolate);
Handle<Object> DoReify(LocalIsolate* isolate);
private:
const double value_;
......@@ -1900,7 +1900,7 @@ class SmiConstant : public FixedInputValueNodeT<0, SmiConstant> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
void DoLoadToRegister(MaglevCodeGenState*, OutputRegister);
Handle<Object> DoReify(Isolate* isolate);
Handle<Object> DoReify(LocalIsolate* isolate);
private:
const Smi value_;
......@@ -1926,7 +1926,7 @@ class Constant : public FixedInputValueNodeT<0, Constant> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
void DoLoadToRegister(MaglevCodeGenState*, OutputRegister);
Handle<Object> DoReify(Isolate* isolate);
Handle<Object> DoReify(LocalIsolate* isolate);
private:
const compiler::HeapObjectRef object_;
......@@ -1950,7 +1950,7 @@ class RootConstant : public FixedInputValueNodeT<0, RootConstant> {
void PrintParams(std::ostream&, MaglevGraphLabeller*) const;
void DoLoadToRegister(MaglevCodeGenState*, OutputRegister);
Handle<Object> DoReify(Isolate* isolate);
Handle<Object> DoReify(LocalIsolate* isolate);
private:
const RootIndex index_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment