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

Side by Side Diff: src/register-allocator-ia32.h

Issue 15079: Experimental: this is a substantial change to allow the virtual frame... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 12 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 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 23 matching lines...) Expand all
34 34
35 35
36 // ------------------------------------------------------------------------- 36 // -------------------------------------------------------------------------
37 // Results 37 // Results
38 // 38 //
39 // Results encapsulate the compile-time values manipulated by the code 39 // Results encapsulate the compile-time values manipulated by the code
40 // generator. They can represent registers or constants. 40 // generator. They can represent registers or constants.
41 41
42 class Result BASE_EMBEDDED { 42 class Result BASE_EMBEDDED {
43 public: 43 public:
44 enum Type {
45 INVALID,
46 REGISTER,
47 CONSTANT
48 };
49
44 // Construct an invalid result. 50 // Construct an invalid result.
45 explicit Result(CodeGenerator* cgen) : type_(INVALID), cgen_(cgen) {} 51 explicit Result(CodeGenerator* cgen) : type_(INVALID), cgen_(cgen) {}
46 52
47 // Construct a register Result. 53 // Construct a register Result.
48 Result(Register reg, CodeGenerator* cgen); 54 Result(Register reg, CodeGenerator* cgen);
49 55
50 // Construct a Result whose value is a compile-time constant. 56 // Construct a Result whose value is a compile-time constant.
51 Result(Handle<Object> value, CodeGenerator * cgen) 57 Result(Handle<Object> value, CodeGenerator * cgen)
52 : type_(CONSTANT), 58 : type_(CONSTANT),
53 cgen_(cgen) { 59 cgen_(cgen) {
54 data_.handle_ = value.location(); 60 data_.handle_ = value.location();
55 } 61 }
56 62
57 // The copy constructor and assignment operators could each create a new 63 // The copy constructor and assignment operators could each create a new
58 // register reference. 64 // register reference.
59 Result(const Result& other) { 65 Result(const Result& other) {
60 other.CopyTo(this); 66 other.CopyTo(this);
61 } 67 }
62 68
63 Result& operator=(Result& other) { 69 Result& operator=(const Result& other) {
64 if (this != &other) { 70 if (this != &other) {
65 Unuse(); 71 Unuse();
66 other.CopyTo(this); 72 other.CopyTo(this);
67 other.Unuse(); 73 // other.Unuse();
68 } 74 }
69 return *this; 75 return *this;
70 } 76 }
71 77
72 ~Result() { Unuse(); } 78 ~Result() { Unuse(); }
73 79
74 void Unuse(); 80 void Unuse();
75 81
82 Type type() const { return type_; }
83
76 bool is_valid() const { return type() != INVALID; } 84 bool is_valid() const { return type() != INVALID; }
77 bool is_register() const { return type() == REGISTER; } 85 bool is_register() const { return type() == REGISTER; }
78 bool is_constant() const { return type() == CONSTANT; } 86 bool is_constant() const { return type() == CONSTANT; }
79 87
80 Register reg() const { 88 Register reg() const {
81 ASSERT(type() == REGISTER); 89 ASSERT(type() == REGISTER);
82 return data_.reg_; 90 return data_.reg_;
83 } 91 }
84 92
85 Handle<Object> handle() const { 93 Handle<Object> handle() const {
86 ASSERT(type() == CONSTANT); 94 ASSERT(type() == CONSTANT);
87 return Handle<Object>(data_.handle_); 95 return Handle<Object>(data_.handle_);
88 } 96 }
89 97
90 // Change a result to a register result. If the result is not already 98 // Move this result to an arbitrary register. The register is not
91 // in a register, allocate a register from the code generator, and emit 99 // necessarily spilled from the frame or even singly-referenced outside
92 // code to move the value into that register. 100 // it.
William Hesse 2008/12/22 13:55:21 How can we move a result into a register that isn'
Kevin Millikin (Chromium) 2008/12/22 14:40:00 Yes, the comment refers to the case where the resu
93 void ToRegister(); 101 void ToRegister();
94 102
103 // Move this result to a specified register. The register is spilled from
104 // the frame, and the register is singly-referenced (by this result)
105 // outside the frame.
106 void ToRegister(Register reg);
107
95 private: 108 private:
96 enum Type {
97 INVALID,
98 REGISTER,
99 CONSTANT
100 };
101
102 Type type_; 109 Type type_;
103 110
104 union { 111 union {
105 Register reg_; 112 Register reg_;
106 Object** handle_; 113 Object** handle_;
107 } data_; 114 } data_;
108 115
109 CodeGenerator* cgen_; 116 CodeGenerator* cgen_;
110 117
111 Type type() const { return type_; }
112
113 void CopyTo(Result* destination) const; 118 void CopyTo(Result* destination) const;
114 }; 119 };
115 120
116 121
117 // ------------------------------------------------------------------------- 122 // -------------------------------------------------------------------------
118 // Register file 123 // Register file
119 // 124 //
120 // The register file tracks reference counts for the processor registers. 125 // The register file tracks reference counts for the processor registers.
121 // It is used by both the register allocator and the virtual frame. 126 // It is used by both the register allocator and the virtual frame.
122 127
123 class RegisterFile BASE_EMBEDDED { 128 class RegisterFile BASE_EMBEDDED {
124 public: 129 public:
125 RegisterFile() { Reset(); } 130 RegisterFile() { Reset(); }
126 131
127 void Reset() { 132 void Reset() {
128 for (int i = 0; i < kNumRegisters; i++) { 133 for (int i = 0; i < kNumRegisters; i++) {
129 ref_counts_[i] = 0; 134 ref_counts_[i] = 0;
130 } 135 }
131 } 136 }
132 137
133 // Predicates and accessors for the reference counts. They take a 138 // Predicates and accessors for the reference counts. The versions
134 // register code rather than a register because they are frequently used 139 // that take a register code rather than a register are for
135 // in a loop over the register codes. 140 // convenience in loops over the register codes.
136 bool is_used(int reg_code) const { return ref_counts_[reg_code] > 0; } 141 bool is_used(int reg_code) const { return ref_counts_[reg_code] > 0; }
142 bool is_used(Register reg) const { return is_used(reg.code()); }
137 int count(int reg_code) const { return ref_counts_[reg_code]; } 143 int count(int reg_code) const { return ref_counts_[reg_code]; }
144 int count(Register reg) const { return count(reg.code()); }
138 145
139 // Record a use of a register by incrementing its reference count. 146 // Record a use of a register by incrementing its reference count.
140 void Use(Register reg) { 147 void Use(Register reg) {
141 ref_counts_[reg.code()]++; 148 ref_counts_[reg.code()]++;
142 } 149 }
143 150
144 // Record that a register will no longer be used by decrementing its 151 // Record that a register will no longer be used by decrementing its
145 // reference count. 152 // reference count.
146 void Unuse(Register reg) { 153 void Unuse(Register reg) {
147 ASSERT(is_used(reg.code())); 154 ASSERT(is_used(reg.code()));
(...skipping 14 matching lines...) Expand all
162 // 169 //
163 170
164 class RegisterAllocator BASE_EMBEDDED { 171 class RegisterAllocator BASE_EMBEDDED {
165 public: 172 public:
166 explicit RegisterAllocator(CodeGenerator* cgen) : cgen_(cgen) {} 173 explicit RegisterAllocator(CodeGenerator* cgen) : cgen_(cgen) {}
167 174
168 int num_registers() const { return RegisterFile::kNumRegisters; } 175 int num_registers() const { return RegisterFile::kNumRegisters; }
169 176
170 // Predicates and accessors for the registers' reference counts. 177 // Predicates and accessors for the registers' reference counts.
171 bool is_used(int reg_code) const { return registers_.is_used(reg_code); } 178 bool is_used(int reg_code) const { return registers_.is_used(reg_code); }
172 int count(int reg_code) { return registers_.count(reg_code); } 179 bool is_used(Register reg) const { return registers_.is_used(reg.code()); }
180 int count(int reg_code) const { return registers_.count(reg_code); }
181 int count(Register reg) const { return registers_.count(reg.code()); }
173 182
174 // Explicitly record a reference to a register. 183 // Explicitly record a reference to a register.
175 void Use(Register reg) { registers_.Use(reg); } 184 void Use(Register reg) { registers_.Use(reg); }
176 185
177 // Explicitly record that a register will no longer be used. 186 // Explicitly record that a register will no longer be used.
178 void Unuse(Register reg) { registers_.Unuse(reg); } 187 void Unuse(Register reg) { registers_.Unuse(reg); }
179 188
180 // Initialize the register allocator for entry to a JS function. On 189 // Initialize the register allocator for entry to a JS function. On
181 // entry, esp, ebp, esi, and edi are externally referenced (ie, outside 190 // entry, esp, ebp, esi, and edi are externally referenced (ie, outside
182 // the virtual frame); and the other registers are free. 191 // the virtual frame); and the other registers are free.
183 void Initialize(); 192 void Initialize();
184 193
185 // Allocate a free register and return a register result if possible or 194 // Allocate a free register and return a register result if possible or
186 // fail and return an invalid result. 195 // fail and return an invalid result.
187 Result Allocate(); 196 Result Allocate();
188 197
198 // Allocate a specific register if possible, spilling it from the frame if
199 // necessary, or else fail and regutrn an invalid result.
William Hesse 2008/12/22 13:55:21 and return an invalid result.
200 Result Allocate(Register target);
201
189 // Allocate a free register without spilling any from the current frame or 202 // Allocate a free register without spilling any from the current frame or
190 // fail and return an invalid result. 203 // fail and return an invalid result.
191 Result AllocateWithoutSpilling(); 204 Result AllocateWithoutSpilling();
192 205
193 private: 206 private:
194 CodeGenerator* cgen_; 207 CodeGenerator* cgen_;
195 RegisterFile registers_; 208 RegisterFile registers_;
196 }; 209 };
197 210
198 } } // namespace v8::internal 211 } } // namespace v8::internal
199 212
200 #endif // V8_REGISTER_ALLOCATOR_IA32_H_ 213 #endif // V8_REGISTER_ALLOCATOR_IA32_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698