Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: src/compiler/instruction.h

Issue 907873002: [turbofan] make zone allocation of InstructionOperand explicit (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/move-optimizer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <iosfwd> 9 #include <iosfwd>
10 #include <map> 10 #include <map>
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 InstructionOperand() : virtual_register_(kInvalidVirtualRegister) { 53 InstructionOperand() : virtual_register_(kInvalidVirtualRegister) {
54 ConvertTo(INVALID, 0); 54 ConvertTo(INVALID, 0);
55 } 55 }
56 56
57 InstructionOperand(Kind kind, int index) 57 InstructionOperand(Kind kind, int index)
58 : virtual_register_(kInvalidVirtualRegister) { 58 : virtual_register_(kInvalidVirtualRegister) {
59 DCHECK(kind != INVALID); 59 DCHECK(kind != INVALID);
60 ConvertTo(kind, index); 60 ConvertTo(kind, index);
61 } 61 }
62 62
63 static InstructionOperand* New(Zone* zone, Kind kind, int index) {
64 return New(zone, InstructionOperand(kind, index));
65 }
66
63 Kind kind() const { return KindField::decode(value_); } 67 Kind kind() const { return KindField::decode(value_); }
64 int index() const { return static_cast<int>(value_) >> KindField::kSize; } 68 int index() const { return static_cast<int>(value_) >> KindField::kSize; }
65 #define INSTRUCTION_OPERAND_PREDICATE(name, type) \ 69 #define INSTRUCTION_OPERAND_PREDICATE(name, type) \
66 bool Is##name() const { return kind() == type; } 70 bool Is##name() const { return kind() == type; }
67 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) 71 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
68 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED) 72 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED)
69 INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID) 73 INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID)
70 #undef INSTRUCTION_OPERAND_PREDICATE 74 #undef INSTRUCTION_OPERAND_PREDICATE
71 bool Equals(const InstructionOperand* other) const { 75 bool Equals(const InstructionOperand* other) const {
72 return value_ == other->value_; 76 return value_ == other->value_;
73 } 77 }
74 78
75 void ConvertTo(Kind kind, int index) { 79 void ConvertTo(Kind kind, int index) {
76 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); 80 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0);
77 value_ = KindField::encode(kind); 81 value_ = KindField::encode(kind);
78 value_ |= bit_cast<unsigned>(index << KindField::kSize); 82 value_ |= bit_cast<unsigned>(index << KindField::kSize);
79 DCHECK(this->index() == index); 83 DCHECK(this->index() == index);
80 if (kind != UNALLOCATED) virtual_register_ = kInvalidVirtualRegister; 84 if (kind != UNALLOCATED) virtual_register_ = kInvalidVirtualRegister;
81 } 85 }
82 86
83 // TODO(dcarney): get rid of these 87 protected:
84 void* operator new(size_t, void* location) { return location; } 88 template <typename SubKindOperand>
85 void* operator new(size_t size, Zone* zone) { 89 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) {
86 return zone->New(static_cast<int>(size)); 90 void* buffer = zone->New(sizeof(op));
91 return new (buffer) SubKindOperand(op);
87 } 92 }
88 void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
89 93
90 protected:
91 InstructionOperand(Kind kind, int index, int virtual_register) 94 InstructionOperand(Kind kind, int index, int virtual_register)
92 : virtual_register_(virtual_register) { 95 : virtual_register_(virtual_register) {
93 ConvertTo(kind, index); 96 ConvertTo(kind, index);
94 } 97 }
95 typedef BitField<Kind, 0, 3> KindField; 98 typedef BitField<Kind, 0, 3> KindField;
96 99
97 uint32_t value_; 100 uint32_t value_;
98 // TODO(dcarney): this should really be unsigned. 101 // TODO(dcarney): this should really be unsigned.
99 int32_t virtual_register_; 102 int32_t virtual_register_;
100 }; 103 };
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 } 162 }
160 163
161 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime, 164 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime,
162 int virtual_register) 165 int virtual_register)
163 : InstructionOperand(UNALLOCATED, 0, virtual_register) { 166 : InstructionOperand(UNALLOCATED, 0, virtual_register) {
164 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 167 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
165 value_ |= ExtendedPolicyField::encode(policy); 168 value_ |= ExtendedPolicyField::encode(policy);
166 value_ |= LifetimeField::encode(lifetime); 169 value_ |= LifetimeField::encode(lifetime);
167 } 170 }
168 171
172 UnallocatedOperand* Copy(Zone* zone) { return New(zone, *this); }
173
169 UnallocatedOperand* CopyUnconstrained(Zone* zone) { 174 UnallocatedOperand* CopyUnconstrained(Zone* zone) {
170 return new (zone) UnallocatedOperand(ANY, virtual_register()); 175 return New(zone, UnallocatedOperand(ANY, virtual_register()));
171 } 176 }
172 177
173 static const UnallocatedOperand* cast(const InstructionOperand* op) { 178 static const UnallocatedOperand* cast(const InstructionOperand* op) {
174 DCHECK(op->IsUnallocated()); 179 DCHECK(op->IsUnallocated());
175 return static_cast<const UnallocatedOperand*>(op); 180 return static_cast<const UnallocatedOperand*>(op);
176 } 181 }
177 182
178 static UnallocatedOperand* cast(InstructionOperand* op) { 183 static UnallocatedOperand* cast(InstructionOperand* op) {
179 DCHECK(op->IsUnallocated()); 184 DCHECK(op->IsUnallocated());
180 return static_cast<UnallocatedOperand*>(op); 185 return static_cast<UnallocatedOperand*>(op);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo); 347 std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo);
343 348
344 349
345 #define INSTRUCTION_SUBKIND_OPERAND_CLASS(SubKind, kOperandKind) \ 350 #define INSTRUCTION_SUBKIND_OPERAND_CLASS(SubKind, kOperandKind) \
346 class SubKind##Operand FINAL : public InstructionOperand { \ 351 class SubKind##Operand FINAL : public InstructionOperand { \
347 public: \ 352 public: \
348 explicit SubKind##Operand(int index) \ 353 explicit SubKind##Operand(int index) \
349 : InstructionOperand(kOperandKind, index) {} \ 354 : InstructionOperand(kOperandKind, index) {} \
350 \ 355 \
351 static SubKind##Operand* New(int index, Zone* zone) { \ 356 static SubKind##Operand* New(int index, Zone* zone) { \
352 return new (zone) SubKind##Operand(index); \ 357 return InstructionOperand::New(zone, SubKind##Operand(index)); \
353 } \ 358 } \
354 \ 359 \
355 static SubKind##Operand* cast(InstructionOperand* op) { \ 360 static SubKind##Operand* cast(InstructionOperand* op) { \
356 DCHECK(op->kind() == kOperandKind); \ 361 DCHECK(op->kind() == kOperandKind); \
357 return reinterpret_cast<SubKind##Operand*>(op); \ 362 return reinterpret_cast<SubKind##Operand*>(op); \
358 } \ 363 } \
359 \ 364 \
360 static const SubKind##Operand* cast(const InstructionOperand* op) { \ 365 static const SubKind##Operand* cast(const InstructionOperand* op) { \
361 DCHECK(op->kind() == kOperandKind); \ 366 DCHECK(op->kind() == kOperandKind); \
362 return reinterpret_cast<const SubKind##Operand*>(op); \ 367 return reinterpret_cast<const SubKind##Operand*>(op); \
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 friend std::ostream& operator<<(std::ostream& os, const PointerMap& pm); 434 friend std::ostream& operator<<(std::ostream& os, const PointerMap& pm);
430 435
431 ZoneList<InstructionOperand*> pointer_operands_; 436 ZoneList<InstructionOperand*> pointer_operands_;
432 ZoneList<InstructionOperand*> untagged_operands_; 437 ZoneList<InstructionOperand*> untagged_operands_;
433 int instruction_position_; 438 int instruction_position_;
434 }; 439 };
435 440
436 std::ostream& operator<<(std::ostream& os, const PointerMap& pm); 441 std::ostream& operator<<(std::ostream& os, const PointerMap& pm);
437 442
438 // TODO(titzer): s/PointerMap/ReferenceMap/ 443 // TODO(titzer): s/PointerMap/ReferenceMap/
439 class Instruction : public ZoneObject { 444 class Instruction {
440 public: 445 public:
441 size_t OutputCount() const { return OutputCountField::decode(bit_field_); } 446 size_t OutputCount() const { return OutputCountField::decode(bit_field_); }
442 const InstructionOperand* OutputAt(size_t i) const { 447 const InstructionOperand* OutputAt(size_t i) const {
443 DCHECK(i < OutputCount()); 448 DCHECK(i < OutputCount());
444 return &operands_[i]; 449 return &operands_[i];
445 } 450 }
446 InstructionOperand* OutputAt(size_t i) { 451 InstructionOperand* OutputAt(size_t i) {
447 DCHECK(i < OutputCount()); 452 DCHECK(i < OutputCount());
448 return &operands_[i]; 453 return &operands_[i];
449 } 454 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 bool ClobbersTemps() const { return IsCall(); } 533 bool ClobbersTemps() const { return IsCall(); }
529 bool ClobbersDoubleRegisters() const { return IsCall(); } 534 bool ClobbersDoubleRegisters() const { return IsCall(); }
530 PointerMap* pointer_map() const { return pointer_map_; } 535 PointerMap* pointer_map() const { return pointer_map_; }
531 536
532 void set_pointer_map(PointerMap* map) { 537 void set_pointer_map(PointerMap* map) {
533 DCHECK(NeedsPointerMap()); 538 DCHECK(NeedsPointerMap());
534 DCHECK(!pointer_map_); 539 DCHECK(!pointer_map_);
535 pointer_map_ = map; 540 pointer_map_ = map;
536 } 541 }
537 542
538 // Placement new operator so that we can smash instructions into
539 // zone-allocated memory.
540 void* operator new(size_t, void* location) { return location; }
541
542 void operator delete(void* pointer, void* location) { UNREACHABLE(); }
543
544 void OverwriteWithNop() { 543 void OverwriteWithNop() {
545 opcode_ = ArchOpcodeField::encode(kArchNop); 544 opcode_ = ArchOpcodeField::encode(kArchNop);
546 bit_field_ = 0; 545 bit_field_ = 0;
547 pointer_map_ = NULL; 546 pointer_map_ = NULL;
548 } 547 }
549 548
550 bool IsNop() const { 549 bool IsNop() const {
551 return arch_opcode() == kArchNop && InputCount() == 0 && 550 return arch_opcode() == kArchNop && InputCount() == 0 &&
552 OutputCount() == 0 && TempCount() == 0; 551 OutputCount() == 0 && TempCount() == 0;
553 } 552 }
554 553
555 protected: 554 protected:
556 explicit Instruction(InstructionCode opcode); 555 explicit Instruction(InstructionCode opcode);
557 Instruction(InstructionCode opcode, size_t output_count, 556 Instruction(InstructionCode opcode, size_t output_count,
558 InstructionOperand* outputs, size_t input_count, 557 InstructionOperand* outputs, size_t input_count,
559 InstructionOperand* inputs, size_t temp_count, 558 InstructionOperand* inputs, size_t temp_count,
560 InstructionOperand* temps); 559 InstructionOperand* temps);
561 560
562 protected:
563 typedef BitField<size_t, 0, 8> OutputCountField; 561 typedef BitField<size_t, 0, 8> OutputCountField;
564 typedef BitField<size_t, 8, 16> InputCountField; 562 typedef BitField<size_t, 8, 16> InputCountField;
565 typedef BitField<size_t, 24, 6> TempCountField; 563 typedef BitField<size_t, 24, 6> TempCountField;
566 typedef BitField<bool, 30, 1> IsCallField; 564 typedef BitField<bool, 30, 1> IsCallField;
567 typedef BitField<bool, 31, 1> IsControlField; 565 typedef BitField<bool, 31, 1> IsControlField;
568 566
569 InstructionCode opcode_; 567 InstructionCode opcode_;
570 uint32_t bit_field_; 568 uint32_t bit_field_;
571 PointerMap* pointer_map_; 569 PointerMap* pointer_map_;
572 InstructionOperand operands_[1]; 570 InstructionOperand operands_[1];
571
572 private:
573 DISALLOW_COPY_AND_ASSIGN(Instruction);
573 }; 574 };
574 575
575 576
576 struct PrintableInstruction { 577 struct PrintableInstruction {
577 const RegisterConfiguration* register_configuration_; 578 const RegisterConfiguration* register_configuration_;
578 const Instruction* instr_; 579 const Instruction* instr_;
579 }; 580 };
580 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr); 581 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr);
581 582
582 583
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 1051
1051 1052
1052 std::ostream& operator<<(std::ostream& os, 1053 std::ostream& operator<<(std::ostream& os,
1053 const PrintableInstructionSequence& code); 1054 const PrintableInstructionSequence& code);
1054 1055
1055 } // namespace compiler 1056 } // namespace compiler
1056 } // namespace internal 1057 } // namespace internal
1057 } // namespace v8 1058 } // namespace v8
1058 1059
1059 #endif // V8_COMPILER_INSTRUCTION_H_ 1060 #endif // V8_COMPILER_INSTRUCTION_H_
OLDNEW
« no previous file with comments | « no previous file | src/compiler/move-optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698