OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 if (is_bound()) { | 73 if (is_bound()) { |
74 ASSERT(direction_ == BIDIRECTIONAL); | 74 ASSERT(direction_ == BIDIRECTIONAL); |
75 // Backward branch. We have an expected frame to merge to on the | 75 // Backward branch. We have an expected frame to merge to on the |
76 // backward edge. | 76 // backward edge. |
77 | 77 |
78 // Swap the current frame for a copy (we do the swapping to get | 78 // Swap the current frame for a copy (we do the swapping to get |
79 // the off-frame registers off the fall through) to use for the | 79 // the off-frame registers off the fall through) to use for the |
80 // branch. | 80 // branch. |
81 VirtualFrame* fall_through_frame = cgen()->frame(); | 81 VirtualFrame* fall_through_frame = cgen()->frame(); |
82 VirtualFrame* branch_frame = new VirtualFrame(fall_through_frame); | 82 VirtualFrame* branch_frame = new VirtualFrame(fall_through_frame); |
83 RegisterFile non_frame_registers = RegisterAllocator::Reserved(); | 83 RegisterFile non_frame_registers; |
84 cgen()->SetFrame(branch_frame, &non_frame_registers); | 84 cgen()->SetFrame(branch_frame, &non_frame_registers); |
85 | 85 |
86 // Check if we can avoid merge code. | 86 // Check if we can avoid merge code. |
87 cgen()->frame()->PrepareMergeTo(entry_frame_); | 87 cgen()->frame()->PrepareMergeTo(entry_frame_); |
88 if (cgen()->frame()->Equals(entry_frame_)) { | 88 if (cgen()->frame()->Equals(entry_frame_)) { |
89 // Branch right in to the block. | 89 // Branch right in to the block. |
90 cgen()->DeleteFrame(); | 90 cgen()->DeleteFrame(); |
91 __ b(cc, &entry_label_); | 91 __ b(cc, &entry_label_); |
92 cgen()->SetFrame(fall_through_frame, &non_frame_registers); | 92 cgen()->SetFrame(fall_through_frame, &non_frame_registers); |
93 return; | 93 return; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 // block. | 156 // block. |
157 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters()); | 157 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters()); |
158 | 158 |
159 if (direction_ == FORWARD_ONLY) { | 159 if (direction_ == FORWARD_ONLY) { |
160 // A simple case: no forward jumps and no possible backward jumps. | 160 // A simple case: no forward jumps and no possible backward jumps. |
161 if (!is_linked()) { | 161 if (!is_linked()) { |
162 // The stack pointer can be floating above the top of the | 162 // The stack pointer can be floating above the top of the |
163 // virtual frame before the bind. Afterward, it should not. | 163 // virtual frame before the bind. Afterward, it should not. |
164 ASSERT(cgen()->has_valid_frame()); | 164 ASSERT(cgen()->has_valid_frame()); |
165 VirtualFrame* frame = cgen()->frame(); | 165 VirtualFrame* frame = cgen()->frame(); |
166 int difference = | 166 int difference = frame->stack_pointer_ - (frame->element_count() - 1); |
167 frame->stack_pointer_ - (frame->elements_.length() - 1); | |
168 if (difference > 0) { | 167 if (difference > 0) { |
169 frame->stack_pointer_ -= difference; | 168 frame->stack_pointer_ -= difference; |
170 __ add(sp, sp, Operand(difference * kPointerSize)); | 169 __ add(sp, sp, Operand(difference * kPointerSize)); |
171 } | 170 } |
172 __ bind(&entry_label_); | 171 __ bind(&entry_label_); |
173 return; | 172 return; |
174 } | 173 } |
175 | 174 |
176 // Another simple case: no fall through, a single forward jump, | 175 // Another simple case: no fall through, a single forward jump, |
177 // and no possible backward jumps. | 176 // and no possible backward jumps. |
178 if (!cgen()->has_valid_frame() && reaching_frames_.length() == 1) { | 177 if (!cgen()->has_valid_frame() && reaching_frames_.length() == 1) { |
179 // Pick up the only reaching frame, take ownership of it, and | 178 // Pick up the only reaching frame, take ownership of it, and |
180 // use it for the block about to be emitted. | 179 // use it for the block about to be emitted. |
181 VirtualFrame* frame = reaching_frames_[0]; | 180 VirtualFrame* frame = reaching_frames_[0]; |
182 RegisterFile reserved = RegisterAllocator::Reserved(); | 181 RegisterFile empty; |
183 cgen()->SetFrame(frame, &reserved); | 182 cgen()->SetFrame(frame, &empty); |
184 reaching_frames_[0] = NULL; | 183 reaching_frames_[0] = NULL; |
185 __ bind(&merge_labels_[0]); | 184 __ bind(&merge_labels_[0]); |
186 | 185 |
187 // The stack pointer can be floating above the top of the | 186 // The stack pointer can be floating above the top of the |
188 // virtual frame before the bind. Afterward, it should not. | 187 // virtual frame before the bind. Afterward, it should not. |
189 int difference = | 188 int difference = frame->stack_pointer_ - (frame->element_count() - 1); |
190 frame->stack_pointer_ - (frame->elements_.length() - 1); | |
191 if (difference > 0) { | 189 if (difference > 0) { |
192 frame->stack_pointer_ -= difference; | 190 frame->stack_pointer_ -= difference; |
193 __ add(sp, sp, Operand(difference * kPointerSize)); | 191 __ add(sp, sp, Operand(difference * kPointerSize)); |
194 } | 192 } |
195 __ bind(&entry_label_); | 193 __ bind(&entry_label_); |
196 return; | 194 return; |
197 } | 195 } |
198 } | 196 } |
199 | 197 |
200 // If there is a current frame, record it as the fall-through. It | 198 // If there is a current frame, record it as the fall-through. It |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 // We could have a valid frame as the fall through to the | 238 // We could have a valid frame as the fall through to the |
241 // binding site or as the fall through from a previous merge | 239 // binding site or as the fall through from a previous merge |
242 // code block. Jump around the code we are about to | 240 // code block. Jump around the code we are about to |
243 // generate. | 241 // generate. |
244 if (cgen()->has_valid_frame()) { | 242 if (cgen()->has_valid_frame()) { |
245 cgen()->DeleteFrame(); | 243 cgen()->DeleteFrame(); |
246 __ b(&entry_label_); | 244 __ b(&entry_label_); |
247 } | 245 } |
248 // Pick up the frame for this block. Assume ownership if | 246 // Pick up the frame for this block. Assume ownership if |
249 // there cannot be backward jumps. | 247 // there cannot be backward jumps. |
250 RegisterFile reserved = RegisterAllocator::Reserved(); | 248 RegisterFile empty; |
251 if (direction_ == BIDIRECTIONAL) { | 249 if (direction_ == BIDIRECTIONAL) { |
252 cgen()->SetFrame(new VirtualFrame(frame), &reserved); | 250 cgen()->SetFrame(new VirtualFrame(frame), &empty); |
253 } else { | 251 } else { |
254 cgen()->SetFrame(frame, &reserved); | 252 cgen()->SetFrame(frame, &empty); |
255 reaching_frames_[i] = NULL; | 253 reaching_frames_[i] = NULL; |
256 } | 254 } |
257 __ bind(&merge_labels_[i]); | 255 __ bind(&merge_labels_[i]); |
258 | 256 |
259 // Loop over the remaining (non-null) reaching frames, | 257 // Loop over the remaining (non-null) reaching frames, |
260 // looking for any that can share merge code with this one. | 258 // looking for any that can share merge code with this one. |
261 for (int j = 0; j < i; j++) { | 259 for (int j = 0; j < i; j++) { |
262 VirtualFrame* other = reaching_frames_[j]; | 260 VirtualFrame* other = reaching_frames_[j]; |
263 if (other != NULL && other->Equals(cgen()->frame())) { | 261 if (other != NULL && other->Equals(cgen()->frame())) { |
264 // Set the reaching frame element to null to avoid | 262 // Set the reaching frame element to null to avoid |
265 // processing it later, and then bind its entry label. | 263 // processing it later, and then bind its entry label. |
266 reaching_frames_[j] = NULL; | 264 reaching_frames_[j] = NULL; |
267 __ bind(&merge_labels_[j]); | 265 __ bind(&merge_labels_[j]); |
268 } | 266 } |
269 } | 267 } |
270 | 268 |
271 // Emit the merge code. | 269 // Emit the merge code. |
272 cgen()->frame()->MergeTo(entry_frame_); | 270 cgen()->frame()->MergeTo(entry_frame_); |
273 } else if (i == reaching_frames_.length() - 1 && had_fall_through) { | 271 } else if (i == reaching_frames_.length() - 1 && had_fall_through) { |
274 // If this is the fall through, and it didn't need merge | 272 // If this is the fall through, and it didn't need merge |
275 // code, we need to pick up the frame so we can jump around | 273 // code, we need to pick up the frame so we can jump around |
276 // subsequent merge blocks if necessary. | 274 // subsequent merge blocks if necessary. |
277 RegisterFile reserved = RegisterAllocator::Reserved(); | 275 RegisterFile empty; |
278 cgen()->SetFrame(frame, &reserved); | 276 cgen()->SetFrame(frame, &empty); |
279 reaching_frames_[i] = NULL; | 277 reaching_frames_[i] = NULL; |
280 } | 278 } |
281 } | 279 } |
282 } | 280 } |
283 | 281 |
284 // The code generator may not have a current frame if there was no | 282 // The code generator may not have a current frame if there was no |
285 // fall through and none of the reaching frames needed merging. | 283 // fall through and none of the reaching frames needed merging. |
286 // In that case, clone the entry frame as the current frame. | 284 // In that case, clone the entry frame as the current frame. |
287 if (!cgen()->has_valid_frame()) { | 285 if (!cgen()->has_valid_frame()) { |
288 RegisterFile reserved_registers = RegisterAllocator::Reserved(); | 286 RegisterFile empty; |
289 cgen()->SetFrame(new VirtualFrame(entry_frame_), &reserved_registers); | 287 cgen()->SetFrame(new VirtualFrame(entry_frame_), &empty); |
290 } | 288 } |
291 | 289 |
292 // There may be unprocessed reaching frames that did not need | 290 // There may be unprocessed reaching frames that did not need |
293 // merge code. They will have unbound merge labels. Bind their | 291 // merge code. They will have unbound merge labels. Bind their |
294 // merge labels to be the same as the entry label and deallocate | 292 // merge labels to be the same as the entry label and deallocate |
295 // them. | 293 // them. |
296 for (int i = 0; i < reaching_frames_.length(); i++) { | 294 for (int i = 0; i < reaching_frames_.length(); i++) { |
297 if (!merge_labels_[i].is_bound()) { | 295 if (!merge_labels_[i].is_bound()) { |
298 reaching_frames_[i] = NULL; | 296 reaching_frames_[i] = NULL; |
299 __ bind(&merge_labels_[i]); | 297 __ bind(&merge_labels_[i]); |
300 } | 298 } |
301 } | 299 } |
302 | 300 |
303 // There are non-NULL reaching frames with bound labels for each | 301 // There are non-NULL reaching frames with bound labels for each |
304 // merge block, but only on backward targets. | 302 // merge block, but only on backward targets. |
305 } else { | 303 } else { |
306 // There were no forward jumps. There must be a current frame and | 304 // There were no forward jumps. There must be a current frame and |
307 // this must be a bidirectional target. | 305 // this must be a bidirectional target. |
308 ASSERT(reaching_frames_.length() == 1); | 306 ASSERT(reaching_frames_.length() == 1); |
309 ASSERT(reaching_frames_[0] != NULL); | 307 ASSERT(reaching_frames_[0] != NULL); |
310 ASSERT(direction_ == BIDIRECTIONAL); | 308 ASSERT(direction_ == BIDIRECTIONAL); |
311 | 309 |
312 // Use a copy of the reaching frame so the original can be saved | 310 // Use a copy of the reaching frame so the original can be saved |
313 // for possible reuse as a backward merge block. | 311 // for possible reuse as a backward merge block. |
314 RegisterFile reserved = RegisterAllocator::Reserved(); | 312 RegisterFile empty; |
315 cgen()->SetFrame(new VirtualFrame(reaching_frames_[0]), &reserved); | 313 cgen()->SetFrame(new VirtualFrame(reaching_frames_[0]), &empty); |
316 __ bind(&merge_labels_[0]); | 314 __ bind(&merge_labels_[0]); |
317 cgen()->frame()->MergeTo(entry_frame_); | 315 cgen()->frame()->MergeTo(entry_frame_); |
318 } | 316 } |
319 | 317 |
320 __ bind(&entry_label_); | 318 __ bind(&entry_label_); |
321 } | 319 } |
322 | 320 |
323 #undef __ | 321 #undef __ |
324 | 322 |
325 | 323 |
326 } } // namespace v8::internal | 324 } } // namespace v8::internal |
OLD | NEW |