| Index: src/lithium.cc
|
| diff --git a/src/lithium.cc b/src/lithium.cc
|
| index fd8b7965f1d7497cb1ae29fc05636a47be7a84a3..f38cd91514383661e2445b6e222384f0792bc4f1 100644
|
| --- a/src/lithium.cc
|
| +++ b/src/lithium.cc
|
| @@ -27,6 +27,19 @@
|
|
|
| #include "v8.h"
|
| #include "lithium.h"
|
| +#include "scopes.h"
|
| +
|
| +#if V8_TARGET_ARCH_IA32
|
| +#include "ia32/lithium-ia32.h"
|
| +#elif V8_TARGET_ARCH_X64
|
| +#include "x64/lithium-x64.h"
|
| +#elif V8_TARGET_ARCH_ARM
|
| +#include "arm/lithium-arm.h"
|
| +#elif V8_TARGET_ARCH_MIPS
|
| +#include "mips/lithium-mips.h"
|
| +#else
|
| +#error "Unknown architecture."
|
| +#endif
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -240,4 +253,137 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) {
|
| }
|
|
|
|
|
| +LLabel* LChunkBase::GetLabel(int block_id) const {
|
| + HBasicBlock* block = graph_->blocks()->at(block_id);
|
| + int first_instruction = block->first_instruction_index();
|
| + return LLabel::cast(instructions_[first_instruction]);
|
| +}
|
| +
|
| +
|
| +int LChunkBase::LookupDestination(int block_id) const {
|
| + LLabel* cur = GetLabel(block_id);
|
| + while (cur->replacement() != NULL) {
|
| + cur = cur->replacement();
|
| + }
|
| + return cur->block_id();
|
| +}
|
| +
|
| +Label* LChunkBase::GetAssemblyLabel(int block_id) const {
|
| + LLabel* label = GetLabel(block_id);
|
| + ASSERT(!label->HasReplacement());
|
| + return label->label();
|
| +}
|
| +
|
| +void LChunkBase::MarkEmptyBlocks() {
|
| + HPhase phase("L_Mark empty blocks", this);
|
| + for (int i = 0; i < graph()->blocks()->length(); ++i) {
|
| + HBasicBlock* block = graph()->blocks()->at(i);
|
| + int first = block->first_instruction_index();
|
| + int last = block->last_instruction_index();
|
| + LInstruction* first_instr = instructions()->at(first);
|
| + LInstruction* last_instr = instructions()->at(last);
|
| +
|
| + LLabel* label = LLabel::cast(first_instr);
|
| + if (last_instr->IsGoto()) {
|
| + LGoto* goto_instr = LGoto::cast(last_instr);
|
| + if (label->IsRedundant() &&
|
| + !label->is_loop_header()) {
|
| + bool can_eliminate = true;
|
| + for (int i = first + 1; i < last && can_eliminate; ++i) {
|
| + LInstruction* cur = instructions()->at(i);
|
| + if (cur->IsGap()) {
|
| + LGap* gap = LGap::cast(cur);
|
| + if (!gap->IsRedundant()) {
|
| + can_eliminate = false;
|
| + }
|
| + } else {
|
| + can_eliminate = false;
|
| + }
|
| + }
|
| +
|
| + if (can_eliminate) {
|
| + label->set_replacement(GetLabel(goto_instr->block_id()));
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void LChunkBase::AddInstruction(LInstruction* instr, HBasicBlock* block) {
|
| + LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
|
| + int index = -1;
|
| + if (instr->IsControl()) {
|
| + instructions_.Add(gap, zone());
|
| + index = instructions_.length();
|
| + instructions_.Add(instr, zone());
|
| + } else {
|
| + index = instructions_.length();
|
| + instructions_.Add(instr, zone());
|
| + instructions_.Add(gap, zone());
|
| + }
|
| + if (instr->HasPointerMap()) {
|
| + pointer_maps_.Add(instr->pointer_map(), zone());
|
| + instr->pointer_map()->set_lithium_position(index);
|
| + }
|
| +}
|
| +
|
| +
|
| +LConstantOperand* LChunkBase::DefineConstantOperand(HConstant* constant) {
|
| + return LConstantOperand::Create(constant->id(), zone());
|
| +}
|
| +
|
| +
|
| +int LChunkBase::GetParameterStackSlot(int index) const {
|
| + // The receiver is at index 0, the first parameter at index 1, so we
|
| + // shift all parameter indexes down by the number of parameters, and
|
| + // make sure they end up negative so they are distinguishable from
|
| + // spill slots.
|
| + int result = index - info()->scope()->num_parameters() - 1;
|
| + ASSERT(result < 0);
|
| + return result;
|
| +}
|
| +
|
| +
|
| +// A parameter relative to ebp in the arguments stub.
|
| +int LChunkBase::ParameterAt(int index) {
|
| + ASSERT(-1 <= index); // -1 is the receiver.
|
| + return (1 + info()->scope()->num_parameters() - index) *
|
| + kPointerSize;
|
| +}
|
| +
|
| +
|
| +LGap* LChunkBase::GetGapAt(int index) const {
|
| + return LGap::cast(instructions_[index]);
|
| +}
|
| +
|
| +
|
| +bool LChunkBase::IsGapAt(int index) const {
|
| + return instructions_[index]->IsGap();
|
| +}
|
| +
|
| +
|
| +int LChunkBase::NearestGapPos(int index) const {
|
| + while (!IsGapAt(index)) index--;
|
| + return index;
|
| +}
|
| +
|
| +
|
| +void LChunkBase::AddGapMove(int index, LOperand* from, LOperand* to) {
|
| + GetGapAt(index)->GetOrCreateParallelMove(
|
| + LGap::START, zone())->AddMove(from, to, zone());
|
| +}
|
| +
|
| +
|
| +Handle<Object> LChunkBase::LookupLiteral(LConstantOperand* operand) const {
|
| + return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
|
| +}
|
| +
|
| +
|
| +Representation LChunkBase::LookupLiteralRepresentation(
|
| + LConstantOperand* operand) const {
|
| + return graph_->LookupValue(operand->index())->representation();
|
| +}
|
| +
|
| +
|
| } } // namespace v8::internal
|
|
|