| 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 } | 190 } |
| 191 | 191 |
| 192 // Build the new frame. A freshly allocated frame has memory elements | 192 // Build the new frame. A freshly allocated frame has memory elements |
| 193 // for the parameters and some platform-dependent elements (e.g., | 193 // for the parameters and some platform-dependent elements (e.g., |
| 194 // return address). Replace those first. | 194 // return address). Replace those first. |
| 195 entry_frame_ = new VirtualFrame(cgen_); | 195 entry_frame_ = new VirtualFrame(cgen_); |
| 196 int index = 0; | 196 int index = 0; |
| 197 for (; index < entry_frame_->elements_.length(); index++) { | 197 for (; index < entry_frame_->elements_.length(); index++) { |
| 198 // If the element is determined, set it now and count registers. | 198 // If the element is determined, set it now. Count registers. |
| 199 // Undetermined elements are initially recorded as if in memory. | 199 // Mark elements as copied exactly if they are. Undetermined |
| 200 // elements are initially recorded as if in memory. |
| 200 if (elements[index] != NULL) { | 201 if (elements[index] != NULL) { |
| 201 entry_frame_->elements_[index] = *elements[index]; | 202 entry_frame_->elements_[index] = *elements[index]; |
| 203 entry_frame_->elements_[index].clear_copied(); |
| 202 if (elements[index]->is_register()) { | 204 if (elements[index]->is_register()) { |
| 203 entry_frame_->register_locations_[elements[index]->reg().code()] = | 205 entry_frame_->register_locations_[elements[index]->reg().code()] = |
| 204 index; | 206 index; |
| 207 } else if (elements[index]->is_copy()) { |
| 208 entry_frame_->elements_[elements[index]->index()].set_copied(); |
| 205 } | 209 } |
| 206 } | 210 } |
| 207 } | 211 } |
| 208 // Then fill in the rest of the frame with new elements. | 212 // Then fill in the rest of the frame with new elements. |
| 209 for (; index < length; index++) { | 213 for (; index < length; index++) { |
| 210 if (elements[index] == NULL) { | 214 if (elements[index] == NULL) { |
| 211 entry_frame_->elements_.Add(FrameElement::MemoryElement()); | 215 entry_frame_->elements_.Add(FrameElement::MemoryElement()); |
| 212 } else { | 216 } else { |
| 213 entry_frame_->elements_.Add(*elements[index]); | 217 entry_frame_->elements_.Add(*elements[index]); |
| 218 entry_frame_->elements_[index].clear_copied(); |
| 214 if (elements[index]->is_register()) { | 219 if (elements[index]->is_register()) { |
| 215 entry_frame_->register_locations_[elements[index]->reg().code()] = | 220 entry_frame_->register_locations_[elements[index]->reg().code()] = |
| 216 index; | 221 index; |
| 222 } else if (elements[index]->is_copy()) { |
| 223 entry_frame_->elements_[elements[index]->index()].set_copied(); |
| 217 } | 224 } |
| 218 } | 225 } |
| 219 } | 226 } |
| 220 | 227 |
| 221 // Allocate any still-undetermined frame elements to registers or | 228 // Allocate any still-undetermined frame elements to registers or |
| 222 // memory, from the top down. | 229 // memory, from the top down. |
| 223 for (int i = length - 1; i >= 0; i--) { | 230 for (int i = length - 1; i >= 0; i--) { |
| 224 if (elements[i] == NULL) { | 231 if (elements[i] == NULL) { |
| 225 // If the value is synced on all frames, put it in memory. This | 232 // If the value is synced on all frames, put it in memory. This |
| 226 // costs nothing at the merge code but will incur a | 233 // costs nothing at the merge code but will incur a |
| (...skipping 27 matching lines...) Expand all Loading... |
| 254 // If there was no preferred choice consider any free register. | 261 // If there was no preferred choice consider any free register. |
| 255 if (best_reg_code == no_reg.code_) { | 262 if (best_reg_code == no_reg.code_) { |
| 256 for (int j = 0; j < kNumRegisters; j++) { | 263 for (int j = 0; j < kNumRegisters; j++) { |
| 257 if (!entry_frame_->is_used(j) && !RegisterAllocator::IsReserved(j)) { | 264 if (!entry_frame_->is_used(j) && !RegisterAllocator::IsReserved(j)) { |
| 258 best_reg_code = j; | 265 best_reg_code = j; |
| 259 break; | 266 break; |
| 260 } | 267 } |
| 261 } | 268 } |
| 262 } | 269 } |
| 263 | 270 |
| 264 // If there was a register choice, use it. If not do nothing | |
| 265 // (the element is already recorded as in memory) | |
| 266 if (best_reg_code != no_reg.code_) { | 271 if (best_reg_code != no_reg.code_) { |
| 272 // If there was a register choice, use it. Preserve the copied |
| 273 // flag on the element. |
| 274 bool is_copied = entry_frame_->elements_[i].is_copied(); |
| 267 Register reg = { best_reg_code }; | 275 Register reg = { best_reg_code }; |
| 268 entry_frame_->elements_[i] = | 276 entry_frame_->elements_[i] = |
| 269 FrameElement::RegisterElement(reg, | 277 FrameElement::RegisterElement(reg, |
| 270 FrameElement::NOT_SYNCED); | 278 FrameElement::NOT_SYNCED); |
| 279 if (is_copied) entry_frame_->elements_[i].set_copied(); |
| 271 entry_frame_->register_locations_[best_reg_code] = i; | 280 entry_frame_->register_locations_[best_reg_code] = i; |
| 272 } | 281 } |
| 282 // If there was no register found, the element is already |
| 283 // recorded as in memory. |
| 273 } | 284 } |
| 274 } | 285 } |
| 275 | 286 |
| 276 // Set the copied flags in the frame to be exact. This assumes that | 287 // Set the static type of frame elements. |
| 277 // the backing store of copies is always lower in the frame. | |
| 278 for (int i = 0; i < length; i++) { | 288 for (int i = 0; i < length; i++) { |
| 279 FrameElement* current = &entry_frame_->elements_[i]; | 289 FrameElement* current = &entry_frame_->elements_[i]; |
| 280 current->clear_copied(); | |
| 281 if (current->is_copy()) { | |
| 282 entry_frame_->elements_[current->index()].set_copied(); | |
| 283 } | |
| 284 | |
| 285 if (direction_ == BIDIRECTIONAL && i >= high_water_mark) { | 290 if (direction_ == BIDIRECTIONAL && i >= high_water_mark) { |
| 286 current->set_static_type(StaticType::unknown()); | 291 current->set_static_type(StaticType::unknown()); |
| 287 } else { | 292 } else { |
| 288 StaticType merged_type = reaching_frames_[0]->elements_[i].static_type(); | 293 StaticType merged_type = reaching_frames_[0]->elements_[i].static_type(); |
| 289 for (int j = 1, n = reaching_frames_.length(); | 294 for (int j = 1, n = reaching_frames_.length(); |
| 290 !merged_type.is_unknown() && j < n; | 295 !merged_type.is_unknown() && j < n; |
| 291 j++) { | 296 j++) { |
| 292 merged_type = | 297 merged_type = |
| 293 merged_type.merge(reaching_frames_[j]->elements_[i].static_type()); | 298 merged_type.merge(reaching_frames_[j]->elements_[i].static_type()); |
| 294 } | 299 } |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 temp.CopyTo(this); | 730 temp.CopyTo(this); |
| 726 temp.Reset(); // So the destructor does not deallocate virtual frames. | 731 temp.Reset(); // So the destructor does not deallocate virtual frames. |
| 727 | 732 |
| 728 #ifdef DEBUG | 733 #ifdef DEBUG |
| 729 is_shadowing_ = false; | 734 is_shadowing_ = false; |
| 730 #endif | 735 #endif |
| 731 } | 736 } |
| 732 | 737 |
| 733 | 738 |
| 734 } } // namespace v8::internal | 739 } } // namespace v8::internal |
| OLD | NEW |