 Chromium Code Reviews
 Chromium Code Reviews Issue 114018:
  Simplify JumpTarget::ComputeEntryFrame.  Eliminate a separate pass...  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
    
  
    Issue 114018:
  Simplify JumpTarget::ComputeEntryFrame.  Eliminate a separate pass...  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/| 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 |