diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index e79214b822..4940b2c5bd 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -85,10 +85,12 @@ class Translation; // LConstantT // LDeoptimize // LFunctionLiteral +// LGap +// LLabel // LGlobalObject // LGlobalReceiver -// LLabel -// LLayzBailout +// LGoto +// LLazyBailout // LLoadGlobal // LMaterializedLiteral // LArrayLiteral diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 3e0cfdd753..7957381238 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -31,6 +31,67 @@ namespace v8 { namespace internal { +LOsrEntry::LOsrEntry() { + for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { + register_spills_[i] = NULL; + } + for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { + double_register_spills_[i] = NULL; + } +} + + +void LOsrEntry::MarkSpilledRegister(int allocation_index, + LOperand* spill_operand) { + ASSERT(spill_operand->IsStackSlot()); + ASSERT(register_spills_[allocation_index] == NULL); + register_spills_[allocation_index] = spill_operand; +} + + +void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, + LOperand* spill_operand) { + ASSERT(spill_operand->IsDoubleStackSlot()); + ASSERT(double_register_spills_[allocation_index] == NULL); + double_register_spills_[allocation_index] = spill_operand; +} + + +void LOsrEntry::CompileToNative(LCodeGen* generator) { + UNIMPLEMENTED(); + // Implement in lithium-codegen-x64.cc. +} + + +void LInstruction::PrintTo(StringStream* stream) { + stream->Add("%s ", this->Mnemonic()); + if (HasResult()) { + LTemplateInstruction<1>::cast(this)->result()->PrintTo(stream); + stream->Add(" "); + } + PrintDataTo(stream); + + if (HasEnvironment()) { + stream->Add(" "); + // environment()->PrintTo(stream); + } + + if (HasPointerMap()) { + stream->Add(" "); + //pointer_map()->PrintTo(stream); + } +} + + +void LLabel::PrintDataTo(StringStream* stream) { + LGap::PrintDataTo(stream); + LLabel* rep = replacement(); + if (rep != NULL) { + stream->Add(" Dead block replaced with B%d", rep->block_id()); + } +} + + bool LGap::IsRedundant() const { for (int i = 0; i < 4; i++) { if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) { @@ -42,7 +103,7 @@ bool LGap::IsRedundant() const { } -void LGap::PrintDataTo(StringStream* stream) const { +void LGap::PrintDataTo(StringStream* stream) { for (int i = 0; i < 4; i++) { stream->Add("("); if (parallel_moves_[i] != NULL) { @@ -53,6 +114,11 @@ void LGap::PrintDataTo(StringStream* stream) const { } +void LGoto::PrintDataTo(StringStream* stream) { + stream->Add("B%d", block_id()); +} + + LChunk* LChunkBuilder::Build() { ASSERT(is_unused()); chunk_ = new LChunk(graph()); diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 24577cba1e..7d9a4af3d1 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -45,13 +45,23 @@ class Translation; // Type hierarchy: // // LInstruction +// LDeoptimize // LGap +// LLabel +// LGoto +// LLazyBailout +// LOsrEntry #define LITHIUM_ALL_INSTRUCTION_LIST(V) \ LITHIUM_CONCRETE_INSTRUCTION_LIST(V) #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ - V(Gap) + V(Deoptimize) \ + V(Gap) \ + V(Goto) \ + V(Label) \ + V(LazyBailout) \ + V(OsrEntry) #define DECLARE_INSTRUCTION(type) \ @@ -80,20 +90,10 @@ class LInstruction: public ZoneObject { : hydrogen_value_(NULL) { } virtual ~LInstruction() { } - // Predicates should be generated by macro as in lithium-ia32.h. - virtual bool IsLabel() const { - UNIMPLEMENTED(); - return false; - } - virtual bool IsOsrEntry() const { - UNIMPLEMENTED(); - return false; - } - virtual void CompileToNative(LCodeGen* generator) = 0; virtual const char* Mnemonic() const = 0; - virtual void PrintTo(StringStream* stream) const; - virtual void PrintDataTo(StringStream* stream) const { } + virtual void PrintTo(StringStream* stream); + virtual void PrintDataTo(StringStream* stream) { } // Declare virtual type testers. #define DECLARE_DO(type) virtual bool Is##type() const { return false; } @@ -109,9 +109,7 @@ class LInstruction: public ZoneObject { LPointerMap* pointer_map() const { return pointer_map_.get(); } bool HasPointerMap() const { return pointer_map_.is_set(); } - void set_result(LOperand* operand) { result_.set(operand); } - LOperand* result() const { return result_.get(); } - bool HasResult() const { return result_.is_set(); } + virtual bool HasResult() const = 0; void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } HValue* hydrogen_value() const { return hydrogen_value_; } @@ -129,13 +127,37 @@ class LInstruction: public ZoneObject { private: SetOncePointer environment_; SetOncePointer pointer_map_; - SetOncePointer result_; HValue* hydrogen_value_; SetOncePointer deoptimization_environment_; }; -class LGap: public LInstruction { +template +class LTemplateInstruction: public LInstruction { }; + + +template<> +class LTemplateInstruction<0>: public LInstruction { + virtual bool HasResult() const { return false; } +}; + + +template<> +class LTemplateInstruction<1>: public LInstruction { + public: + static LTemplateInstruction<1>* cast(LInstruction* instr) { + ASSERT(instr->HasResult()); + return reinterpret_cast*>(instr); + } + void set_result(LOperand* operand) { result_.set(operand); } + LOperand* result() const { return result_.get(); } + virtual bool HasResult() const { return result_.is_set(); } + private: + SetOncePointer result_; +}; + + +class LGap: public LTemplateInstruction<0> { public: explicit LGap(HBasicBlock* block) : block_(block) { @@ -146,7 +168,7 @@ class LGap: public LInstruction { } DECLARE_CONCRETE_INSTRUCTION(Gap, "gap") - virtual void PrintDataTo(StringStream* stream) const; + virtual void PrintDataTo(StringStream* stream); bool IsRedundant() const; @@ -176,9 +198,61 @@ class LGap: public LInstruction { }; +class LGoto: public LTemplateInstruction<0> { + public: + LGoto(int block_id, bool include_stack_check = false) + : block_id_(block_id), include_stack_check_(include_stack_check) { } + + DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") + virtual void PrintDataTo(StringStream* stream); + virtual bool IsControl() const { return true; } + + int block_id() const { return block_id_; } + bool include_stack_check() const { return include_stack_check_; } + + private: + int block_id_; + bool include_stack_check_; +}; + + +class LLazyBailout: public LTemplateInstruction<0> { + public: + LLazyBailout() : gap_instructions_size_(0) { } + + DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") + + void set_gap_instructions_size(int gap_instructions_size) { + gap_instructions_size_ = gap_instructions_size; + } + int gap_instructions_size() { return gap_instructions_size_; } + + private: + int gap_instructions_size_; +}; + + +class LDeoptimize: public LTemplateInstruction<0> { + public: + DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") +}; + + class LLabel: public LGap { public: - explicit LLabel(HBasicBlock* block) : LGap(block) { } + explicit LLabel(HBasicBlock* block) + : LGap(block), replacement_(NULL) { } + + DECLARE_CONCRETE_INSTRUCTION(Label, "label") + + virtual void PrintDataTo(StringStream* stream); + + int block_id() const { return block()->block_id(); } + bool is_loop_header() const { return block()->IsLoopHeader(); } + Label* label() { return &label_; } + LLabel* replacement() const { return replacement_; } + void set_replacement(LLabel* label) { replacement_ = label; } + bool HasReplacement() const { return replacement_ != NULL; } private: Label label_; @@ -186,30 +260,18 @@ class LLabel: public LGap { }; -class LOsrEntry: public LInstruction { +class LOsrEntry: public LTemplateInstruction<0> { public: - // Function could be generated by a macro as in lithium-ia32.h. - static LOsrEntry* cast(LInstruction* instr) { - UNIMPLEMENTED(); - return NULL; - } + LOsrEntry(); - LOperand** SpilledRegisterArray() { - UNIMPLEMENTED(); - return NULL; - } - LOperand** SpilledDoubleRegisterArray() { - UNIMPLEMENTED(); - return NULL; - } + DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") - void MarkSpilledRegister(int allocation_index, LOperand* spill_operand) { - UNIMPLEMENTED(); - } + LOperand** SpilledRegisterArray() { return register_spills_; } + LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; } + + void MarkSpilledRegister(int allocation_index, LOperand* spill_operand); void MarkSpilledDoubleRegister(int allocation_index, - LOperand* spill_operand) { - UNIMPLEMENTED(); - } + LOperand* spill_operand); private: // Arrays of spill slot operands for registers with an assigned spill