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 |