OLD | NEW |
---|---|
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 | 182 |
183 // Element computation is monotonic: new information will not | 183 // Element computation is monotonic: new information will not |
184 // change our decision about undetermined or invalid elements. | 184 // change our decision about undetermined or invalid elements. |
185 if (element == NULL || !element->is_valid()) break; | 185 if (element == NULL || !element->is_valid()) break; |
186 | 186 |
187 elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]); | 187 elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]); |
188 } | 188 } |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 // Compute the registers already reserved by values in the frame. | 192 // Build the new frame. Initially it has memory elements for the |
193 // Count the reserved registers to avoid using them. | 193 // parameters and some platform-dependent elements (e.g., return |
194 RegisterFile frame_registers = RegisterAllocator::Reserved(); | 194 // address). Fill those in first. |
William Hesse
2009/05/11 13:47:34
The new frame does not "have" memory elements for
Kevin Millikin (Chromium)
2009/05/11 13:57:15
Replaced with:
// Build the new frame. A freshl
| |
195 for (int i = 0; i < length; i++) { | 195 entry_frame_ = new VirtualFrame(cgen_); |
196 FrameElement* element = elements[i]; | 196 int index = 0; |
197 if (element != NULL && element->is_register()) { | 197 for (; index < entry_frame_->elements_.length(); index++) { |
198 frame_registers.Use(element->reg()); | 198 // If the element is determined, set it now and count registers. |
199 // Undetermined elements are initially recorded as if in memory. | |
200 if (elements[index] != NULL) { | |
201 entry_frame_->elements_[index] = *elements[index]; | |
202 if (elements[index]->is_register()) { | |
203 entry_frame_->register_locations_[elements[index]->reg().code()] = | |
204 index; | |
205 } | |
206 } | |
207 } | |
208 // Fill in the rest of the frame with new elements. | |
209 for (; index < length; index++) { | |
210 if (elements[index] == NULL) { | |
211 entry_frame_->elements_.Add(FrameElement::MemoryElement()); | |
212 } else { | |
213 entry_frame_->elements_.Add(*elements[index]); | |
214 if (elements[index]->is_register()) { | |
215 entry_frame_->register_locations_[elements[index]->reg().code()] = | |
216 index; | |
217 } | |
199 } | 218 } |
200 } | 219 } |
201 | 220 |
202 // Build the new frame. The frame already has memory elements for | 221 // Allocate any still-undetermined frame elements to registers or |
203 // the parameters (including the receiver) and the return address. | 222 // memory, from the top down. |
204 // We will fill it up with memory elements. | |
205 entry_frame_ = new VirtualFrame(cgen_); | |
206 while (entry_frame_->elements_.length() < length) { | |
207 entry_frame_->elements_.Add(FrameElement::MemoryElement()); | |
208 } | |
209 | |
210 | |
211 // Copy the already-determined frame elements to the entry frame, | |
212 // and allocate any still-undetermined frame elements to registers | |
213 // or memory, from the top down. | |
214 for (int i = length - 1; i >= 0; i--) { | 223 for (int i = length - 1; i >= 0; i--) { |
215 if (elements[i] == NULL) { | 224 if (elements[i] == NULL) { |
216 // If the value is synced on all frames, put it in memory. This | 225 // If the value is synced on all frames, put it in memory. This |
217 // costs nothing at the merge code but will incur a | 226 // costs nothing at the merge code but will incur a |
218 // memory-to-register move when the value is needed later. | 227 // memory-to-register move when the value is needed later. |
219 bool is_synced = true; | 228 bool is_synced = true; |
220 for (int j = 0; is_synced && j < reaching_frames_.length(); j++) { | 229 for (int j = 0; is_synced && j < reaching_frames_.length(); j++) { |
221 is_synced = reaching_frames_[j]->elements_[i].is_synced(); | 230 is_synced = reaching_frames_[j]->elements_[i].is_synced(); |
222 } | 231 } |
223 | 232 |
224 // There is nothing to be done if the elements are all synced. | 233 // There is nothing to be done if the elements are all synced. |
225 // It is already recorded as a memory element. | 234 // It is already recorded as a memory element. |
226 if (is_synced) continue; | 235 if (is_synced) continue; |
227 | 236 |
228 // Choose an available register. Prefer ones that the element | 237 // Choose an available register. Prefer ones that the element |
229 // is already occupying on some reaching frame. | 238 // is already occupying on some reaching frame. |
230 RegisterFile candidate_registers; | 239 RegisterFile candidate_registers; |
231 int max_count = kMinInt; | 240 int max_count = kMinInt; |
232 int best_reg_code = no_reg.code_; | 241 int best_reg_code = no_reg.code_; |
233 | 242 |
234 for (int j = 0; j < reaching_frames_.length(); j++) { | 243 for (int j = 0; j < reaching_frames_.length(); j++) { |
235 FrameElement element = reaching_frames_[j]->elements_[i]; | 244 FrameElement element = reaching_frames_[j]->elements_[i]; |
236 if (element.is_register() && | 245 if (element.is_register() && |
237 !frame_registers.is_used(element.reg())) { | 246 !entry_frame_->is_used(element.reg())) { |
238 candidate_registers.Use(element.reg()); | 247 candidate_registers.Use(element.reg()); |
239 if (candidate_registers.count(element.reg()) > max_count) { | 248 if (candidate_registers.count(element.reg()) > max_count) { |
240 max_count = candidate_registers.count(element.reg()); | 249 max_count = candidate_registers.count(element.reg()); |
241 best_reg_code = element.reg().code(); | 250 best_reg_code = element.reg().code(); |
242 } | 251 } |
243 } | 252 } |
244 } | 253 } |
245 // If there was no preferred choice consider any free register. | 254 // If there was no preferred choice consider any free register. |
246 if (best_reg_code == no_reg.code_) { | 255 if (best_reg_code == no_reg.code_) { |
247 for (int j = 0; j < kNumRegisters; j++) { | 256 for (int j = 0; j < kNumRegisters; j++) { |
248 if (!frame_registers.is_used(j)) { | 257 if (!entry_frame_->is_used(j) && !RegisterAllocator::IsReserved(j)) { |
249 best_reg_code = j; | 258 best_reg_code = j; |
250 break; | 259 break; |
251 } | 260 } |
252 } | 261 } |
253 } | 262 } |
254 | 263 |
255 // If there was a register choice, use it. If not do nothing | 264 // If there was a register choice, use it. If not do nothing |
256 // (the element is already recorded as in memory) | 265 // (the element is already recorded as in memory) |
257 if (best_reg_code != no_reg.code_) { | 266 if (best_reg_code != no_reg.code_) { |
258 Register reg = { best_reg_code }; | 267 Register reg = { best_reg_code }; |
259 frame_registers.Use(reg); | |
260 entry_frame_->elements_[i] = | 268 entry_frame_->elements_[i] = |
261 FrameElement::RegisterElement(reg, | 269 FrameElement::RegisterElement(reg, |
262 FrameElement::NOT_SYNCED); | 270 FrameElement::NOT_SYNCED); |
271 entry_frame_->register_locations_[best_reg_code] = i; | |
263 } | 272 } |
264 } else { | |
265 // The element is already determined. | |
266 entry_frame_->elements_[i] = *elements[i]; | |
267 } | 273 } |
268 } | 274 } |
269 | 275 |
270 // Set the copied flags in the frame to be exact. This assumes that | 276 // Set the copied flags in the frame to be exact. This assumes that |
271 // the backing store of copies is always lower in the frame. | 277 // the backing store of copies is always lower in the frame. |
272 // Set the register locations to their index in the frame. | |
273 for (int i = 0; i < length; i++) { | 278 for (int i = 0; i < length; i++) { |
274 FrameElement* current = &entry_frame_->elements_[i]; | 279 FrameElement* current = &entry_frame_->elements_[i]; |
275 current->clear_copied(); | 280 current->clear_copied(); |
276 if (current->is_copy()) { | 281 if (current->is_copy()) { |
277 entry_frame_->elements_[current->index()].set_copied(); | 282 entry_frame_->elements_[current->index()].set_copied(); |
278 } else if (current->is_register()) { | |
279 entry_frame_->register_locations_[current->reg().code()] = i; | |
280 } | 283 } |
281 | 284 |
282 if (direction_ == BIDIRECTIONAL && i >= high_water_mark) { | 285 if (direction_ == BIDIRECTIONAL && i >= high_water_mark) { |
283 current->set_static_type(StaticType::unknown()); | 286 current->set_static_type(StaticType::unknown()); |
284 } else { | 287 } else { |
285 StaticType merged_type = reaching_frames_[0]->elements_[i].static_type(); | 288 StaticType merged_type = reaching_frames_[0]->elements_[i].static_type(); |
286 for (int j = 1, n = reaching_frames_.length(); | 289 for (int j = 1, n = reaching_frames_.length(); |
287 !merged_type.is_unknown() && j < n; | 290 !merged_type.is_unknown() && j < n; |
288 j++) { | 291 j++) { |
289 merged_type = | 292 merged_type = |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
722 temp.CopyTo(this); | 725 temp.CopyTo(this); |
723 temp.Reset(); // So the destructor does not deallocate virtual frames. | 726 temp.Reset(); // So the destructor does not deallocate virtual frames. |
724 | 727 |
725 #ifdef DEBUG | 728 #ifdef DEBUG |
726 is_shadowing_ = false; | 729 is_shadowing_ = false; |
727 #endif | 730 #endif |
728 } | 731 } |
729 | 732 |
730 | 733 |
731 } } // namespace v8::internal | 734 } } // namespace v8::internal |
OLD | NEW |