OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 bool Is##name() const { return kind() == type; } | 66 bool Is##name() const { return kind() == type; } |
67 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) | 67 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) |
68 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) | 68 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) |
69 INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0) | 69 INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0) |
70 #undef INSTRUCTION_OPERAND_PREDICATE | 70 #undef INSTRUCTION_OPERAND_PREDICATE |
71 bool Equals(InstructionOperand* other) const { | 71 bool Equals(InstructionOperand* other) const { |
72 return value_ == other->value_; | 72 return value_ == other->value_; |
73 } | 73 } |
74 | 74 |
75 void ConvertTo(Kind kind, int index) { | 75 void ConvertTo(Kind kind, int index) { |
76 if (kind == REGISTER || kind == DOUBLE_REGISTER) ASSERT(index >= 0); | 76 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); |
77 value_ = KindField::encode(kind); | 77 value_ = KindField::encode(kind); |
78 value_ |= index << KindField::kSize; | 78 value_ |= index << KindField::kSize; |
79 ASSERT(this->index() == index); | 79 DCHECK(this->index() == index); |
80 } | 80 } |
81 | 81 |
82 // Calls SetUpCache()/TearDownCache() for each subclass. | 82 // Calls SetUpCache()/TearDownCache() for each subclass. |
83 static void SetUpCaches(); | 83 static void SetUpCaches(); |
84 static void TearDownCaches(); | 84 static void TearDownCaches(); |
85 | 85 |
86 protected: | 86 protected: |
87 typedef BitField<Kind, 0, 3> KindField; | 87 typedef BitField<Kind, 0, 3> KindField; |
88 | 88 |
89 unsigned value_; | 89 unsigned value_; |
(...skipping 30 matching lines...) Expand all Loading... |
120 | 120 |
121 explicit UnallocatedOperand(ExtendedPolicy policy) | 121 explicit UnallocatedOperand(ExtendedPolicy policy) |
122 : InstructionOperand(UNALLOCATED, 0) { | 122 : InstructionOperand(UNALLOCATED, 0) { |
123 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 123 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
124 value_ |= ExtendedPolicyField::encode(policy); | 124 value_ |= ExtendedPolicyField::encode(policy); |
125 value_ |= LifetimeField::encode(USED_AT_END); | 125 value_ |= LifetimeField::encode(USED_AT_END); |
126 } | 126 } |
127 | 127 |
128 UnallocatedOperand(BasicPolicy policy, int index) | 128 UnallocatedOperand(BasicPolicy policy, int index) |
129 : InstructionOperand(UNALLOCATED, 0) { | 129 : InstructionOperand(UNALLOCATED, 0) { |
130 ASSERT(policy == FIXED_SLOT); | 130 DCHECK(policy == FIXED_SLOT); |
131 value_ |= BasicPolicyField::encode(policy); | 131 value_ |= BasicPolicyField::encode(policy); |
132 value_ |= index << FixedSlotIndexField::kShift; | 132 value_ |= index << FixedSlotIndexField::kShift; |
133 ASSERT(this->fixed_slot_index() == index); | 133 DCHECK(this->fixed_slot_index() == index); |
134 } | 134 } |
135 | 135 |
136 UnallocatedOperand(ExtendedPolicy policy, int index) | 136 UnallocatedOperand(ExtendedPolicy policy, int index) |
137 : InstructionOperand(UNALLOCATED, 0) { | 137 : InstructionOperand(UNALLOCATED, 0) { |
138 ASSERT(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); | 138 DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); |
139 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 139 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
140 value_ |= ExtendedPolicyField::encode(policy); | 140 value_ |= ExtendedPolicyField::encode(policy); |
141 value_ |= LifetimeField::encode(USED_AT_END); | 141 value_ |= LifetimeField::encode(USED_AT_END); |
142 value_ |= FixedRegisterField::encode(index); | 142 value_ |= FixedRegisterField::encode(index); |
143 } | 143 } |
144 | 144 |
145 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime) | 145 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime) |
146 : InstructionOperand(UNALLOCATED, 0) { | 146 : InstructionOperand(UNALLOCATED, 0) { |
147 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 147 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
148 value_ |= ExtendedPolicyField::encode(policy); | 148 value_ |= ExtendedPolicyField::encode(policy); |
149 value_ |= LifetimeField::encode(lifetime); | 149 value_ |= LifetimeField::encode(lifetime); |
150 } | 150 } |
151 | 151 |
152 UnallocatedOperand* CopyUnconstrained(Zone* zone) { | 152 UnallocatedOperand* CopyUnconstrained(Zone* zone) { |
153 UnallocatedOperand* result = new (zone) UnallocatedOperand(ANY); | 153 UnallocatedOperand* result = new (zone) UnallocatedOperand(ANY); |
154 result->set_virtual_register(virtual_register()); | 154 result->set_virtual_register(virtual_register()); |
155 return result; | 155 return result; |
156 } | 156 } |
157 | 157 |
158 static const UnallocatedOperand* cast(const InstructionOperand* op) { | 158 static const UnallocatedOperand* cast(const InstructionOperand* op) { |
159 ASSERT(op->IsUnallocated()); | 159 DCHECK(op->IsUnallocated()); |
160 return static_cast<const UnallocatedOperand*>(op); | 160 return static_cast<const UnallocatedOperand*>(op); |
161 } | 161 } |
162 | 162 |
163 static UnallocatedOperand* cast(InstructionOperand* op) { | 163 static UnallocatedOperand* cast(InstructionOperand* op) { |
164 ASSERT(op->IsUnallocated()); | 164 DCHECK(op->IsUnallocated()); |
165 return static_cast<UnallocatedOperand*>(op); | 165 return static_cast<UnallocatedOperand*>(op); |
166 } | 166 } |
167 | 167 |
168 // The encoding used for UnallocatedOperand operands depends on the policy | 168 // The encoding used for UnallocatedOperand operands depends on the policy |
169 // that is | 169 // that is |
170 // stored within the operand. The FIXED_SLOT policy uses a compact encoding | 170 // stored within the operand. The FIXED_SLOT policy uses a compact encoding |
171 // because it accommodates a larger pay-load. | 171 // because it accommodates a larger pay-load. |
172 // | 172 // |
173 // For FIXED_SLOT policy: | 173 // For FIXED_SLOT policy: |
174 // +------------------------------------------+ | 174 // +------------------------------------------+ |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 bool HasFixedDoubleRegisterPolicy() const { | 228 bool HasFixedDoubleRegisterPolicy() const { |
229 return basic_policy() == EXTENDED_POLICY && | 229 return basic_policy() == EXTENDED_POLICY && |
230 extended_policy() == FIXED_DOUBLE_REGISTER; | 230 extended_policy() == FIXED_DOUBLE_REGISTER; |
231 } | 231 } |
232 | 232 |
233 // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. | 233 // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. |
234 BasicPolicy basic_policy() const { return BasicPolicyField::decode(value_); } | 234 BasicPolicy basic_policy() const { return BasicPolicyField::decode(value_); } |
235 | 235 |
236 // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. | 236 // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. |
237 ExtendedPolicy extended_policy() const { | 237 ExtendedPolicy extended_policy() const { |
238 ASSERT(basic_policy() == EXTENDED_POLICY); | 238 DCHECK(basic_policy() == EXTENDED_POLICY); |
239 return ExtendedPolicyField::decode(value_); | 239 return ExtendedPolicyField::decode(value_); |
240 } | 240 } |
241 | 241 |
242 // [fixed_slot_index]: Only for FIXED_SLOT. | 242 // [fixed_slot_index]: Only for FIXED_SLOT. |
243 int fixed_slot_index() const { | 243 int fixed_slot_index() const { |
244 ASSERT(HasFixedSlotPolicy()); | 244 DCHECK(HasFixedSlotPolicy()); |
245 return static_cast<int>(value_) >> FixedSlotIndexField::kShift; | 245 return static_cast<int>(value_) >> FixedSlotIndexField::kShift; |
246 } | 246 } |
247 | 247 |
248 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER. | 248 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER. |
249 int fixed_register_index() const { | 249 int fixed_register_index() const { |
250 ASSERT(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy()); | 250 DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy()); |
251 return FixedRegisterField::decode(value_); | 251 return FixedRegisterField::decode(value_); |
252 } | 252 } |
253 | 253 |
254 // [virtual_register]: The virtual register ID for this operand. | 254 // [virtual_register]: The virtual register ID for this operand. |
255 int virtual_register() const { return VirtualRegisterField::decode(value_); } | 255 int virtual_register() const { return VirtualRegisterField::decode(value_); } |
256 void set_virtual_register(unsigned id) { | 256 void set_virtual_register(unsigned id) { |
257 value_ = VirtualRegisterField::update(value_, id); | 257 value_ = VirtualRegisterField::update(value_, id); |
258 } | 258 } |
259 | 259 |
260 // [lifetime]: Only for non-FIXED_SLOT. | 260 // [lifetime]: Only for non-FIXED_SLOT. |
261 bool IsUsedAtStart() { | 261 bool IsUsedAtStart() { |
262 ASSERT(basic_policy() == EXTENDED_POLICY); | 262 DCHECK(basic_policy() == EXTENDED_POLICY); |
263 return LifetimeField::decode(value_) == USED_AT_START; | 263 return LifetimeField::decode(value_) == USED_AT_START; |
264 } | 264 } |
265 }; | 265 }; |
266 | 266 |
267 | 267 |
268 class MoveOperands V8_FINAL { | 268 class MoveOperands V8_FINAL { |
269 public: | 269 public: |
270 MoveOperands(InstructionOperand* source, InstructionOperand* destination) | 270 MoveOperands(InstructionOperand* source, InstructionOperand* destination) |
271 : source_(source), destination_(destination) {} | 271 : source_(source), destination_(destination) {} |
272 | 272 |
(...skipping 19 matching lines...) Expand all Loading... |
292 (destination_ != NULL && destination_->IsConstant()); | 292 (destination_ != NULL && destination_->IsConstant()); |
293 } | 293 } |
294 | 294 |
295 bool IsIgnored() const { | 295 bool IsIgnored() const { |
296 return destination_ != NULL && destination_->IsIgnored(); | 296 return destination_ != NULL && destination_->IsIgnored(); |
297 } | 297 } |
298 | 298 |
299 // We clear both operands to indicate move that's been eliminated. | 299 // We clear both operands to indicate move that's been eliminated. |
300 void Eliminate() { source_ = destination_ = NULL; } | 300 void Eliminate() { source_ = destination_ = NULL; } |
301 bool IsEliminated() const { | 301 bool IsEliminated() const { |
302 ASSERT(source_ != NULL || destination_ == NULL); | 302 DCHECK(source_ != NULL || destination_ == NULL); |
303 return source_ == NULL; | 303 return source_ == NULL; |
304 } | 304 } |
305 | 305 |
306 private: | 306 private: |
307 InstructionOperand* source_; | 307 InstructionOperand* source_; |
308 InstructionOperand* destination_; | 308 InstructionOperand* destination_; |
309 }; | 309 }; |
310 | 310 |
311 OStream& operator<<(OStream& os, const MoveOperands& mo); | 311 OStream& operator<<(OStream& os, const MoveOperands& mo); |
312 | 312 |
313 template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands> | 313 template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands> |
314 class SubKindOperand V8_FINAL : public InstructionOperand { | 314 class SubKindOperand V8_FINAL : public InstructionOperand { |
315 public: | 315 public: |
316 static SubKindOperand* Create(int index, Zone* zone) { | 316 static SubKindOperand* Create(int index, Zone* zone) { |
317 ASSERT(index >= 0); | 317 DCHECK(index >= 0); |
318 if (index < kNumCachedOperands) return &cache[index]; | 318 if (index < kNumCachedOperands) return &cache[index]; |
319 return new (zone) SubKindOperand(index); | 319 return new (zone) SubKindOperand(index); |
320 } | 320 } |
321 | 321 |
322 static SubKindOperand* cast(InstructionOperand* op) { | 322 static SubKindOperand* cast(InstructionOperand* op) { |
323 ASSERT(op->kind() == kOperandKind); | 323 DCHECK(op->kind() == kOperandKind); |
324 return reinterpret_cast<SubKindOperand*>(op); | 324 return reinterpret_cast<SubKindOperand*>(op); |
325 } | 325 } |
326 | 326 |
327 static void SetUpCache(); | 327 static void SetUpCache(); |
328 static void TearDownCache(); | 328 static void TearDownCache(); |
329 | 329 |
330 private: | 330 private: |
331 static SubKindOperand* cache; | 331 static SubKindOperand* cache; |
332 | 332 |
333 SubKindOperand() : InstructionOperand() {} | 333 SubKindOperand() : InstructionOperand() {} |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 const ZoneList<InstructionOperand*>* GetNormalizedOperands() { | 373 const ZoneList<InstructionOperand*>* GetNormalizedOperands() { |
374 for (int i = 0; i < untagged_operands_.length(); ++i) { | 374 for (int i = 0; i < untagged_operands_.length(); ++i) { |
375 RemovePointer(untagged_operands_[i]); | 375 RemovePointer(untagged_operands_[i]); |
376 } | 376 } |
377 untagged_operands_.Clear(); | 377 untagged_operands_.Clear(); |
378 return &pointer_operands_; | 378 return &pointer_operands_; |
379 } | 379 } |
380 int instruction_position() const { return instruction_position_; } | 380 int instruction_position() const { return instruction_position_; } |
381 | 381 |
382 void set_instruction_position(int pos) { | 382 void set_instruction_position(int pos) { |
383 ASSERT(instruction_position_ == -1); | 383 DCHECK(instruction_position_ == -1); |
384 instruction_position_ = pos; | 384 instruction_position_ = pos; |
385 } | 385 } |
386 | 386 |
387 void RecordPointer(InstructionOperand* op, Zone* zone); | 387 void RecordPointer(InstructionOperand* op, Zone* zone); |
388 void RemovePointer(InstructionOperand* op); | 388 void RemovePointer(InstructionOperand* op); |
389 void RecordUntagged(InstructionOperand* op, Zone* zone); | 389 void RecordUntagged(InstructionOperand* op, Zone* zone); |
390 | 390 |
391 private: | 391 private: |
392 friend OStream& operator<<(OStream& os, const PointerMap& pm); | 392 friend OStream& operator<<(OStream& os, const PointerMap& pm); |
393 | 393 |
394 ZoneList<InstructionOperand*> pointer_operands_; | 394 ZoneList<InstructionOperand*> pointer_operands_; |
395 ZoneList<InstructionOperand*> untagged_operands_; | 395 ZoneList<InstructionOperand*> untagged_operands_; |
396 int instruction_position_; | 396 int instruction_position_; |
397 }; | 397 }; |
398 | 398 |
399 OStream& operator<<(OStream& os, const PointerMap& pm); | 399 OStream& operator<<(OStream& os, const PointerMap& pm); |
400 | 400 |
401 // TODO(titzer): s/PointerMap/ReferenceMap/ | 401 // TODO(titzer): s/PointerMap/ReferenceMap/ |
402 class Instruction : public ZoneObject { | 402 class Instruction : public ZoneObject { |
403 public: | 403 public: |
404 size_t OutputCount() const { return OutputCountField::decode(bit_field_); } | 404 size_t OutputCount() const { return OutputCountField::decode(bit_field_); } |
405 InstructionOperand* Output() const { return OutputAt(0); } | 405 InstructionOperand* Output() const { return OutputAt(0); } |
406 InstructionOperand* OutputAt(size_t i) const { | 406 InstructionOperand* OutputAt(size_t i) const { |
407 ASSERT(i < OutputCount()); | 407 DCHECK(i < OutputCount()); |
408 return operands_[i]; | 408 return operands_[i]; |
409 } | 409 } |
410 | 410 |
411 size_t InputCount() const { return InputCountField::decode(bit_field_); } | 411 size_t InputCount() const { return InputCountField::decode(bit_field_); } |
412 InstructionOperand* InputAt(size_t i) const { | 412 InstructionOperand* InputAt(size_t i) const { |
413 ASSERT(i < InputCount()); | 413 DCHECK(i < InputCount()); |
414 return operands_[OutputCount() + i]; | 414 return operands_[OutputCount() + i]; |
415 } | 415 } |
416 | 416 |
417 size_t TempCount() const { return TempCountField::decode(bit_field_); } | 417 size_t TempCount() const { return TempCountField::decode(bit_field_); } |
418 InstructionOperand* TempAt(size_t i) const { | 418 InstructionOperand* TempAt(size_t i) const { |
419 ASSERT(i < TempCount()); | 419 DCHECK(i < TempCount()); |
420 return operands_[OutputCount() + InputCount() + i]; | 420 return operands_[OutputCount() + InputCount() + i]; |
421 } | 421 } |
422 | 422 |
423 InstructionCode opcode() const { return opcode_; } | 423 InstructionCode opcode() const { return opcode_; } |
424 ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); } | 424 ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); } |
425 AddressingMode addressing_mode() const { | 425 AddressingMode addressing_mode() const { |
426 return AddressingModeField::decode(opcode()); | 426 return AddressingModeField::decode(opcode()); |
427 } | 427 } |
428 FlagsMode flags_mode() const { return FlagsModeField::decode(opcode()); } | 428 FlagsMode flags_mode() const { return FlagsModeField::decode(opcode()); } |
429 FlagsCondition flags_condition() const { | 429 FlagsCondition flags_condition() const { |
430 return FlagsConditionField::decode(opcode()); | 430 return FlagsConditionField::decode(opcode()); |
431 } | 431 } |
432 | 432 |
433 // TODO(titzer): make control and call into flags. | 433 // TODO(titzer): make control and call into flags. |
434 static Instruction* New(Zone* zone, InstructionCode opcode) { | 434 static Instruction* New(Zone* zone, InstructionCode opcode) { |
435 return New(zone, opcode, 0, NULL, 0, NULL, 0, NULL); | 435 return New(zone, opcode, 0, NULL, 0, NULL, 0, NULL); |
436 } | 436 } |
437 | 437 |
438 static Instruction* New(Zone* zone, InstructionCode opcode, | 438 static Instruction* New(Zone* zone, InstructionCode opcode, |
439 size_t output_count, InstructionOperand** outputs, | 439 size_t output_count, InstructionOperand** outputs, |
440 size_t input_count, InstructionOperand** inputs, | 440 size_t input_count, InstructionOperand** inputs, |
441 size_t temp_count, InstructionOperand** temps) { | 441 size_t temp_count, InstructionOperand** temps) { |
442 ASSERT(opcode >= 0); | 442 DCHECK(opcode >= 0); |
443 ASSERT(output_count == 0 || outputs != NULL); | 443 DCHECK(output_count == 0 || outputs != NULL); |
444 ASSERT(input_count == 0 || inputs != NULL); | 444 DCHECK(input_count == 0 || inputs != NULL); |
445 ASSERT(temp_count == 0 || temps != NULL); | 445 DCHECK(temp_count == 0 || temps != NULL); |
446 InstructionOperand* none = NULL; | 446 InstructionOperand* none = NULL; |
447 USE(none); | 447 USE(none); |
448 int size = static_cast<int>(RoundUp(sizeof(Instruction), kPointerSize) + | 448 int size = static_cast<int>(RoundUp(sizeof(Instruction), kPointerSize) + |
449 (output_count + input_count + temp_count - 1) * | 449 (output_count + input_count + temp_count - 1) * |
450 sizeof(none)); | 450 sizeof(none)); |
451 return new (zone->New(size)) Instruction( | 451 return new (zone->New(size)) Instruction( |
452 opcode, output_count, outputs, input_count, inputs, temp_count, temps); | 452 opcode, output_count, outputs, input_count, inputs, temp_count, temps); |
453 } | 453 } |
454 | 454 |
455 // TODO(titzer): another holdover from lithium days; register allocator | 455 // TODO(titzer): another holdover from lithium days; register allocator |
(...skipping 18 matching lines...) Expand all Loading... |
474 bool IsSourcePosition() const { | 474 bool IsSourcePosition() const { |
475 return opcode() == kSourcePositionInstruction; | 475 return opcode() == kSourcePositionInstruction; |
476 } | 476 } |
477 | 477 |
478 bool ClobbersRegisters() const { return IsCall(); } | 478 bool ClobbersRegisters() const { return IsCall(); } |
479 bool ClobbersTemps() const { return IsCall(); } | 479 bool ClobbersTemps() const { return IsCall(); } |
480 bool ClobbersDoubleRegisters() const { return IsCall(); } | 480 bool ClobbersDoubleRegisters() const { return IsCall(); } |
481 PointerMap* pointer_map() const { return pointer_map_; } | 481 PointerMap* pointer_map() const { return pointer_map_; } |
482 | 482 |
483 void set_pointer_map(PointerMap* map) { | 483 void set_pointer_map(PointerMap* map) { |
484 ASSERT(NeedsPointerMap()); | 484 DCHECK(NeedsPointerMap()); |
485 ASSERT_EQ(NULL, pointer_map_); | 485 DCHECK_EQ(NULL, pointer_map_); |
486 pointer_map_ = map; | 486 pointer_map_ = map; |
487 } | 487 } |
488 | 488 |
489 // Placement new operator so that we can smash instructions into | 489 // Placement new operator so that we can smash instructions into |
490 // zone-allocated memory. | 490 // zone-allocated memory. |
491 void* operator new(size_t, void* location) { return location; } | 491 void* operator new(size_t, void* location) { return location; } |
492 | 492 |
493 void operator delete(void* pointer, void* location) { UNREACHABLE(); } | 493 void operator delete(void* pointer, void* location) { UNREACHABLE(); } |
494 | 494 |
495 protected: | 495 protected: |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 ParallelMove* GetParallelMove(InnerPosition pos) { | 560 ParallelMove* GetParallelMove(InnerPosition pos) { |
561 return parallel_moves_[pos]; | 561 return parallel_moves_[pos]; |
562 } | 562 } |
563 | 563 |
564 static GapInstruction* New(Zone* zone) { | 564 static GapInstruction* New(Zone* zone) { |
565 void* buffer = zone->New(sizeof(GapInstruction)); | 565 void* buffer = zone->New(sizeof(GapInstruction)); |
566 return new (buffer) GapInstruction(kGapInstruction); | 566 return new (buffer) GapInstruction(kGapInstruction); |
567 } | 567 } |
568 | 568 |
569 static GapInstruction* cast(Instruction* instr) { | 569 static GapInstruction* cast(Instruction* instr) { |
570 ASSERT(instr->IsGapMoves()); | 570 DCHECK(instr->IsGapMoves()); |
571 return static_cast<GapInstruction*>(instr); | 571 return static_cast<GapInstruction*>(instr); |
572 } | 572 } |
573 | 573 |
574 static const GapInstruction* cast(const Instruction* instr) { | 574 static const GapInstruction* cast(const Instruction* instr) { |
575 ASSERT(instr->IsGapMoves()); | 575 DCHECK(instr->IsGapMoves()); |
576 return static_cast<const GapInstruction*>(instr); | 576 return static_cast<const GapInstruction*>(instr); |
577 } | 577 } |
578 | 578 |
579 protected: | 579 protected: |
580 explicit GapInstruction(InstructionCode opcode) : Instruction(opcode) { | 580 explicit GapInstruction(InstructionCode opcode) : Instruction(opcode) { |
581 parallel_moves_[BEFORE] = NULL; | 581 parallel_moves_[BEFORE] = NULL; |
582 parallel_moves_[START] = NULL; | 582 parallel_moves_[START] = NULL; |
583 parallel_moves_[END] = NULL; | 583 parallel_moves_[END] = NULL; |
584 parallel_moves_[AFTER] = NULL; | 584 parallel_moves_[AFTER] = NULL; |
585 } | 585 } |
(...skipping 11 matching lines...) Expand all Loading... |
597 public: | 597 public: |
598 BasicBlock* block() const { return block_; } | 598 BasicBlock* block() const { return block_; } |
599 Label* label() { return &label_; } | 599 Label* label() { return &label_; } |
600 | 600 |
601 static BlockStartInstruction* New(Zone* zone, BasicBlock* block) { | 601 static BlockStartInstruction* New(Zone* zone, BasicBlock* block) { |
602 void* buffer = zone->New(sizeof(BlockStartInstruction)); | 602 void* buffer = zone->New(sizeof(BlockStartInstruction)); |
603 return new (buffer) BlockStartInstruction(block); | 603 return new (buffer) BlockStartInstruction(block); |
604 } | 604 } |
605 | 605 |
606 static BlockStartInstruction* cast(Instruction* instr) { | 606 static BlockStartInstruction* cast(Instruction* instr) { |
607 ASSERT(instr->IsBlockStart()); | 607 DCHECK(instr->IsBlockStart()); |
608 return static_cast<BlockStartInstruction*>(instr); | 608 return static_cast<BlockStartInstruction*>(instr); |
609 } | 609 } |
610 | 610 |
611 private: | 611 private: |
612 explicit BlockStartInstruction(BasicBlock* block) | 612 explicit BlockStartInstruction(BasicBlock* block) |
613 : GapInstruction(kBlockStartInstruction), block_(block) {} | 613 : GapInstruction(kBlockStartInstruction), block_(block) {} |
614 | 614 |
615 BasicBlock* block_; | 615 BasicBlock* block_; |
616 Label label_; | 616 Label label_; |
617 }; | 617 }; |
618 | 618 |
619 | 619 |
620 class SourcePositionInstruction V8_FINAL : public Instruction { | 620 class SourcePositionInstruction V8_FINAL : public Instruction { |
621 public: | 621 public: |
622 static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { | 622 static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { |
623 void* buffer = zone->New(sizeof(SourcePositionInstruction)); | 623 void* buffer = zone->New(sizeof(SourcePositionInstruction)); |
624 return new (buffer) SourcePositionInstruction(position); | 624 return new (buffer) SourcePositionInstruction(position); |
625 } | 625 } |
626 | 626 |
627 SourcePosition source_position() const { return source_position_; } | 627 SourcePosition source_position() const { return source_position_; } |
628 | 628 |
629 static SourcePositionInstruction* cast(Instruction* instr) { | 629 static SourcePositionInstruction* cast(Instruction* instr) { |
630 ASSERT(instr->IsSourcePosition()); | 630 DCHECK(instr->IsSourcePosition()); |
631 return static_cast<SourcePositionInstruction*>(instr); | 631 return static_cast<SourcePositionInstruction*>(instr); |
632 } | 632 } |
633 | 633 |
634 static const SourcePositionInstruction* cast(const Instruction* instr) { | 634 static const SourcePositionInstruction* cast(const Instruction* instr) { |
635 ASSERT(instr->IsSourcePosition()); | 635 DCHECK(instr->IsSourcePosition()); |
636 return static_cast<const SourcePositionInstruction*>(instr); | 636 return static_cast<const SourcePositionInstruction*>(instr); |
637 } | 637 } |
638 | 638 |
639 private: | 639 private: |
640 explicit SourcePositionInstruction(SourcePosition source_position) | 640 explicit SourcePositionInstruction(SourcePosition source_position) |
641 : Instruction(kSourcePositionInstruction), | 641 : Instruction(kSourcePositionInstruction), |
642 source_position_(source_position) { | 642 source_position_(source_position) { |
643 ASSERT(!source_position_.IsInvalid()); | 643 DCHECK(!source_position_.IsInvalid()); |
644 ASSERT(!source_position_.IsUnknown()); | 644 DCHECK(!source_position_.IsUnknown()); |
645 } | 645 } |
646 | 646 |
647 SourcePosition source_position_; | 647 SourcePosition source_position_; |
648 }; | 648 }; |
649 | 649 |
650 | 650 |
651 class Constant V8_FINAL { | 651 class Constant V8_FINAL { |
652 public: | 652 public: |
653 enum Type { kInt32, kInt64, kFloat64, kExternalReference, kHeapObject }; | 653 enum Type { kInt32, kInt64, kFloat64, kExternalReference, kHeapObject }; |
654 | 654 |
655 explicit Constant(int32_t v) : type_(kInt32), value_(v) {} | 655 explicit Constant(int32_t v) : type_(kInt32), value_(v) {} |
656 explicit Constant(int64_t v) : type_(kInt64), value_(v) {} | 656 explicit Constant(int64_t v) : type_(kInt64), value_(v) {} |
657 explicit Constant(double v) : type_(kFloat64), value_(BitCast<int64_t>(v)) {} | 657 explicit Constant(double v) : type_(kFloat64), value_(BitCast<int64_t>(v)) {} |
658 explicit Constant(ExternalReference ref) | 658 explicit Constant(ExternalReference ref) |
659 : type_(kExternalReference), value_(BitCast<intptr_t>(ref)) {} | 659 : type_(kExternalReference), value_(BitCast<intptr_t>(ref)) {} |
660 explicit Constant(Handle<HeapObject> obj) | 660 explicit Constant(Handle<HeapObject> obj) |
661 : type_(kHeapObject), value_(BitCast<intptr_t>(obj)) {} | 661 : type_(kHeapObject), value_(BitCast<intptr_t>(obj)) {} |
662 | 662 |
663 Type type() const { return type_; } | 663 Type type() const { return type_; } |
664 | 664 |
665 int32_t ToInt32() const { | 665 int32_t ToInt32() const { |
666 ASSERT_EQ(kInt32, type()); | 666 DCHECK_EQ(kInt32, type()); |
667 return static_cast<int32_t>(value_); | 667 return static_cast<int32_t>(value_); |
668 } | 668 } |
669 | 669 |
670 int64_t ToInt64() const { | 670 int64_t ToInt64() const { |
671 if (type() == kInt32) return ToInt32(); | 671 if (type() == kInt32) return ToInt32(); |
672 ASSERT_EQ(kInt64, type()); | 672 DCHECK_EQ(kInt64, type()); |
673 return value_; | 673 return value_; |
674 } | 674 } |
675 | 675 |
676 double ToFloat64() const { | 676 double ToFloat64() const { |
677 if (type() == kInt32) return ToInt32(); | 677 if (type() == kInt32) return ToInt32(); |
678 ASSERT_EQ(kFloat64, type()); | 678 DCHECK_EQ(kFloat64, type()); |
679 return BitCast<double>(value_); | 679 return BitCast<double>(value_); |
680 } | 680 } |
681 | 681 |
682 ExternalReference ToExternalReference() const { | 682 ExternalReference ToExternalReference() const { |
683 ASSERT_EQ(kExternalReference, type()); | 683 DCHECK_EQ(kExternalReference, type()); |
684 return BitCast<ExternalReference>(static_cast<intptr_t>(value_)); | 684 return BitCast<ExternalReference>(static_cast<intptr_t>(value_)); |
685 } | 685 } |
686 | 686 |
687 Handle<HeapObject> ToHeapObject() const { | 687 Handle<HeapObject> ToHeapObject() const { |
688 ASSERT_EQ(kHeapObject, type()); | 688 DCHECK_EQ(kHeapObject, type()); |
689 return BitCast<Handle<HeapObject> >(static_cast<intptr_t>(value_)); | 689 return BitCast<Handle<HeapObject> >(static_cast<intptr_t>(value_)); |
690 } | 690 } |
691 | 691 |
692 private: | 692 private: |
693 Type type_; | 693 Type type_; |
694 int64_t value_; | 694 int64_t value_; |
695 }; | 695 }; |
696 | 696 |
697 OStream& operator<<(OStream& os, const Constant& constant); | 697 OStream& operator<<(OStream& os, const Constant& constant); |
698 | 698 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 | 764 |
765 typedef InstructionDeque::const_iterator const_iterator; | 765 typedef InstructionDeque::const_iterator const_iterator; |
766 const_iterator begin() const { return instructions_.begin(); } | 766 const_iterator begin() const { return instructions_.begin(); } |
767 const_iterator end() const { return instructions_.end(); } | 767 const_iterator end() const { return instructions_.end(); } |
768 | 768 |
769 GapInstruction* GapAt(int index) const { | 769 GapInstruction* GapAt(int index) const { |
770 return GapInstruction::cast(InstructionAt(index)); | 770 return GapInstruction::cast(InstructionAt(index)); |
771 } | 771 } |
772 bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); } | 772 bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); } |
773 Instruction* InstructionAt(int index) const { | 773 Instruction* InstructionAt(int index) const { |
774 ASSERT(index >= 0); | 774 DCHECK(index >= 0); |
775 ASSERT(index < static_cast<int>(instructions_.size())); | 775 DCHECK(index < static_cast<int>(instructions_.size())); |
776 return instructions_[index]; | 776 return instructions_[index]; |
777 } | 777 } |
778 | 778 |
779 Frame* frame() { return &frame_; } | 779 Frame* frame() { return &frame_; } |
780 Graph* graph() const { return graph_; } | 780 Graph* graph() const { return graph_; } |
781 Isolate* isolate() const { return zone()->isolate(); } | 781 Isolate* isolate() const { return zone()->isolate(); } |
782 Linkage* linkage() const { return linkage_; } | 782 Linkage* linkage() const { return linkage_; } |
783 Schedule* schedule() const { return schedule_; } | 783 Schedule* schedule() const { return schedule_; } |
784 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } | 784 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } |
785 Zone* zone() const { return graph_->zone(); } | 785 Zone* zone() const { return graph_->zone(); } |
786 | 786 |
787 // Used by the code generator while adding instructions. | 787 // Used by the code generator while adding instructions. |
788 int AddInstruction(Instruction* instr, BasicBlock* block); | 788 int AddInstruction(Instruction* instr, BasicBlock* block); |
789 void StartBlock(BasicBlock* block); | 789 void StartBlock(BasicBlock* block); |
790 void EndBlock(BasicBlock* block); | 790 void EndBlock(BasicBlock* block); |
791 | 791 |
792 void AddConstant(int virtual_register, Constant constant) { | 792 void AddConstant(int virtual_register, Constant constant) { |
793 ASSERT(constants_.find(virtual_register) == constants_.end()); | 793 DCHECK(constants_.find(virtual_register) == constants_.end()); |
794 constants_.insert(std::make_pair(virtual_register, constant)); | 794 constants_.insert(std::make_pair(virtual_register, constant)); |
795 } | 795 } |
796 Constant GetConstant(int virtual_register) const { | 796 Constant GetConstant(int virtual_register) const { |
797 ConstantMap::const_iterator it = constants_.find(virtual_register); | 797 ConstantMap::const_iterator it = constants_.find(virtual_register); |
798 ASSERT(it != constants_.end()); | 798 DCHECK(it != constants_.end()); |
799 ASSERT_EQ(virtual_register, it->first); | 799 DCHECK_EQ(virtual_register, it->first); |
800 return it->second; | 800 return it->second; |
801 } | 801 } |
802 | 802 |
803 typedef ConstantDeque Immediates; | 803 typedef ConstantDeque Immediates; |
804 const Immediates& immediates() const { return immediates_; } | 804 const Immediates& immediates() const { return immediates_; } |
805 | 805 |
806 int AddImmediate(Constant constant) { | 806 int AddImmediate(Constant constant) { |
807 int index = static_cast<int>(immediates_.size()); | 807 int index = static_cast<int>(immediates_.size()); |
808 immediates_.push_back(constant); | 808 immediates_.push_back(constant); |
809 return index; | 809 return index; |
810 } | 810 } |
811 Constant GetImmediate(int index) const { | 811 Constant GetImmediate(int index) const { |
812 ASSERT(index >= 0); | 812 DCHECK(index >= 0); |
813 ASSERT(index < static_cast<int>(immediates_.size())); | 813 DCHECK(index < static_cast<int>(immediates_.size())); |
814 return immediates_[index]; | 814 return immediates_[index]; |
815 } | 815 } |
816 | 816 |
817 int AddDeoptimizationEntry(const FrameStateDescriptor& descriptor); | 817 int AddDeoptimizationEntry(const FrameStateDescriptor& descriptor); |
818 FrameStateDescriptor GetDeoptimizationEntry(int deoptimization_id); | 818 FrameStateDescriptor GetDeoptimizationEntry(int deoptimization_id); |
819 int GetDeoptimizationEntryCount(); | 819 int GetDeoptimizationEntryCount(); |
820 | 820 |
821 private: | 821 private: |
822 friend OStream& operator<<(OStream& os, const InstructionSequence& code); | 822 friend OStream& operator<<(OStream& os, const InstructionSequence& code); |
823 | 823 |
(...skipping 13 matching lines...) Expand all Loading... |
837 DeoptimizationVector deoptimization_entries_; | 837 DeoptimizationVector deoptimization_entries_; |
838 }; | 838 }; |
839 | 839 |
840 OStream& operator<<(OStream& os, const InstructionSequence& code); | 840 OStream& operator<<(OStream& os, const InstructionSequence& code); |
841 | 841 |
842 } // namespace compiler | 842 } // namespace compiler |
843 } // namespace internal | 843 } // namespace internal |
844 } // namespace v8 | 844 } // namespace v8 |
845 | 845 |
846 #endif // V8_COMPILER_INSTRUCTION_H_ | 846 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |