lithium-x64.h revision 086aeeaae12517475c22695a200be45495516549
1// Copyright 2011 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_X64_LITHIUM_X64_H_
29#define V8_X64_LITHIUM_X64_H_
30
31#include "hydrogen.h"
32#include "lithium-allocator.h"
33#include "lithium.h"
34#include "safepoint-table.h"
35
36namespace v8 {
37namespace internal {
38
39// Forward declarations.
40class LCodeGen;
41class LEnvironment;
42class Translation;
43
44class LInstruction: public ZoneObject {
45 public:
46  LInstruction() { }
47  virtual ~LInstruction() { }
48
49  virtual void PrintTo(StringStream* stream) const { UNIMPLEMENTED(); }
50  virtual void PrintDataTo(StringStream* stream) const { }
51
52  // Predicates should be generated by macro as in lithium-ia32.h.
53  virtual bool IsLabel() const {
54    UNIMPLEMENTED();
55    return false;
56  }
57  virtual bool IsOsrEntry() const {
58    UNIMPLEMENTED();
59    return false;
60  }
61
62  void set_environment(LEnvironment* env) { environment_.set(env); }
63  LEnvironment* environment() const { return environment_.get(); }
64  bool HasEnvironment() const { return environment_.is_set(); }
65
66  void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
67  LPointerMap* pointer_map() const { return pointer_map_.get(); }
68  bool HasPointerMap() const { return pointer_map_.is_set(); }
69
70  void set_result(LOperand* operand) { result_.set(operand); }
71  LOperand* result() const { return result_.get(); }
72  bool HasResult() const { return result_.is_set(); }
73
74  void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
75  HValue* hydrogen_value() const { return hydrogen_value_; }
76
77  void set_deoptimization_environment(LEnvironment* env) {
78    deoptimization_environment_.set(env);
79  }
80  LEnvironment* deoptimization_environment() const {
81    return deoptimization_environment_.get();
82  }
83  bool HasDeoptimizationEnvironment() const {
84    return deoptimization_environment_.is_set();
85  }
86
87 private:
88  SetOncePointer<LEnvironment> environment_;
89  SetOncePointer<LPointerMap> pointer_map_;
90  SetOncePointer<LOperand> result_;
91  HValue* hydrogen_value_;
92  SetOncePointer<LEnvironment> deoptimization_environment_;
93};
94
95
96class LParallelMove : public ZoneObject {
97 public:
98  LParallelMove() : move_operands_(4) { }
99
100  void AddMove(LOperand* from, LOperand* to) {
101    UNIMPLEMENTED();
102  }
103
104  const ZoneList<LMoveOperands>* move_operands() const {
105    UNIMPLEMENTED();
106    return NULL;
107  }
108
109 private:
110  ZoneList<LMoveOperands> move_operands_;
111};
112
113
114class LGap: public LInstruction {
115 public:
116  explicit LGap(HBasicBlock* block) { }
117
118  HBasicBlock* block() const {
119    UNIMPLEMENTED();
120    return NULL;
121  }
122
123  enum InnerPosition {
124    BEFORE,
125    START,
126    END,
127    AFTER,
128    FIRST_INNER_POSITION = BEFORE,
129    LAST_INNER_POSITION = AFTER
130  };
131
132  LParallelMove* GetOrCreateParallelMove(InnerPosition pos) {
133    UNIMPLEMENTED();
134    return NULL;
135  }
136
137  LParallelMove* GetParallelMove(InnerPosition pos)  {
138    UNIMPLEMENTED();
139    return NULL;
140  }
141
142 private:
143  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
144  HBasicBlock* block_;
145};
146
147
148class LLabel: public LGap {
149 public:
150  explicit LLabel(HBasicBlock* block) : LGap(block) { }
151
152 private:
153  Label label_;
154  LLabel* replacement_;
155};
156
157
158class LOsrEntry: public LInstruction {
159 public:
160  // Function could be generated by a macro as in lithium-ia32.h.
161  static LOsrEntry* cast(LInstruction* instr) {
162    UNIMPLEMENTED();
163    return NULL;
164  }
165
166  LOperand** SpilledRegisterArray() {
167    UNIMPLEMENTED();
168    return NULL;
169  }
170  LOperand** SpilledDoubleRegisterArray() {
171    UNIMPLEMENTED();
172    return NULL;
173  }
174
175  void MarkSpilledRegister(int allocation_index, LOperand* spill_operand) {
176    UNIMPLEMENTED();
177  }
178  void MarkSpilledDoubleRegister(int allocation_index,
179                                 LOperand* spill_operand) {
180    UNIMPLEMENTED();
181  }
182
183 private:
184  // Arrays of spill slot operands for registers with an assigned spill
185  // slot, i.e., that must also be restored to the spill slot on OSR entry.
186  // NULL if the register has no assigned spill slot.  Indexed by allocation
187  // index.
188  LOperand* register_spills_[Register::kNumAllocatableRegisters];
189  LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters];
190};
191
192
193class LPointerMap: public ZoneObject {
194 public:
195  explicit LPointerMap(int position)
196      : pointer_operands_(8), position_(position), lithium_position_(-1) { }
197
198  int lithium_position() const {
199    UNIMPLEMENTED();
200    return 0;
201  }
202
203  void RecordPointer(LOperand* op) { UNIMPLEMENTED(); }
204
205 private:
206  ZoneList<LOperand*> pointer_operands_;
207  int position_;
208  int lithium_position_;
209};
210
211
212class LEnvironment: public ZoneObject {
213 public:
214  LEnvironment(Handle<JSFunction> closure,
215               int ast_id,
216               int parameter_count,
217               int argument_count,
218               int value_count,
219               LEnvironment* outer)
220      : closure_(closure),
221        arguments_stack_height_(argument_count),
222        deoptimization_index_(Safepoint::kNoDeoptimizationIndex),
223        translation_index_(-1),
224        ast_id_(ast_id),
225        parameter_count_(parameter_count),
226        values_(value_count),
227        representations_(value_count),
228        spilled_registers_(NULL),
229        spilled_double_registers_(NULL),
230        outer_(outer) {
231  }
232
233  Handle<JSFunction> closure() const { return closure_; }
234  int arguments_stack_height() const { return arguments_stack_height_; }
235  int deoptimization_index() const { return deoptimization_index_; }
236  int translation_index() const { return translation_index_; }
237  int ast_id() const { return ast_id_; }
238  int parameter_count() const { return parameter_count_; }
239  const ZoneList<LOperand*>* values() const { return &values_; }
240  LEnvironment* outer() const { return outer_; }
241
242 private:
243  Handle<JSFunction> closure_;
244  int arguments_stack_height_;
245  int deoptimization_index_;
246  int translation_index_;
247  int ast_id_;
248  int parameter_count_;
249  ZoneList<LOperand*> values_;
250  ZoneList<Representation> representations_;
251
252  // Allocation index indexed arrays of spill slot operands for registers
253  // that are also in spill slots at an OSR entry.  NULL for environments
254  // that do not correspond to an OSR entry.
255  LOperand** spilled_registers_;
256  LOperand** spilled_double_registers_;
257
258  LEnvironment* outer_;
259};
260
261
262class LChunkBuilder;
263class LChunk: public ZoneObject {
264 public:
265  explicit LChunk(HGraph* graph)
266    : spill_slot_count_(0),
267      graph_(graph),
268      instructions_(32),
269      pointer_maps_(8),
270      inlined_closures_(1) { }
271
272  int spill_slot_count() const { return spill_slot_count_; }
273  HGraph* graph() const { return graph_; }
274  const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
275  const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
276  const ZoneList<Handle<JSFunction> >* inlined_closures() const {
277    return &inlined_closures_;
278  }
279
280  LOperand* GetNextSpillSlot(bool double_slot) {
281    UNIMPLEMENTED();
282    return NULL;
283  }
284
285  LConstantOperand* DefineConstantOperand(HConstant* constant) {
286    UNIMPLEMENTED();
287    return NULL;
288  }
289
290  LLabel* GetLabel(int block_id) const {
291    UNIMPLEMENTED();
292    return NULL;
293  }
294
295  int GetParameterStackSlot(int index) const {
296    UNIMPLEMENTED();
297    return 0;
298  }
299
300  void AddGapMove(int index, LOperand* from, LOperand* to) { UNIMPLEMENTED(); }
301
302  LGap* GetGapAt(int index) const {
303    UNIMPLEMENTED();
304    return NULL;
305  }
306
307  bool IsGapAt(int index) const {
308    UNIMPLEMENTED();
309    return false;
310  }
311
312  int NearestGapPos(int index) const {
313    UNIMPLEMENTED();
314    return 0;
315  }
316
317  void MarkEmptyBlocks() { UNIMPLEMENTED(); }
318
319#ifdef DEBUG
320  void Verify() { }
321#endif
322
323 private:
324  int spill_slot_count_;
325  HGraph* const graph_;
326  ZoneList<LInstruction*> instructions_;
327  ZoneList<LPointerMap*> pointer_maps_;
328  ZoneList<Handle<JSFunction> > inlined_closures_;
329};
330
331
332class LChunkBuilder BASE_EMBEDDED {
333 public:
334  LChunkBuilder(HGraph* graph, LAllocator* allocator)
335      : chunk_(NULL),
336        graph_(graph),
337        status_(UNUSED),
338        current_instruction_(NULL),
339        current_block_(NULL),
340        next_block_(NULL),
341        argument_count_(0),
342        allocator_(allocator),
343        position_(RelocInfo::kNoPosition),
344        instructions_pending_deoptimization_environment_(NULL),
345        pending_deoptimization_ast_id_(AstNode::kNoNumber) { }
346
347  // Build the sequence for the graph.
348  LChunk* Build();
349
350  // Declare methods that deal with the individual node types.
351#define DECLARE_DO(type) LInstruction* Do##type(H##type* node) { \
352    UNIMPLEMENTED(); \
353    return NULL; \
354  }
355  HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
356#undef DECLARE_DO
357
358 private:
359  enum Status {
360    UNUSED,
361    BUILDING,
362    DONE,
363    ABORTED
364  };
365
366  LChunk* chunk() const { return chunk_; }
367  HGraph* graph() const { return graph_; }
368
369  bool is_unused() const { return status_ == UNUSED; }
370  bool is_building() const { return status_ == BUILDING; }
371  bool is_done() const { return status_ == DONE; }
372  bool is_aborted() const { return status_ == ABORTED; }
373
374  void Abort(const char* format, ...);
375
376  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
377
378  LChunk* chunk_;
379  HGraph* const graph_;
380  Status status_;
381  HInstruction* current_instruction_;
382  HBasicBlock* current_block_;
383  HBasicBlock* next_block_;
384  int argument_count_;
385  LAllocator* allocator_;
386  int position_;
387  LInstruction* instructions_pending_deoptimization_environment_;
388  int pending_deoptimization_ast_id_;
389
390  DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
391};
392
393
394} }  // namespace v8::internal
395
396#endif  // V8_X64_LITHIUM_X64_H_
397