blob: fcab235662627239af24725203a81811de83ee95 [file] [log] [blame]
// 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_