| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 // Forward declarations. | 39 // Forward declarations. |
| 40 class LCodeGen; | 40 class LCodeGen; |
| 41 class LEnvironment; | 41 class LEnvironment; |
| 42 class Translation; | 42 class Translation; |
| 43 | 43 |
| 44 | 44 |
| 45 // Type hierarchy: | 45 // Type hierarchy: |
| 46 // | 46 // |
| 47 // LInstruction | 47 // LInstruction |
| 48 // LDeoptimize |
| 48 // LGap | 49 // LGap |
| 50 // LLabel |
| 51 // LGoto |
| 52 // LLazyBailout |
| 53 // LOsrEntry |
| 49 | 54 |
| 50 #define LITHIUM_ALL_INSTRUCTION_LIST(V) \ | 55 #define LITHIUM_ALL_INSTRUCTION_LIST(V) \ |
| 51 LITHIUM_CONCRETE_INSTRUCTION_LIST(V) | 56 LITHIUM_CONCRETE_INSTRUCTION_LIST(V) |
| 52 | 57 |
| 53 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ | 58 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \ |
| 54 V(Gap) | 59 V(Deoptimize) \ |
| 60 V(Gap) \ |
| 61 V(Goto) \ |
| 62 V(Label) \ |
| 63 V(LazyBailout) \ |
| 64 V(OsrEntry) |
| 55 | 65 |
| 56 | 66 |
| 57 #define DECLARE_INSTRUCTION(type) \ | 67 #define DECLARE_INSTRUCTION(type) \ |
| 58 virtual bool Is##type() const { return true; } \ | 68 virtual bool Is##type() const { return true; } \ |
| 59 static L##type* cast(LInstruction* instr) { \ | 69 static L##type* cast(LInstruction* instr) { \ |
| 60 ASSERT(instr->Is##type()); \ | 70 ASSERT(instr->Is##type()); \ |
| 61 return reinterpret_cast<L##type*>(instr); \ | 71 return reinterpret_cast<L##type*>(instr); \ |
| 62 } | 72 } |
| 63 | 73 |
| 64 | 74 |
| 65 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ | 75 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \ |
| 66 virtual void CompileToNative(LCodeGen* generator); \ | 76 virtual void CompileToNative(LCodeGen* generator); \ |
| 67 virtual const char* Mnemonic() const { return mnemonic; } \ | 77 virtual const char* Mnemonic() const { return mnemonic; } \ |
| 68 DECLARE_INSTRUCTION(type) | 78 DECLARE_INSTRUCTION(type) |
| 69 | 79 |
| 70 | 80 |
| 71 #define DECLARE_HYDROGEN_ACCESSOR(type) \ | 81 #define DECLARE_HYDROGEN_ACCESSOR(type) \ |
| 72 H##type* hydrogen() const { \ | 82 H##type* hydrogen() const { \ |
| 73 return H##type::cast(hydrogen_value()); \ | 83 return H##type::cast(hydrogen_value()); \ |
| 74 } | 84 } |
| 75 | 85 |
| 76 | 86 |
| 77 class LInstruction: public ZoneObject { | 87 class LInstruction: public ZoneObject { |
| 78 public: | 88 public: |
| 79 LInstruction() | 89 LInstruction() |
| 80 : hydrogen_value_(NULL) { } | 90 : hydrogen_value_(NULL) { } |
| 81 virtual ~LInstruction() { } | 91 virtual ~LInstruction() { } |
| 82 | 92 |
| 83 // Predicates should be generated by macro as in lithium-ia32.h. | |
| 84 virtual bool IsLabel() const { | |
| 85 UNIMPLEMENTED(); | |
| 86 return false; | |
| 87 } | |
| 88 virtual bool IsOsrEntry() const { | |
| 89 UNIMPLEMENTED(); | |
| 90 return false; | |
| 91 } | |
| 92 | |
| 93 virtual void CompileToNative(LCodeGen* generator) = 0; | 93 virtual void CompileToNative(LCodeGen* generator) = 0; |
| 94 virtual const char* Mnemonic() const = 0; | 94 virtual const char* Mnemonic() const = 0; |
| 95 virtual void PrintTo(StringStream* stream) const; | 95 virtual void PrintTo(StringStream* stream); |
| 96 virtual void PrintDataTo(StringStream* stream) const { } | 96 virtual void PrintDataTo(StringStream* stream) { } |
| 97 | 97 |
| 98 // Declare virtual type testers. | 98 // Declare virtual type testers. |
| 99 #define DECLARE_DO(type) virtual bool Is##type() const { return false; } | 99 #define DECLARE_DO(type) virtual bool Is##type() const { return false; } |
| 100 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO) | 100 LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO) |
| 101 #undef DECLARE_DO | 101 #undef DECLARE_DO |
| 102 virtual bool IsControl() const { return false; } | 102 virtual bool IsControl() const { return false; } |
| 103 | 103 |
| 104 void set_environment(LEnvironment* env) { environment_.set(env); } | 104 void set_environment(LEnvironment* env) { environment_.set(env); } |
| 105 LEnvironment* environment() const { return environment_.get(); } | 105 LEnvironment* environment() const { return environment_.get(); } |
| 106 bool HasEnvironment() const { return environment_.is_set(); } | 106 bool HasEnvironment() const { return environment_.is_set(); } |
| 107 | 107 |
| 108 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } | 108 void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } |
| 109 LPointerMap* pointer_map() const { return pointer_map_.get(); } | 109 LPointerMap* pointer_map() const { return pointer_map_.get(); } |
| 110 bool HasPointerMap() const { return pointer_map_.is_set(); } | 110 bool HasPointerMap() const { return pointer_map_.is_set(); } |
| 111 | 111 |
| 112 void set_result(LOperand* operand) { result_.set(operand); } | 112 virtual bool HasResult() const = 0; |
| 113 LOperand* result() const { return result_.get(); } | |
| 114 bool HasResult() const { return result_.is_set(); } | |
| 115 | 113 |
| 116 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } | 114 void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } |
| 117 HValue* hydrogen_value() const { return hydrogen_value_; } | 115 HValue* hydrogen_value() const { return hydrogen_value_; } |
| 118 | 116 |
| 119 void set_deoptimization_environment(LEnvironment* env) { | 117 void set_deoptimization_environment(LEnvironment* env) { |
| 120 deoptimization_environment_.set(env); | 118 deoptimization_environment_.set(env); |
| 121 } | 119 } |
| 122 LEnvironment* deoptimization_environment() const { | 120 LEnvironment* deoptimization_environment() const { |
| 123 return deoptimization_environment_.get(); | 121 return deoptimization_environment_.get(); |
| 124 } | 122 } |
| 125 bool HasDeoptimizationEnvironment() const { | 123 bool HasDeoptimizationEnvironment() const { |
| 126 return deoptimization_environment_.is_set(); | 124 return deoptimization_environment_.is_set(); |
| 127 } | 125 } |
| 128 | 126 |
| 129 private: | 127 private: |
| 130 SetOncePointer<LEnvironment> environment_; | 128 SetOncePointer<LEnvironment> environment_; |
| 131 SetOncePointer<LPointerMap> pointer_map_; | 129 SetOncePointer<LPointerMap> pointer_map_; |
| 132 SetOncePointer<LOperand> result_; | |
| 133 HValue* hydrogen_value_; | 130 HValue* hydrogen_value_; |
| 134 SetOncePointer<LEnvironment> deoptimization_environment_; | 131 SetOncePointer<LEnvironment> deoptimization_environment_; |
| 135 }; | 132 }; |
| 136 | 133 |
| 137 | 134 |
| 138 class LGap: public LInstruction { | 135 template <int Result> |
| 136 class LTemplateInstruction: public LInstruction { }; |
| 137 |
| 138 |
| 139 template<> |
| 140 class LTemplateInstruction<0>: public LInstruction { |
| 141 virtual bool HasResult() const { return false; } |
| 142 }; |
| 143 |
| 144 |
| 145 template<> |
| 146 class LTemplateInstruction<1>: public LInstruction { |
| 147 public: |
| 148 static LTemplateInstruction<1>* cast(LInstruction* instr) { |
| 149 ASSERT(instr->HasResult()); |
| 150 return reinterpret_cast<LTemplateInstruction<1>*>(instr); |
| 151 } |
| 152 void set_result(LOperand* operand) { result_.set(operand); } |
| 153 LOperand* result() const { return result_.get(); } |
| 154 virtual bool HasResult() const { return result_.is_set(); } |
| 155 private: |
| 156 SetOncePointer<LOperand> result_; |
| 157 }; |
| 158 |
| 159 |
| 160 class LGap: public LTemplateInstruction<0> { |
| 139 public: | 161 public: |
| 140 explicit LGap(HBasicBlock* block) | 162 explicit LGap(HBasicBlock* block) |
| 141 : block_(block) { | 163 : block_(block) { |
| 142 parallel_moves_[BEFORE] = NULL; | 164 parallel_moves_[BEFORE] = NULL; |
| 143 parallel_moves_[START] = NULL; | 165 parallel_moves_[START] = NULL; |
| 144 parallel_moves_[END] = NULL; | 166 parallel_moves_[END] = NULL; |
| 145 parallel_moves_[AFTER] = NULL; | 167 parallel_moves_[AFTER] = NULL; |
| 146 } | 168 } |
| 147 | 169 |
| 148 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap") | 170 DECLARE_CONCRETE_INSTRUCTION(Gap, "gap") |
| 149 virtual void PrintDataTo(StringStream* stream) const; | 171 virtual void PrintDataTo(StringStream* stream); |
| 150 | 172 |
| 151 bool IsRedundant() const; | 173 bool IsRedundant() const; |
| 152 | 174 |
| 153 HBasicBlock* block() const { return block_; } | 175 HBasicBlock* block() const { return block_; } |
| 154 | 176 |
| 155 enum InnerPosition { | 177 enum InnerPosition { |
| 156 BEFORE, | 178 BEFORE, |
| 157 START, | 179 START, |
| 158 END, | 180 END, |
| 159 AFTER, | 181 AFTER, |
| 160 FIRST_INNER_POSITION = BEFORE, | 182 FIRST_INNER_POSITION = BEFORE, |
| 161 LAST_INNER_POSITION = AFTER | 183 LAST_INNER_POSITION = AFTER |
| 162 }; | 184 }; |
| 163 | 185 |
| 164 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) { | 186 LParallelMove* GetOrCreateParallelMove(InnerPosition pos) { |
| 165 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove; | 187 if (parallel_moves_[pos] == NULL) parallel_moves_[pos] = new LParallelMove; |
| 166 return parallel_moves_[pos]; | 188 return parallel_moves_[pos]; |
| 167 } | 189 } |
| 168 | 190 |
| 169 LParallelMove* GetParallelMove(InnerPosition pos) { | 191 LParallelMove* GetParallelMove(InnerPosition pos) { |
| 170 return parallel_moves_[pos]; | 192 return parallel_moves_[pos]; |
| 171 } | 193 } |
| 172 | 194 |
| 173 private: | 195 private: |
| 174 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; | 196 LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; |
| 175 HBasicBlock* block_; | 197 HBasicBlock* block_; |
| 176 }; | 198 }; |
| 177 | 199 |
| 178 | 200 |
| 201 class LGoto: public LTemplateInstruction<0> { |
| 202 public: |
| 203 LGoto(int block_id, bool include_stack_check = false) |
| 204 : block_id_(block_id), include_stack_check_(include_stack_check) { } |
| 205 |
| 206 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") |
| 207 virtual void PrintDataTo(StringStream* stream); |
| 208 virtual bool IsControl() const { return true; } |
| 209 |
| 210 int block_id() const { return block_id_; } |
| 211 bool include_stack_check() const { return include_stack_check_; } |
| 212 |
| 213 private: |
| 214 int block_id_; |
| 215 bool include_stack_check_; |
| 216 }; |
| 217 |
| 218 |
| 219 class LLazyBailout: public LTemplateInstruction<0> { |
| 220 public: |
| 221 LLazyBailout() : gap_instructions_size_(0) { } |
| 222 |
| 223 DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout") |
| 224 |
| 225 void set_gap_instructions_size(int gap_instructions_size) { |
| 226 gap_instructions_size_ = gap_instructions_size; |
| 227 } |
| 228 int gap_instructions_size() { return gap_instructions_size_; } |
| 229 |
| 230 private: |
| 231 int gap_instructions_size_; |
| 232 }; |
| 233 |
| 234 |
| 235 class LDeoptimize: public LTemplateInstruction<0> { |
| 236 public: |
| 237 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize") |
| 238 }; |
| 239 |
| 240 |
| 179 class LLabel: public LGap { | 241 class LLabel: public LGap { |
| 180 public: | 242 public: |
| 181 explicit LLabel(HBasicBlock* block) : LGap(block) { } | 243 explicit LLabel(HBasicBlock* block) |
| 244 : LGap(block), replacement_(NULL) { } |
| 245 |
| 246 DECLARE_CONCRETE_INSTRUCTION(Label, "label") |
| 247 |
| 248 virtual void PrintDataTo(StringStream* stream); |
| 249 |
| 250 int block_id() const { return block()->block_id(); } |
| 251 bool is_loop_header() const { return block()->IsLoopHeader(); } |
| 252 Label* label() { return &label_; } |
| 253 LLabel* replacement() const { return replacement_; } |
| 254 void set_replacement(LLabel* label) { replacement_ = label; } |
| 255 bool HasReplacement() const { return replacement_ != NULL; } |
| 182 | 256 |
| 183 private: | 257 private: |
| 184 Label label_; | 258 Label label_; |
| 185 LLabel* replacement_; | 259 LLabel* replacement_; |
| 186 }; | 260 }; |
| 187 | 261 |
| 188 | 262 |
| 189 class LOsrEntry: public LInstruction { | 263 class LOsrEntry: public LTemplateInstruction<0> { |
| 190 public: | 264 public: |
| 191 // Function could be generated by a macro as in lithium-ia32.h. | 265 LOsrEntry(); |
| 192 static LOsrEntry* cast(LInstruction* instr) { | |
| 193 UNIMPLEMENTED(); | |
| 194 return NULL; | |
| 195 } | |
| 196 | 266 |
| 197 LOperand** SpilledRegisterArray() { | 267 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry") |
| 198 UNIMPLEMENTED(); | |
| 199 return NULL; | |
| 200 } | |
| 201 LOperand** SpilledDoubleRegisterArray() { | |
| 202 UNIMPLEMENTED(); | |
| 203 return NULL; | |
| 204 } | |
| 205 | 268 |
| 206 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand) { | 269 LOperand** SpilledRegisterArray() { return register_spills_; } |
| 207 UNIMPLEMENTED(); | 270 LOperand** SpilledDoubleRegisterArray() { return double_register_spills_; } |
| 208 } | 271 |
| 272 void MarkSpilledRegister(int allocation_index, LOperand* spill_operand); |
| 209 void MarkSpilledDoubleRegister(int allocation_index, | 273 void MarkSpilledDoubleRegister(int allocation_index, |
| 210 LOperand* spill_operand) { | 274 LOperand* spill_operand); |
| 211 UNIMPLEMENTED(); | |
| 212 } | |
| 213 | 275 |
| 214 private: | 276 private: |
| 215 // Arrays of spill slot operands for registers with an assigned spill | 277 // Arrays of spill slot operands for registers with an assigned spill |
| 216 // slot, i.e., that must also be restored to the spill slot on OSR entry. | 278 // slot, i.e., that must also be restored to the spill slot on OSR entry. |
| 217 // NULL if the register has no assigned spill slot. Indexed by allocation | 279 // NULL if the register has no assigned spill slot. Indexed by allocation |
| 218 // index. | 280 // index. |
| 219 LOperand* register_spills_[Register::kNumAllocatableRegisters]; | 281 LOperand* register_spills_[Register::kNumAllocatableRegisters]; |
| 220 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; | 282 LOperand* double_register_spills_[DoubleRegister::kNumAllocatableRegisters]; |
| 221 }; | 283 }; |
| 222 | 284 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 LInstruction* instructions_pending_deoptimization_environment_; | 480 LInstruction* instructions_pending_deoptimization_environment_; |
| 419 int pending_deoptimization_ast_id_; | 481 int pending_deoptimization_ast_id_; |
| 420 | 482 |
| 421 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); | 483 DISALLOW_COPY_AND_ASSIGN(LChunkBuilder); |
| 422 }; | 484 }; |
| 423 | 485 |
| 424 | 486 |
| 425 } } // namespace v8::internal | 487 } } // namespace v8::internal |
| 426 | 488 |
| 427 #endif // V8_X64_LITHIUM_X64_H_ | 489 #endif // V8_X64_LITHIUM_X64_H_ |
| OLD | NEW |