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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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->element_count(); | 77 int length = initial_frame->element_count(); |
78 ZoneList<FrameElement*> elements(length); | 78 ZoneList<FrameElement*> elements(length); |
79 | 79 |
80 // Initially populate the list of elements based on the initial | 80 // Initially populate the list of elements based on the initial |
81 // frame. | 81 // frame. |
82 for (int i = 0; i < length; i++) { | 82 for (int i = 0; i < length; i++) { |
83 FrameElement element = initial_frame->elements_[i]; | 83 FrameElement element = initial_frame->elements_[i]; |
84 // We do not allow copies or constants in bidirectional frames. All | 84 // We do not allow copies or constants in bidirectional frames. |
85 // elements above the water mark on bidirectional frames have | |
86 // unknown static types. | |
87 if (direction_ == BIDIRECTIONAL) { | 85 if (direction_ == BIDIRECTIONAL) { |
88 if (element.is_constant() || element.is_copy()) { | 86 if (element.is_constant() || element.is_copy()) { |
89 elements.Add(NULL); | 87 elements.Add(NULL); |
90 continue; | 88 continue; |
91 } | 89 } |
92 // It's safe to change the static type on the initial frame | |
93 // element, see comment in JumpTarget::Combine. | |
94 initial_frame->elements_[i].set_static_type(StaticType::unknown()); | |
95 } | 90 } |
96 elements.Add(&initial_frame->elements_[i]); | 91 elements.Add(&initial_frame->elements_[i]); |
97 } | 92 } |
98 | 93 |
99 // Compute elements based on the other reaching frames. | 94 // Compute elements based on the other reaching frames. |
100 if (reaching_frames_.length() > 1) { | 95 if (reaching_frames_.length() > 1) { |
101 for (int i = 0; i < length; i++) { | 96 for (int i = 0; i < length; i++) { |
102 FrameElement* element = elements[i]; | 97 FrameElement* element = elements[i]; |
103 for (int j = 1; j < reaching_frames_.length(); j++) { | 98 for (int j = 1; j < reaching_frames_.length(); j++) { |
104 // Element computation is monotonic: new information will not | 99 // Element computation is monotonic: new information will not |
(...skipping 30 matching lines...) Expand all Loading... |
135 entry_frame_->elements_.Add(*target); | 130 entry_frame_->elements_.Add(*target); |
136 InitializeEntryElement(index, target); | 131 InitializeEntryElement(index, target); |
137 } | 132 } |
138 } | 133 } |
139 | 134 |
140 // Allocate any still-undetermined frame elements to registers or | 135 // Allocate any still-undetermined frame elements to registers or |
141 // memory, from the top down. | 136 // memory, from the top down. |
142 for (int i = length - 1; i >= 0; i--) { | 137 for (int i = length - 1; i >= 0; i--) { |
143 if (elements[i] == NULL) { | 138 if (elements[i] == NULL) { |
144 // Loop over all the reaching frames to check whether the element | 139 // Loop over all the reaching frames to check whether the element |
145 // is synced on all frames, to count the registers it occupies, | 140 // is synced on all frames and to count the registers it occupies. |
146 // and to compute a merged static type. | |
147 bool is_synced = true; | 141 bool is_synced = true; |
148 RegisterFile candidate_registers; | 142 RegisterFile candidate_registers; |
149 int best_count = kMinInt; | 143 int best_count = kMinInt; |
150 int best_reg_num = RegisterAllocator::kInvalidRegister; | 144 int best_reg_num = RegisterAllocator::kInvalidRegister; |
151 | 145 |
152 StaticType type; // Initially invalid. | |
153 if (direction_ != BIDIRECTIONAL) { | |
154 type = reaching_frames_[0]->elements_[i].static_type(); | |
155 } | |
156 | |
157 for (int j = 0; j < reaching_frames_.length(); j++) { | 146 for (int j = 0; j < reaching_frames_.length(); j++) { |
158 FrameElement element = reaching_frames_[j]->elements_[i]; | 147 FrameElement element = reaching_frames_[j]->elements_[i]; |
159 is_synced = is_synced && element.is_synced(); | 148 is_synced = is_synced && element.is_synced(); |
160 if (element.is_register() && !entry_frame_->is_used(element.reg())) { | 149 if (element.is_register() && !entry_frame_->is_used(element.reg())) { |
161 // Count the register occurrence and remember it if better | 150 // Count the register occurrence and remember it if better |
162 // than the previous best. | 151 // than the previous best. |
163 int num = RegisterAllocator::ToNumber(element.reg()); | 152 int num = RegisterAllocator::ToNumber(element.reg()); |
164 candidate_registers.Use(num); | 153 candidate_registers.Use(num); |
165 if (candidate_registers.count(num) > best_count) { | 154 if (candidate_registers.count(num) > best_count) { |
166 best_count = candidate_registers.count(num); | 155 best_count = candidate_registers.count(num); |
167 best_reg_num = num; | 156 best_reg_num = num; |
168 } | 157 } |
169 } | 158 } |
170 type = type.merge(element.static_type()); | |
171 } | 159 } |
172 | 160 |
173 // If the value is synced on all frames, put it in memory. This | 161 // If the value is synced on all frames, put it in memory. This |
174 // costs nothing at the merge code but will incur a | 162 // costs nothing at the merge code but will incur a |
175 // memory-to-register move when the value is needed later. | 163 // memory-to-register move when the value is needed later. |
176 if (is_synced) { | 164 if (is_synced) { |
177 // Already recorded as a memory element. | 165 // Already recorded as a memory element. |
178 entry_frame_->elements_[i].set_static_type(type); | |
179 continue; | 166 continue; |
180 } | 167 } |
181 | 168 |
182 // Try to put it in a register. If there was no best choice | 169 // Try to put it in a register. If there was no best choice |
183 // consider any free register. | 170 // consider any free register. |
184 if (best_reg_num == RegisterAllocator::kInvalidRegister) { | 171 if (best_reg_num == RegisterAllocator::kInvalidRegister) { |
185 for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { | 172 for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { |
186 if (!entry_frame_->is_used(j)) { | 173 if (!entry_frame_->is_used(j)) { |
187 best_reg_num = j; | 174 best_reg_num = j; |
188 break; | 175 break; |
189 } | 176 } |
190 } | 177 } |
191 } | 178 } |
192 | 179 |
193 if (best_reg_num == RegisterAllocator::kInvalidRegister) { | 180 if (best_reg_num != RegisterAllocator::kInvalidRegister) { |
194 // If there was no register found, the element is already | |
195 // recorded as in memory. | |
196 entry_frame_->elements_[i].set_static_type(type); | |
197 } else { | |
198 // If there was a register choice, use it. Preserve the copied | 181 // If there was a register choice, use it. Preserve the copied |
199 // flag on the element. Set the static type as computed. | 182 // flag on the element. |
200 bool is_copied = entry_frame_->elements_[i].is_copied(); | 183 bool is_copied = entry_frame_->elements_[i].is_copied(); |
201 Register reg = RegisterAllocator::ToRegister(best_reg_num); | 184 Register reg = RegisterAllocator::ToRegister(best_reg_num); |
202 entry_frame_->elements_[i] = | 185 entry_frame_->elements_[i] = |
203 FrameElement::RegisterElement(reg, | 186 FrameElement::RegisterElement(reg, |
204 FrameElement::NOT_SYNCED); | 187 FrameElement::NOT_SYNCED); |
205 if (is_copied) entry_frame_->elements_[i].set_copied(); | 188 if (is_copied) entry_frame_->elements_[i].set_copied(); |
206 entry_frame_->elements_[i].set_static_type(type); | |
207 entry_frame_->set_register_location(reg, i); | 189 entry_frame_->set_register_location(reg, i); |
208 } | 190 } |
209 } | 191 } |
210 } | 192 } |
211 | 193 |
212 // The stack pointer is at the highest synced element or the base of | 194 // The stack pointer is at the highest synced element or the base of |
213 // the expression stack. | 195 // the expression stack. |
214 int stack_pointer = length - 1; | 196 int stack_pointer = length - 1; |
215 while (stack_pointer >= entry_frame_->expression_base_index() && | 197 while (stack_pointer >= entry_frame_->expression_base_index() && |
216 !entry_frame_->elements_[stack_pointer].is_synced()) { | 198 !entry_frame_->elements_[stack_pointer].is_synced()) { |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 temp.CopyTo(this); | 435 temp.CopyTo(this); |
454 temp.Unuse(); | 436 temp.Unuse(); |
455 | 437 |
456 #ifdef DEBUG | 438 #ifdef DEBUG |
457 is_shadowing_ = false; | 439 is_shadowing_ = false; |
458 #endif | 440 #endif |
459 } | 441 } |
460 | 442 |
461 | 443 |
462 } } // namespace v8::internal | 444 } } // namespace v8::internal |
OLD | NEW |