| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 } | 67 } |
| 68 ASSERT(!all_identical || all_identical); | 68 ASSERT(!all_identical || all_identical); |
| 69 } | 69 } |
| 70 #endif | 70 #endif |
| 71 | 71 |
| 72 // Choose an initial frame. | 72 // Choose an initial frame. |
| 73 VirtualFrame* initial_frame = reaching_frames_[0]; | 73 VirtualFrame* initial_frame = reaching_frames_[0]; |
| 74 | 74 |
| 75 // A list of pointers to frame elements in the entry frame. NULL | 75 // A list of pointers to frame elements in the entry frame. NULL |
| 76 // indicates that the element has not yet been determined. | 76 // indicates that the element has not yet been determined. |
| 77 int length = initial_frame->elements_.length(); | 77 int length = initial_frame->element_count(); |
| 78 ZoneList<FrameElement*> elements(length); | 78 ZoneList<FrameElement*> elements(length); |
| 79 | 79 |
| 80 // Convert the number of mergable elements (counted from the top | 80 // Convert the number of mergable elements (counted from the top |
| 81 // down) to a frame high-water mark (counted from the bottom up). | 81 // down) to a frame high-water mark (counted from the bottom up). |
| 82 // Elements strictly above the high-water index will be mergable in | 82 // Elements strictly above the high-water index will be mergable in |
| 83 // entry frames for bidirectional jump targets. | 83 // entry frames for bidirectional jump targets. |
| 84 int high_water_mark = (mergable_elements == kAllElements) | 84 int high_water_mark = (mergable_elements == kAllElements) |
| 85 ? VirtualFrame::kIllegalIndex // All frame indices are above this. | 85 ? VirtualFrame::kIllegalIndex // All frame indices are above this. |
| 86 : length - mergable_elements - 1; // Top index if m_e == 0. | 86 : length - mergable_elements - 1; // Top index if m_e == 0. |
| 87 | 87 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 117 } | 117 } |
| 118 elements[i] = element; | 118 elements[i] = element; |
| 119 } | 119 } |
| 120 } | 120 } |
| 121 | 121 |
| 122 // Build the new frame. A freshly allocated frame has memory elements | 122 // Build the new frame. A freshly allocated frame has memory elements |
| 123 // for the parameters and some platform-dependent elements (e.g., | 123 // for the parameters and some platform-dependent elements (e.g., |
| 124 // return address). Replace those first. | 124 // return address). Replace those first. |
| 125 entry_frame_ = new VirtualFrame(); | 125 entry_frame_ = new VirtualFrame(); |
| 126 int index = 0; | 126 int index = 0; |
| 127 for (; index < entry_frame_->elements_.length(); index++) { | 127 for (; index < entry_frame_->element_count(); index++) { |
| 128 FrameElement* target = elements[index]; | 128 FrameElement* target = elements[index]; |
| 129 // If the element is determined, set it now. Count registers. Mark | 129 // If the element is determined, set it now. Count registers. Mark |
| 130 // elements as copied exactly when they have a copy. Undetermined | 130 // elements as copied exactly when they have a copy. Undetermined |
| 131 // elements are initially recorded as if in memory. | 131 // elements are initially recorded as if in memory. |
| 132 if (target != NULL) { | 132 if (target != NULL) { |
| 133 entry_frame_->elements_[index] = *target; | 133 entry_frame_->elements_[index] = *target; |
| 134 InitializeEntryElement(index, target); | 134 InitializeEntryElement(index, target); |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 // Then fill in the rest of the frame with new elements. | 137 // Then fill in the rest of the frame with new elements. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 148 // Allocate any still-undetermined frame elements to registers or | 148 // Allocate any still-undetermined frame elements to registers or |
| 149 // memory, from the top down. | 149 // memory, from the top down. |
| 150 for (int i = length - 1; i >= 0; i--) { | 150 for (int i = length - 1; i >= 0; i--) { |
| 151 if (elements[i] == NULL) { | 151 if (elements[i] == NULL) { |
| 152 // Loop over all the reaching frames to check whether the element | 152 // Loop over all the reaching frames to check whether the element |
| 153 // is synced on all frames, to count the registers it occupies, | 153 // is synced on all frames, to count the registers it occupies, |
| 154 // and to compute a merged static type. | 154 // and to compute a merged static type. |
| 155 bool is_synced = true; | 155 bool is_synced = true; |
| 156 RegisterFile candidate_registers; | 156 RegisterFile candidate_registers; |
| 157 int best_count = kMinInt; | 157 int best_count = kMinInt; |
| 158 int best_reg_code = no_reg.code_; | 158 int best_reg_num = RegisterAllocator::kInvalidRegister; |
| 159 | 159 |
| 160 StaticType type; // Initially invalid. | 160 StaticType type; // Initially invalid. |
| 161 if (direction_ != BIDIRECTIONAL || i < high_water_mark) { | 161 if (direction_ != BIDIRECTIONAL || i < high_water_mark) { |
| 162 type = reaching_frames_[0]->elements_[i].static_type(); | 162 type = reaching_frames_[0]->elements_[i].static_type(); |
| 163 } | 163 } |
| 164 | 164 |
| 165 for (int j = 0; j < reaching_frames_.length(); j++) { | 165 for (int j = 0; j < reaching_frames_.length(); j++) { |
| 166 FrameElement element = reaching_frames_[j]->elements_[i]; | 166 FrameElement element = reaching_frames_[j]->elements_[i]; |
| 167 is_synced = is_synced && element.is_synced(); | 167 is_synced = is_synced && element.is_synced(); |
| 168 if (element.is_register() && !entry_frame_->is_used(element.reg())) { | 168 if (element.is_register() && !entry_frame_->is_used(element.reg())) { |
| 169 // Count the register occurrence and remember it if better | 169 // Count the register occurrence and remember it if better |
| 170 // than the previous best. | 170 // than the previous best. |
| 171 candidate_registers.Use(element.reg()); | 171 int num = RegisterAllocator::ToNumber(element.reg()); |
| 172 if (candidate_registers.count(element.reg()) > best_count) { | 172 candidate_registers.Use(num); |
| 173 best_count = candidate_registers.count(element.reg()); | 173 if (candidate_registers.count(num) > best_count) { |
| 174 best_reg_code = element.reg().code(); | 174 best_count = candidate_registers.count(num); |
| 175 best_reg_num = num; |
| 175 } | 176 } |
| 176 } | 177 } |
| 177 type = type.merge(element.static_type()); | 178 type = type.merge(element.static_type()); |
| 178 } | 179 } |
| 179 | 180 |
| 180 // If the value is synced on all frames, put it in memory. This | 181 // If the value is synced on all frames, put it in memory. This |
| 181 // costs nothing at the merge code but will incur a | 182 // costs nothing at the merge code but will incur a |
| 182 // memory-to-register move when the value is needed later. | 183 // memory-to-register move when the value is needed later. |
| 183 if (is_synced) { | 184 if (is_synced) { |
| 184 // Already recorded as a memory element. | 185 // Already recorded as a memory element. |
| 185 entry_frame_->elements_[i].set_static_type(type); | 186 entry_frame_->elements_[i].set_static_type(type); |
| 186 continue; | 187 continue; |
| 187 } | 188 } |
| 188 | 189 |
| 189 // Try to put it in a register. If there was no best choice | 190 // Try to put it in a register. If there was no best choice |
| 190 // consider any free register. | 191 // consider any free register. |
| 191 if (best_reg_code == no_reg.code_) { | 192 if (best_reg_num == RegisterAllocator::kInvalidRegister) { |
| 192 for (int j = 0; j < kNumRegisters; j++) { | 193 for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { |
| 193 if (!entry_frame_->is_used(j) && !RegisterAllocator::IsReserved(j)) { | 194 if (!entry_frame_->is_used(j)) { |
| 194 best_reg_code = j; | 195 best_reg_num = j; |
| 195 break; | 196 break; |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 } | 199 } |
| 199 | 200 |
| 200 if (best_reg_code == no_reg.code_) { | 201 if (best_reg_num == RegisterAllocator::kInvalidRegister) { |
| 201 // If there was no register found, the element is already | 202 // If there was no register found, the element is already |
| 202 // recorded as in memory. | 203 // recorded as in memory. |
| 203 entry_frame_->elements_[i].set_static_type(type); | 204 entry_frame_->elements_[i].set_static_type(type); |
| 204 } else { | 205 } else { |
| 205 // If there was a register choice, use it. Preserve the copied | 206 // If there was a register choice, use it. Preserve the copied |
| 206 // flag on the element. Set the static type as computed. | 207 // flag on the element. Set the static type as computed. |
| 207 bool is_copied = entry_frame_->elements_[i].is_copied(); | 208 bool is_copied = entry_frame_->elements_[i].is_copied(); |
| 208 Register reg = { best_reg_code }; | 209 Register reg = RegisterAllocator::ToRegister(best_reg_num); |
| 209 entry_frame_->elements_[i] = | 210 entry_frame_->elements_[i] = |
| 210 FrameElement::RegisterElement(reg, | 211 FrameElement::RegisterElement(reg, |
| 211 FrameElement::NOT_SYNCED); | 212 FrameElement::NOT_SYNCED); |
| 212 if (is_copied) entry_frame_->elements_[i].set_copied(); | 213 if (is_copied) entry_frame_->elements_[i].set_copied(); |
| 213 entry_frame_->elements_[i].set_static_type(type); | 214 entry_frame_->elements_[i].set_static_type(type); |
| 214 entry_frame_->register_locations_[best_reg_code] = i; | 215 entry_frame_->set_register_location(reg, i); |
| 215 } | 216 } |
| 216 } | 217 } |
| 217 } | 218 } |
| 218 | 219 |
| 219 // The stack pointer is at the highest synced element or the base of | 220 // The stack pointer is at the highest synced element or the base of |
| 220 // the expression stack. | 221 // the expression stack. |
| 221 int stack_pointer = length - 1; | 222 int stack_pointer = length - 1; |
| 222 while (stack_pointer >= entry_frame_->expression_base_index() && | 223 while (stack_pointer >= entry_frame_->expression_base_index() && |
| 223 !entry_frame_->elements_[stack_pointer].is_synced()) { | 224 !entry_frame_->elements_[stack_pointer].is_synced()) { |
| 224 stack_pointer--; | 225 stack_pointer--; |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 temp.CopyTo(this); | 604 temp.CopyTo(this); |
| 604 temp.Unuse(); | 605 temp.Unuse(); |
| 605 | 606 |
| 606 #ifdef DEBUG | 607 #ifdef DEBUG |
| 607 is_shadowing_ = false; | 608 is_shadowing_ = false; |
| 608 #endif | 609 #endif |
| 609 } | 610 } |
| 610 | 611 |
| 611 | 612 |
| 612 } } // namespace v8::internal | 613 } } // namespace v8::internal |
| OLD | NEW |