Crankshaft: Move LEnvironment and LPointerMap classes to platform-independent lithium.h. Move WriteTranslation method from LEnvironment class to LCodeGen class.
Review URL: http://codereview.chromium.org/6142011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6276 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b85538bc16
commit
b6ebcd58c6
@ -880,59 +880,6 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
|
||||
}
|
||||
|
||||
|
||||
void LEnvironment::WriteTranslation(LCodeGen* cgen,
|
||||
Translation* translation) const {
|
||||
if (this == NULL) return;
|
||||
|
||||
// The translation includes one command per value in the environment.
|
||||
int translation_size = values()->length();
|
||||
// The output frame height does not include the parameters.
|
||||
int height = translation_size - parameter_count();
|
||||
|
||||
outer()->WriteTranslation(cgen, translation);
|
||||
int closure_id = cgen->DefineDeoptimizationLiteral(closure());
|
||||
translation->BeginFrame(ast_id(), closure_id, height);
|
||||
for (int i = 0; i < translation_size; ++i) {
|
||||
LOperand* value = values()->at(i);
|
||||
// spilled_registers_ and spilled_double_registers_ are either
|
||||
// both NULL or both set.
|
||||
if (spilled_registers_ != NULL && value != NULL) {
|
||||
if (value->IsRegister() &&
|
||||
spilled_registers_[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
cgen->AddToTranslation(translation,
|
||||
spilled_registers_[value->index()],
|
||||
HasTaggedValueAt(i));
|
||||
} else if (value->IsDoubleRegister() &&
|
||||
spilled_double_registers_[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
cgen->AddToTranslation(translation,
|
||||
spilled_double_registers_[value->index()],
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
cgen->AddToTranslation(translation, value, HasTaggedValueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LEnvironment::PrintTo(StringStream* stream) const {
|
||||
stream->Add("[id=%d|", ast_id());
|
||||
stream->Add("[parameters=%d|", parameter_count());
|
||||
stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
|
||||
for (int i = 0; i < values_.length(); ++i) {
|
||||
if (i != 0) stream->Add(";");
|
||||
if (values_[i] == NULL) {
|
||||
stream->Add("[hole]");
|
||||
} else {
|
||||
values_[i]->PrintTo(stream);
|
||||
}
|
||||
}
|
||||
stream->Add("]");
|
||||
}
|
||||
|
||||
|
||||
LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
|
||||
if (hydrogen_env == NULL) return NULL;
|
||||
|
||||
@ -1889,21 +1836,4 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LPointerMap::RecordPointer(LOperand* op) {
|
||||
// Do not record arguments as pointers.
|
||||
if (op->IsStackSlot() && op->index() < 0) return;
|
||||
ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
|
||||
pointer_operands_.Add(op);
|
||||
}
|
||||
|
||||
|
||||
void LPointerMap::PrintTo(StringStream* stream) const {
|
||||
stream->Add("{");
|
||||
for (int i = 0; i < pointer_operands_.length(); ++i) {
|
||||
if (i != 0) stream->Add(";");
|
||||
pointer_operands_[i]->PrintTo(stream);
|
||||
}
|
||||
stream->Add("} @%d", position());
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -38,8 +38,6 @@ namespace internal {
|
||||
|
||||
// Forward declarations.
|
||||
class LCodeGen;
|
||||
class LEnvironment;
|
||||
class Translation;
|
||||
|
||||
|
||||
// Type hierarchy:
|
||||
@ -1752,108 +1750,6 @@ class LStackCheck: public LInstruction {
|
||||
};
|
||||
|
||||
|
||||
class LPointerMap: public ZoneObject {
|
||||
public:
|
||||
explicit LPointerMap(int position)
|
||||
: pointer_operands_(8), position_(position), lithium_position_(-1) { }
|
||||
|
||||
const ZoneList<LOperand*>* operands() const { return &pointer_operands_; }
|
||||
int position() const { return position_; }
|
||||
int lithium_position() const { return lithium_position_; }
|
||||
|
||||
void set_lithium_position(int pos) {
|
||||
ASSERT(lithium_position_ == -1);
|
||||
lithium_position_ = pos;
|
||||
}
|
||||
|
||||
void RecordPointer(LOperand* op);
|
||||
void PrintTo(StringStream* stream) const;
|
||||
|
||||
private:
|
||||
ZoneList<LOperand*> pointer_operands_;
|
||||
int position_;
|
||||
int lithium_position_;
|
||||
};
|
||||
|
||||
|
||||
class LEnvironment: public ZoneObject {
|
||||
public:
|
||||
LEnvironment(Handle<JSFunction> closure,
|
||||
int ast_id,
|
||||
int parameter_count,
|
||||
int argument_count,
|
||||
int value_count,
|
||||
LEnvironment* outer)
|
||||
: closure_(closure),
|
||||
arguments_stack_height_(argument_count),
|
||||
deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
|
||||
translation_index_(-1),
|
||||
ast_id_(ast_id),
|
||||
parameter_count_(parameter_count),
|
||||
values_(value_count),
|
||||
representations_(value_count),
|
||||
spilled_registers_(NULL),
|
||||
spilled_double_registers_(NULL),
|
||||
outer_(outer) {
|
||||
}
|
||||
|
||||
Handle<JSFunction> closure() const { return closure_; }
|
||||
int arguments_stack_height() const { return arguments_stack_height_; }
|
||||
int deoptimization_index() const { return deoptimization_index_; }
|
||||
int translation_index() const { return translation_index_; }
|
||||
int ast_id() const { return ast_id_; }
|
||||
int parameter_count() const { return parameter_count_; }
|
||||
const ZoneList<LOperand*>* values() const { return &values_; }
|
||||
LEnvironment* outer() const { return outer_; }
|
||||
|
||||
void AddValue(LOperand* operand, Representation representation) {
|
||||
values_.Add(operand);
|
||||
representations_.Add(representation);
|
||||
}
|
||||
|
||||
bool HasTaggedValueAt(int index) const {
|
||||
return representations_[index].IsTagged();
|
||||
}
|
||||
|
||||
void Register(int deoptimization_index, int translation_index) {
|
||||
ASSERT(!HasBeenRegistered());
|
||||
deoptimization_index_ = deoptimization_index;
|
||||
translation_index_ = translation_index;
|
||||
}
|
||||
bool HasBeenRegistered() const {
|
||||
return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex;
|
||||
}
|
||||
|
||||
void SetSpilledRegisters(LOperand** registers,
|
||||
LOperand** double_registers) {
|
||||
spilled_registers_ = registers;
|
||||
spilled_double_registers_ = double_registers;
|
||||
}
|
||||
|
||||
// Emit frame translation commands for this environment.
|
||||
void WriteTranslation(LCodeGen* cgen, Translation* translation) const;
|
||||
|
||||
void PrintTo(StringStream* stream) const;
|
||||
|
||||
private:
|
||||
Handle<JSFunction> closure_;
|
||||
int arguments_stack_height_;
|
||||
int deoptimization_index_;
|
||||
int translation_index_;
|
||||
int ast_id_;
|
||||
int parameter_count_;
|
||||
ZoneList<LOperand*> values_;
|
||||
ZoneList<Representation> representations_;
|
||||
|
||||
// Allocation index indexed arrays of spill slot operands for registers
|
||||
// that are also in spill slots at an OSR entry. NULL for environments
|
||||
// that do not correspond to an OSR entry.
|
||||
LOperand** spilled_registers_;
|
||||
LOperand** spilled_double_registers_;
|
||||
|
||||
LEnvironment* outer_;
|
||||
};
|
||||
|
||||
class LChunkBuilder;
|
||||
class LChunk: public ZoneObject {
|
||||
public:
|
||||
|
@ -324,6 +324,45 @@ MemOperand LCodeGen::ToMemOperand(LOperand* op) const {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::WriteTranslation(LEnvironment* environment,
|
||||
Translation* translation) {
|
||||
if (environment == NULL) return;
|
||||
|
||||
// The translation includes one command per value in the environment.
|
||||
int translation_size = environment->values()->length();
|
||||
// The output frame height does not include the parameters.
|
||||
int height = translation_size - environment->parameter_count();
|
||||
|
||||
WriteTranslation(environment->outer(), translation);
|
||||
int closure_id = DefineDeoptimizationLiteral(environment->closure());
|
||||
translation->BeginFrame(environment->ast_id(), closure_id, height);
|
||||
for (int i = 0; i < translation_size; ++i) {
|
||||
LOperand* value = environment->values()->at(i);
|
||||
// spilled_registers_ and spilled_double_registers_ are either
|
||||
// both NULL or both set.
|
||||
if (environment->spilled_registers() != NULL && value != NULL) {
|
||||
if (value->IsRegister() &&
|
||||
environment->spilled_registers()[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
AddToTranslation(translation,
|
||||
environment->spilled_registers()[value->index()],
|
||||
environment->HasTaggedValueAt(i));
|
||||
} else if (
|
||||
value->IsDoubleRegister() &&
|
||||
environment->spilled_double_registers()[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
AddToTranslation(
|
||||
translation,
|
||||
environment->spilled_double_registers()[value->index()],
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::AddToTranslation(Translation* translation,
|
||||
LOperand* op,
|
||||
bool is_tagged) {
|
||||
@ -439,7 +478,7 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) {
|
||||
++frame_count;
|
||||
}
|
||||
Translation translation(&translations_, frame_count);
|
||||
environment->WriteTranslation(this, &translation);
|
||||
WriteTranslation(environment, &translation);
|
||||
int deoptimization_index = deoptimizations_.length();
|
||||
environment->Register(deoptimization_index, translation.index());
|
||||
deoptimizations_.Add(environment);
|
||||
|
@ -80,6 +80,9 @@ class LCodeGen BASE_EMBEDDED {
|
||||
// Parallel move support.
|
||||
void DoParallelMove(LParallelMove* move);
|
||||
|
||||
// Emit frame translation commands for an environment.
|
||||
void WriteTranslation(LEnvironment* environment, Translation* translation);
|
||||
|
||||
// Declare methods that deal with the individual node types.
|
||||
#define DECLARE_DO(type) void Do##type(L##type* node);
|
||||
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
|
||||
|
@ -261,6 +261,45 @@ Operand LCodeGen::ToOperand(LOperand* op) const {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::WriteTranslation(LEnvironment* environment,
|
||||
Translation* translation) {
|
||||
if (environment == NULL) return;
|
||||
|
||||
// The translation includes one command per value in the environment.
|
||||
int translation_size = environment->values()->length();
|
||||
// The output frame height does not include the parameters.
|
||||
int height = translation_size - environment->parameter_count();
|
||||
|
||||
WriteTranslation(environment->outer(), translation);
|
||||
int closure_id = DefineDeoptimizationLiteral(environment->closure());
|
||||
translation->BeginFrame(environment->ast_id(), closure_id, height);
|
||||
for (int i = 0; i < translation_size; ++i) {
|
||||
LOperand* value = environment->values()->at(i);
|
||||
// spilled_registers_ and spilled_double_registers_ are either
|
||||
// both NULL or both set.
|
||||
if (environment->spilled_registers() != NULL && value != NULL) {
|
||||
if (value->IsRegister() &&
|
||||
environment->spilled_registers()[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
AddToTranslation(translation,
|
||||
environment->spilled_registers()[value->index()],
|
||||
environment->HasTaggedValueAt(i));
|
||||
} else if (
|
||||
value->IsDoubleRegister() &&
|
||||
environment->spilled_double_registers()[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
AddToTranslation(
|
||||
translation,
|
||||
environment->spilled_double_registers()[value->index()],
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::AddToTranslation(Translation* translation,
|
||||
LOperand* op,
|
||||
bool is_tagged) {
|
||||
@ -385,7 +424,7 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) {
|
||||
++frame_count;
|
||||
}
|
||||
Translation translation(&translations_, frame_count);
|
||||
environment->WriteTranslation(this, &translation);
|
||||
WriteTranslation(environment, &translation);
|
||||
int deoptimization_index = deoptimizations_.length();
|
||||
environment->Register(deoptimization_index, translation.index());
|
||||
deoptimizations_.Add(environment);
|
||||
|
@ -83,6 +83,9 @@ class LCodeGen BASE_EMBEDDED {
|
||||
// Parallel move support.
|
||||
void DoParallelMove(LParallelMove* move);
|
||||
|
||||
// Emit frame translation commands for an environment.
|
||||
void WriteTranslation(LEnvironment* environment, Translation* translation);
|
||||
|
||||
// Declare methods that deal with the individual node types.
|
||||
#define DECLARE_DO(type) void Do##type(L##type* node);
|
||||
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
|
||||
|
@ -890,59 +890,6 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
|
||||
}
|
||||
|
||||
|
||||
void LEnvironment::WriteTranslation(LCodeGen* cgen,
|
||||
Translation* translation) const {
|
||||
if (this == NULL) return;
|
||||
|
||||
// The translation includes one command per value in the environment.
|
||||
int translation_size = values()->length();
|
||||
// The output frame height does not include the parameters.
|
||||
int height = translation_size - parameter_count();
|
||||
|
||||
outer()->WriteTranslation(cgen, translation);
|
||||
int closure_id = cgen->DefineDeoptimizationLiteral(closure());
|
||||
translation->BeginFrame(ast_id(), closure_id, height);
|
||||
for (int i = 0; i < translation_size; ++i) {
|
||||
LOperand* value = values()->at(i);
|
||||
// spilled_registers_ and spilled_double_registers_ are either
|
||||
// both NULL or both set.
|
||||
if (spilled_registers_ != NULL && value != NULL) {
|
||||
if (value->IsRegister() &&
|
||||
spilled_registers_[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
cgen->AddToTranslation(translation,
|
||||
spilled_registers_[value->index()],
|
||||
HasTaggedValueAt(i));
|
||||
} else if (value->IsDoubleRegister() &&
|
||||
spilled_double_registers_[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
cgen->AddToTranslation(translation,
|
||||
spilled_double_registers_[value->index()],
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
cgen->AddToTranslation(translation, value, HasTaggedValueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LEnvironment::PrintTo(StringStream* stream) {
|
||||
stream->Add("[id=%d|", ast_id());
|
||||
stream->Add("[parameters=%d|", parameter_count());
|
||||
stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
|
||||
for (int i = 0; i < values_.length(); ++i) {
|
||||
if (i != 0) stream->Add(";");
|
||||
if (values_[i] == NULL) {
|
||||
stream->Add("[hole]");
|
||||
} else {
|
||||
values_[i]->PrintTo(stream);
|
||||
}
|
||||
}
|
||||
stream->Add("]");
|
||||
}
|
||||
|
||||
|
||||
LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
|
||||
if (hydrogen_env == NULL) return NULL;
|
||||
|
||||
@ -1922,21 +1869,4 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LPointerMap::RecordPointer(LOperand* op) {
|
||||
// Do not record arguments as pointers.
|
||||
if (op->IsStackSlot() && op->index() < 0) return;
|
||||
ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
|
||||
pointer_operands_.Add(op);
|
||||
}
|
||||
|
||||
|
||||
void LPointerMap::PrintTo(StringStream* stream) {
|
||||
stream->Add("{");
|
||||
for (int i = 0; i < pointer_operands_.length(); ++i) {
|
||||
if (i != 0) stream->Add(";");
|
||||
pointer_operands_[i]->PrintTo(stream);
|
||||
}
|
||||
stream->Add("} @%d", position());
|
||||
}
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -38,8 +38,6 @@ namespace internal {
|
||||
|
||||
// Forward declarations.
|
||||
class LCodeGen;
|
||||
class LEnvironment;
|
||||
class Translation;
|
||||
|
||||
|
||||
// Type hierarchy:
|
||||
@ -1836,108 +1834,6 @@ class LStackCheck: public LTemplateInstruction<0, 0, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LPointerMap: public ZoneObject {
|
||||
public:
|
||||
explicit LPointerMap(int position)
|
||||
: pointer_operands_(8), position_(position), lithium_position_(-1) { }
|
||||
|
||||
const ZoneList<LOperand*>* operands() const { return &pointer_operands_; }
|
||||
int position() const { return position_; }
|
||||
int lithium_position() const { return lithium_position_; }
|
||||
|
||||
void set_lithium_position(int pos) {
|
||||
ASSERT(lithium_position_ == -1);
|
||||
lithium_position_ = pos;
|
||||
}
|
||||
|
||||
void RecordPointer(LOperand* op);
|
||||
void PrintTo(StringStream* stream);
|
||||
|
||||
private:
|
||||
ZoneList<LOperand*> pointer_operands_;
|
||||
int position_;
|
||||
int lithium_position_;
|
||||
};
|
||||
|
||||
|
||||
class LEnvironment: public ZoneObject {
|
||||
public:
|
||||
LEnvironment(Handle<JSFunction> closure,
|
||||
int ast_id,
|
||||
int parameter_count,
|
||||
int argument_count,
|
||||
int value_count,
|
||||
LEnvironment* outer)
|
||||
: closure_(closure),
|
||||
arguments_stack_height_(argument_count),
|
||||
deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
|
||||
translation_index_(-1),
|
||||
ast_id_(ast_id),
|
||||
parameter_count_(parameter_count),
|
||||
values_(value_count),
|
||||
representations_(value_count),
|
||||
spilled_registers_(NULL),
|
||||
spilled_double_registers_(NULL),
|
||||
outer_(outer) {
|
||||
}
|
||||
|
||||
Handle<JSFunction> closure() const { return closure_; }
|
||||
int arguments_stack_height() const { return arguments_stack_height_; }
|
||||
int deoptimization_index() const { return deoptimization_index_; }
|
||||
int translation_index() const { return translation_index_; }
|
||||
int ast_id() const { return ast_id_; }
|
||||
int parameter_count() const { return parameter_count_; }
|
||||
const ZoneList<LOperand*>* values() const { return &values_; }
|
||||
LEnvironment* outer() const { return outer_; }
|
||||
|
||||
void AddValue(LOperand* operand, Representation representation) {
|
||||
values_.Add(operand);
|
||||
representations_.Add(representation);
|
||||
}
|
||||
|
||||
bool HasTaggedValueAt(int index) const {
|
||||
return representations_[index].IsTagged();
|
||||
}
|
||||
|
||||
void Register(int deoptimization_index, int translation_index) {
|
||||
ASSERT(!HasBeenRegistered());
|
||||
deoptimization_index_ = deoptimization_index;
|
||||
translation_index_ = translation_index;
|
||||
}
|
||||
bool HasBeenRegistered() const {
|
||||
return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex;
|
||||
}
|
||||
|
||||
void SetSpilledRegisters(LOperand** registers,
|
||||
LOperand** double_registers) {
|
||||
spilled_registers_ = registers;
|
||||
spilled_double_registers_ = double_registers;
|
||||
}
|
||||
|
||||
// Emit frame translation commands for this environment.
|
||||
void WriteTranslation(LCodeGen* cgen, Translation* translation) const;
|
||||
|
||||
void PrintTo(StringStream* stream);
|
||||
|
||||
private:
|
||||
Handle<JSFunction> closure_;
|
||||
int arguments_stack_height_;
|
||||
int deoptimization_index_;
|
||||
int translation_index_;
|
||||
int ast_id_;
|
||||
int parameter_count_;
|
||||
ZoneList<LOperand*> values_;
|
||||
ZoneList<Representation> representations_;
|
||||
|
||||
// Allocation index indexed arrays of spill slot operands for registers
|
||||
// that are also in spill slots at an OSR entry. NULL for environments
|
||||
// that do not correspond to an OSR entry.
|
||||
LOperand** spilled_registers_;
|
||||
LOperand** spilled_double_registers_;
|
||||
|
||||
LEnvironment* outer_;
|
||||
};
|
||||
|
||||
class LChunkBuilder;
|
||||
class LChunk: public ZoneObject {
|
||||
public:
|
||||
|
@ -208,4 +208,38 @@ void LParallelMove::PrintDataTo(StringStream* stream) const {
|
||||
}
|
||||
|
||||
|
||||
void LEnvironment::PrintTo(StringStream* stream) {
|
||||
stream->Add("[id=%d|", ast_id());
|
||||
stream->Add("[parameters=%d|", parameter_count());
|
||||
stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
|
||||
for (int i = 0; i < values_.length(); ++i) {
|
||||
if (i != 0) stream->Add(";");
|
||||
if (values_[i] == NULL) {
|
||||
stream->Add("[hole]");
|
||||
} else {
|
||||
values_[i]->PrintTo(stream);
|
||||
}
|
||||
}
|
||||
stream->Add("]");
|
||||
}
|
||||
|
||||
|
||||
void LPointerMap::RecordPointer(LOperand* op) {
|
||||
// Do not record arguments as pointers.
|
||||
if (op->IsStackSlot() && op->index() < 0) return;
|
||||
ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
|
||||
pointer_operands_.Add(op);
|
||||
}
|
||||
|
||||
|
||||
void LPointerMap::PrintTo(StringStream* stream) {
|
||||
stream->Add("{");
|
||||
for (int i = 0; i < pointer_operands_.length(); ++i) {
|
||||
if (i != 0) stream->Add(";");
|
||||
pointer_operands_[i]->PrintTo(stream);
|
||||
}
|
||||
stream->Add("} @%d", position());
|
||||
}
|
||||
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
109
src/lithium.h
109
src/lithium.h
@ -28,12 +28,16 @@
|
||||
#ifndef V8_LITHIUM_H_
|
||||
#define V8_LITHIUM_H_
|
||||
|
||||
#include "hydrogen.h"
|
||||
#include "lithium-allocator.h"
|
||||
#include "safepoint-table.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class LCodeGen;
|
||||
class LGapNode;
|
||||
class Translation;
|
||||
|
||||
class LGapResolver BASE_EMBEDDED {
|
||||
public:
|
||||
@ -78,6 +82,111 @@ class LParallelMove : public ZoneObject {
|
||||
};
|
||||
|
||||
|
||||
class LPointerMap: public ZoneObject {
|
||||
public:
|
||||
explicit LPointerMap(int position)
|
||||
: pointer_operands_(8), position_(position), lithium_position_(-1) { }
|
||||
|
||||
const ZoneList<LOperand*>* operands() const { return &pointer_operands_; }
|
||||
int position() const { return position_; }
|
||||
int lithium_position() const { return lithium_position_; }
|
||||
|
||||
void set_lithium_position(int pos) {
|
||||
ASSERT(lithium_position_ == -1);
|
||||
lithium_position_ = pos;
|
||||
}
|
||||
|
||||
void RecordPointer(LOperand* op);
|
||||
void PrintTo(StringStream* stream);
|
||||
|
||||
private:
|
||||
ZoneList<LOperand*> pointer_operands_;
|
||||
int position_;
|
||||
int lithium_position_;
|
||||
};
|
||||
|
||||
|
||||
class LEnvironment: public ZoneObject {
|
||||
public:
|
||||
LEnvironment(Handle<JSFunction> closure,
|
||||
int ast_id,
|
||||
int parameter_count,
|
||||
int argument_count,
|
||||
int value_count,
|
||||
LEnvironment* outer)
|
||||
: closure_(closure),
|
||||
arguments_stack_height_(argument_count),
|
||||
deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
|
||||
translation_index_(-1),
|
||||
ast_id_(ast_id),
|
||||
parameter_count_(parameter_count),
|
||||
values_(value_count),
|
||||
representations_(value_count),
|
||||
spilled_registers_(NULL),
|
||||
spilled_double_registers_(NULL),
|
||||
outer_(outer) {
|
||||
}
|
||||
|
||||
Handle<JSFunction> closure() const { return closure_; }
|
||||
int arguments_stack_height() const { return arguments_stack_height_; }
|
||||
int deoptimization_index() const { return deoptimization_index_; }
|
||||
int translation_index() const { return translation_index_; }
|
||||
int ast_id() const { return ast_id_; }
|
||||
int parameter_count() const { return parameter_count_; }
|
||||
LOperand** spilled_registers() const { return spilled_registers_; }
|
||||
LOperand** spilled_double_registers() const {
|
||||
return spilled_double_registers_;
|
||||
}
|
||||
const ZoneList<LOperand*>* values() const { return &values_; }
|
||||
LEnvironment* outer() const { return outer_; }
|
||||
|
||||
void AddValue(LOperand* operand, Representation representation) {
|
||||
values_.Add(operand);
|
||||
representations_.Add(representation);
|
||||
}
|
||||
|
||||
bool HasTaggedValueAt(int index) const {
|
||||
return representations_[index].IsTagged();
|
||||
}
|
||||
|
||||
void Register(int deoptimization_index, int translation_index) {
|
||||
ASSERT(!HasBeenRegistered());
|
||||
deoptimization_index_ = deoptimization_index;
|
||||
translation_index_ = translation_index;
|
||||
}
|
||||
bool HasBeenRegistered() const {
|
||||
return deoptimization_index_ != Safepoint::kNoDeoptimizationIndex;
|
||||
}
|
||||
|
||||
void SetSpilledRegisters(LOperand** registers,
|
||||
LOperand** double_registers) {
|
||||
spilled_registers_ = registers;
|
||||
spilled_double_registers_ = double_registers;
|
||||
}
|
||||
|
||||
void PrintTo(StringStream* stream);
|
||||
|
||||
private:
|
||||
Handle<JSFunction> closure_;
|
||||
int arguments_stack_height_;
|
||||
int deoptimization_index_;
|
||||
int translation_index_;
|
||||
int ast_id_;
|
||||
int parameter_count_;
|
||||
ZoneList<LOperand*> values_;
|
||||
ZoneList<Representation> representations_;
|
||||
|
||||
// Allocation index indexed arrays of spill slot operands for registers
|
||||
// that are also in spill slots at an OSR entry. NULL for environments
|
||||
// that do not correspond to an OSR entry.
|
||||
LOperand** spilled_registers_;
|
||||
LOperand** spilled_double_registers_;
|
||||
|
||||
LEnvironment* outer_;
|
||||
|
||||
friend class LCodegen;
|
||||
};
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
||||
#endif // V8_LITHIUM_H_
|
||||
|
@ -36,6 +36,45 @@ namespace internal {
|
||||
#define __ masm()->
|
||||
|
||||
|
||||
void LCodeGen::WriteTranslation(LEnvironment* environment,
|
||||
Translation* translation) {
|
||||
if (environment == NULL) return;
|
||||
|
||||
// The translation includes one command per value in the environment.
|
||||
int translation_size = environment->values()->length();
|
||||
// The output frame height does not include the parameters.
|
||||
int height = translation_size - environment->parameter_count();
|
||||
|
||||
WriteTranslation(environment->outer(), translation);
|
||||
int closure_id = DefineDeoptimizationLiteral(environment->closure());
|
||||
translation->BeginFrame(environment->ast_id(), closure_id, height);
|
||||
for (int i = 0; i < translation_size; ++i) {
|
||||
LOperand* value = environment->values()->at(i);
|
||||
// spilled_registers_ and spilled_double_registers_ are either
|
||||
// both NULL or both set.
|
||||
if (environment->spilled_registers() != NULL && value != NULL) {
|
||||
if (value->IsRegister() &&
|
||||
environment->spilled_registers()[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
AddToTranslation(translation,
|
||||
environment->spilled_registers()[value->index()],
|
||||
environment->HasTaggedValueAt(i));
|
||||
} else if (
|
||||
value->IsDoubleRegister() &&
|
||||
environment->spilled_double_registers()[value->index()] != NULL) {
|
||||
translation->MarkDuplicate();
|
||||
AddToTranslation(
|
||||
translation,
|
||||
environment->spilled_double_registers()[value->index()],
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
|
||||
// No code for lazy bailout instruction. Used to capture environment after a
|
||||
// call for populating the safepoint data with deoptimization data.
|
||||
|
@ -76,6 +76,9 @@ class LCodeGen BASE_EMBEDDED {
|
||||
// Parallel move support.
|
||||
void DoParallelMove(LParallelMove* move);
|
||||
|
||||
// Emit frame translation commands for an environment.
|
||||
void WriteTranslation(LEnvironment* environment, Translation* translation);
|
||||
|
||||
// Declare methods that deal with the individual node types.
|
||||
#define DECLARE_DO(type) void Do##type(L##type* node);
|
||||
LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
|
||||
@ -158,6 +161,15 @@ class LCodeGen BASE_EMBEDDED {
|
||||
void DeoptimizeIf(Condition cc, LEnvironment* environment) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void AddToTranslation(Translation* translation,
|
||||
LOperand* op,
|
||||
bool is_tagged) { UNIMPLEMENTED(); }
|
||||
|
||||
int DefineDeoptimizationLiteral(Handle<Object> literal) {
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
void PopulateDeoptimizationLiteralsWithInlinedFunctions() { UNIMPLEMENTED(); }
|
||||
|
||||
LChunk* const chunk_;
|
||||
|
@ -38,8 +38,6 @@ namespace internal {
|
||||
|
||||
// Forward declarations.
|
||||
class LCodeGen;
|
||||
class LEnvironment;
|
||||
class Translation;
|
||||
|
||||
|
||||
// Type hierarchy:
|
||||
@ -283,75 +281,6 @@ class LOsrEntry: public LTemplateInstruction<0> {
|
||||
};
|
||||
|
||||
|
||||
class LPointerMap: public ZoneObject {
|
||||
public:
|
||||
explicit LPointerMap(int position)
|
||||
: pointer_operands_(8), position_(position), lithium_position_(-1) { }
|
||||
|
||||
int lithium_position() const {
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RecordPointer(LOperand* op) { UNIMPLEMENTED(); }
|
||||
|
||||
private:
|
||||
ZoneList<LOperand*> pointer_operands_;
|
||||
int position_;
|
||||
int lithium_position_;
|
||||
};
|
||||
|
||||
|
||||
class LEnvironment: public ZoneObject {
|
||||
public:
|
||||
LEnvironment(Handle<JSFunction> closure,
|
||||
int ast_id,
|
||||
int parameter_count,
|
||||
int argument_count,
|
||||
int value_count,
|
||||
LEnvironment* outer)
|
||||
: closure_(closure),
|
||||
arguments_stack_height_(argument_count),
|
||||
deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
|
||||
translation_index_(-1),
|
||||
ast_id_(ast_id),
|
||||
parameter_count_(parameter_count),
|
||||
values_(value_count),
|
||||
representations_(value_count),
|
||||
spilled_registers_(NULL),
|
||||
spilled_double_registers_(NULL),
|
||||
outer_(outer) {
|
||||
}
|
||||
|
||||
Handle<JSFunction> closure() const { return closure_; }
|
||||
int arguments_stack_height() const { return arguments_stack_height_; }
|
||||
int deoptimization_index() const { return deoptimization_index_; }
|
||||
int translation_index() const { return translation_index_; }
|
||||
int ast_id() const { return ast_id_; }
|
||||
int parameter_count() const { return parameter_count_; }
|
||||
const ZoneList<LOperand*>* values() const { return &values_; }
|
||||
LEnvironment* outer() const { return outer_; }
|
||||
|
||||
private:
|
||||
Handle<JSFunction> closure_;
|
||||
int arguments_stack_height_;
|
||||
int deoptimization_index_;
|
||||
int translation_index_;
|
||||
int ast_id_;
|
||||
int parameter_count_;
|
||||
ZoneList<LOperand*> values_;
|
||||
ZoneList<Representation> representations_;
|
||||
|
||||
// Allocation index indexed arrays of spill slot operands for registers
|
||||
// that are also in spill slots at an OSR entry. NULL for environments
|
||||
// that do not correspond to an OSR entry.
|
||||
LOperand** spilled_registers_;
|
||||
LOperand** spilled_double_registers_;
|
||||
|
||||
LEnvironment* outer_;
|
||||
};
|
||||
|
||||
|
||||
class LChunkBuilder;
|
||||
class LChunk: public ZoneObject {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user