| // Copyright 2011 the V8 project authors. All rights reserved. |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following |
| // disclaimer in the documentation and/or other materials provided |
| // with the distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived |
| // from this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #ifndef V8_X64_LITHIUM_X64_H_ |
| #define V8_X64_LITHIUM_X64_H_ |
| |
| #include "hydrogen.h" |
| #include "lithium-allocator.h" |
| #include "lithium.h" |
| #include "safepoint-table.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| // Forward declarations. |
| class LCodeGen; |
| class LEnvironment; |
| class Translation; |
| |
| class LInstruction: public ZoneObject { |
| public: |
| LInstruction() { } |
| virtual ~LInstruction() { } |
| |
| virtual void PrintTo(StringStream* stream) const { UNIMPLEMENTED(); } |
| virtual void PrintDataTo(StringStream* stream) const { } |
| |
| // 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; |
| } |
| |
| void set_environment(LEnvironment* env) { environment_.set(env); } |
| LEnvironment* environment() const { return environment_.get(); } |
| bool HasEnvironment() const { return environment_.is_set(); } |
| |
| void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } |
| 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(); } |
| |
| void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } |
| HValue* hydrogen_value() const { return hydrogen_value_; } |
| |
| void set_deoptimization_environment(LEnvironment* env) { |
| deoptimization_environment_.set(env); |
| } |
| LEnvironment* deoptimization_environment() const { |
| return deoptimization_environment_.get(); |
| } |
| bool HasDeoptimizationEnvironment() const { |
| return deoptimization_environment_.is_set(); |
| } |
| |
| private: |
| SetOncePointer<LEnvironment> environment_; |
| SetOncePointer<LPointerMap> pointer_map_; |
| SetOncePointer<LOperand> result_; |
| HValue* hydrogen_value_; |
| SetOncePointer<LEnvironment> deoptimization_environment_; |
| }; |
| |
| |
| class LParallelMove : public ZoneObject { |
| public: |
| LParallelMove() : move_operands_(4) { } |
| |
| void AddMove(LOperand* from, LOperand* to) { |
| UNIMPLEMENTED(); |
| } |
| |
| const ZoneList<LMoveOperands>* move_operands() const { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| private: |
| ZoneList<LMoveOperands> move_operands_; |
| }; |
| |
| |
| class LGap: public LInstruction { |
| public: |
| explicit LGap(HBasicBlock* block) { } |
| |
| HBasicBlock* block() const { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| enum InnerPosition { |
| BEFORE, |
| START, |
| END, |
| AFTER, |
| FIRST_INNER_POSITION = BEFORE, |
| LAST_INNER_POSITION = AFTER |
| }; |
| |
| LParallelMove* GetOrCreateParallelMove(InnerPosition pos) { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| LParallelMove* GetParallelMove(InnerPosition pos) { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| private: |
| LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; |
| HBasicBlock* block_; |
| }; |
| |
| |
| class LLabel: public LGap { |
| public: |
| explicit LLabel(HBasicBlock* block) : LGap(block) { } |
| |
| private: |
| Label label_; |
| LLabel* replacement_; |
| }; |
| |
| |
| class LOsrEntry: public LInstruction { |
| public: |
| // Function could be generated by a macro as in lithium-ia32.h. |
| static LOsrEntry* cast(LInstruction* instr) { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| LOperand** SpilledRegisterArray() { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| LOperand** SpilledDoubleRegisterArray() { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| void MarkSpilledRegister(int allocation_index, LOperand* spill_operand) { |
| UNIMPLEMENTED(); |
| } |
| void MarkSpilledDoubleRegister(int allocation_index, |
| LOperand* spill_operand) { |
| UNIMPLEMENTED(); |
| } |
| |
| private: |
| // Arrays of spill slot operands for registers with an assigned spill |
| // slot, i.e., that must also be restored to the spill slot on OSR entry. |
| // NULL if the register has no assigned spill slot. Indexed by allocation |
| // index. |
| LOperand* register_spills_[Register::kNumAllocatableRegisters]; |
| LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; |
| }; |
| |
| |
| 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: |
| explicit LChunk(HGraph* graph) |
| : spill_slot_count_(0), |
| graph_(graph), |
| instructions_(32), |
| pointer_maps_(8), |
| inlined_closures_(1) { } |
| |
| int spill_slot_count() const { return spill_slot_count_; } |
| HGraph* graph() const { return graph_; } |
| const ZoneList<LInstruction*>* instructions() const { return &instructions_; } |
| const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; } |
| const ZoneList<Handle<JSFunction> >* inlined_closures() const { |
| return &inlined_closures_; |
| } |
| |
| LOperand* GetNextSpillSlot(bool double_slot) { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| LConstantOperand* DefineConstantOperand(HConstant* constant) { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| LLabel* GetLabel(int block_id) const { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| int GetParameterStackSlot(int index) const { |
| UNIMPLEMENTED(); |
| return 0; |
| } |
| |
| void AddGapMove(int index, LOperand* from, LOperand* to) { UNIMPLEMENTED(); } |
| |
| LGap* GetGapAt(int index) const { |
| UNIMPLEMENTED(); |
| return NULL; |
| } |
| |
| bool IsGapAt(int index) const { |
| UNIMPLEMENTED(); |
| return false; |
| } |
| |
| int NearestGapPos(int index) const { |
| UNIMPLEMENTED(); |
| return 0; |
| } |
| |
| void MarkEmptyBlocks() { UNIMPLEMENTED(); } |
| |
| #ifdef DEBUG |
| void Verify() { } |
| #endif |
| |
| private: |
| int spill_slot_count_; |
| HGraph* const graph_; |
| ZoneList<LInstruction*> instructions_; |
| ZoneList<LPointerMap*> pointer_maps_; |
| ZoneList<Handle<JSFunction> > inlined_closures_; |
| }; |
| |
| |
| class LChunkBuilder BASE_EMBEDDED { |
| public: |
| LChunkBuilder(HGraph* graph, LAllocator* allocator) |
| : chunk_(NULL), |
| graph_(graph), |
| status_(UNUSED), |
| current_instruction_(NULL), |
| current_block_(NULL), |
| next_block_(NULL), |
| argument_count_(0), |
| allocator_(allocator), |
| position_(RelocInfo::kNoPosition), |
| instructions_pending_deoptimization_environment_(NULL), |
| pending_deoptimization_ast_id_(AstNode::kNoNumber) { } |
| |
| // Build the sequence for the graph. |
| LChunk* Build(); |
| |
| // Declare methods that deal with the individual node types. |
| #define DECLARE_DO(type) LInstruction* Do##type(H##type* node) { \ |
| UNIMPLEMENTED(); \ |
| return NULL; \ |
| } |
| HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) |
| #undef DECLARE_DO |
| |
| private: |
| enum Status { |
| UNUSED, |
| BUILDING, |
| DONE, |
| ABORTED |
| }; |
| |
| LChunk* chunk() const { return chunk_; } |
| HGraph* graph() const { return graph_; } |
| |
| bool is_unused() const { return status_ == UNUSED; } |
| bool is_building() const { return status_ == BUILDING; } |
| bool is_done() const { return status_ == DONE; } |
| bool is_aborted() const { return status_ == ABORTED; } |
| |
| void Abort(const char* format, ...); |
| |
| void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); |
| |
| LChunk* chunk_; |
| HGraph* const graph_; |
| Status status_; |
| HInstruction* current_instruction_; |
| HBasicBlock* current_block_; |
| HBasicBlock* next_block_; |
| int argument_count_; |
| LAllocator* allocator_; |
| int position_; |
| LInstruction* instructions_pending_deoptimization_environment_; |
| int pending_deoptimization_ast_id_; |
| |
| DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |
| }; |
| |
| |
| } } // namespace v8::internal |
| |
| #endif // V8_X64_LITHIUM_X64_H_ |