Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: src/ia32/jump-target-ia32.cc

Issue 113837: Change the register allocator so that it no longer tracks references... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 if (is_bound()) { 77 if (is_bound()) {
78 ASSERT(direction_ == BIDIRECTIONAL); 78 ASSERT(direction_ == BIDIRECTIONAL);
79 // Backward branch. We have an expected frame to merge to on the 79 // Backward branch. We have an expected frame to merge to on the
80 // backward edge. 80 // backward edge.
81 81
82 // Swap the current frame for a copy (we do the swapping to get 82 // Swap the current frame for a copy (we do the swapping to get
83 // the off-frame registers off the fall through) to use for the 83 // the off-frame registers off the fall through) to use for the
84 // branch. 84 // branch.
85 VirtualFrame* fall_through_frame = cgen()->frame(); 85 VirtualFrame* fall_through_frame = cgen()->frame();
86 VirtualFrame* branch_frame = new VirtualFrame(fall_through_frame); 86 VirtualFrame* branch_frame = new VirtualFrame(fall_through_frame);
87 RegisterFile non_frame_registers = RegisterAllocator::Reserved(); 87 RegisterFile non_frame_registers;
88 cgen()->SetFrame(branch_frame, &non_frame_registers); 88 cgen()->SetFrame(branch_frame, &non_frame_registers);
89 89
90 // Check if we can avoid merge code. 90 // Check if we can avoid merge code.
91 cgen()->frame()->PrepareMergeTo(entry_frame_); 91 cgen()->frame()->PrepareMergeTo(entry_frame_);
92 if (cgen()->frame()->Equals(entry_frame_)) { 92 if (cgen()->frame()->Equals(entry_frame_)) {
93 // Branch right in to the block. 93 // Branch right in to the block.
94 cgen()->DeleteFrame(); 94 cgen()->DeleteFrame();
95 __ j(cc, &entry_label_, hint); 95 __ j(cc, &entry_label_, hint);
96 cgen()->SetFrame(fall_through_frame, &non_frame_registers); 96 cgen()->SetFrame(fall_through_frame, &non_frame_registers);
97 return; 97 return;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 // block. 172 // block.
173 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters()); 173 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters());
174 174
175 // Fast case: the jump target was manually configured with an entry 175 // Fast case: the jump target was manually configured with an entry
176 // frame to use. 176 // frame to use.
177 if (entry_frame_ != NULL) { 177 if (entry_frame_ != NULL) {
178 // Assert no reaching frames to deal with. 178 // Assert no reaching frames to deal with.
179 ASSERT(reaching_frames_.is_empty()); 179 ASSERT(reaching_frames_.is_empty());
180 ASSERT(!cgen()->has_valid_frame()); 180 ASSERT(!cgen()->has_valid_frame());
181 181
182 RegisterFile reserved = RegisterAllocator::Reserved(); 182 RegisterFile empty;
183 if (direction_ == BIDIRECTIONAL) { 183 if (direction_ == BIDIRECTIONAL) {
184 // Copy the entry frame so the original can be used for a 184 // Copy the entry frame so the original can be used for a
185 // possible backward jump. 185 // possible backward jump.
186 cgen()->SetFrame(new VirtualFrame(entry_frame_), &reserved); 186 cgen()->SetFrame(new VirtualFrame(entry_frame_), &empty);
187 } else { 187 } else {
188 // Take ownership of the entry frame. 188 // Take ownership of the entry frame.
189 cgen()->SetFrame(entry_frame_, &reserved); 189 cgen()->SetFrame(entry_frame_, &empty);
190 entry_frame_ = NULL; 190 entry_frame_ = NULL;
191 } 191 }
192 __ bind(&entry_label_); 192 __ bind(&entry_label_);
193 return; 193 return;
194 } 194 }
195 195
196 if (!is_linked()) { 196 if (!is_linked()) {
197 ASSERT(cgen()->has_valid_frame()); 197 ASSERT(cgen()->has_valid_frame());
198 if (direction_ == FORWARD_ONLY) { 198 if (direction_ == FORWARD_ONLY) {
199 // Fast case: no forward jumps and no possible backward jumps. 199 // Fast case: no forward jumps and no possible backward jumps.
200 // The stack pointer can be floating above the top of the 200 // The stack pointer can be floating above the top of the
201 // virtual frame before the bind. Afterward, it should not. 201 // virtual frame before the bind. Afterward, it should not.
202 VirtualFrame* frame = cgen()->frame(); 202 VirtualFrame* frame = cgen()->frame();
203 int difference = 203 int difference = frame->stack_pointer_ - (frame->element_count() - 1);
204 frame->stack_pointer_ - (frame->elements_.length() - 1);
205 if (difference > 0) { 204 if (difference > 0) {
206 frame->stack_pointer_ -= difference; 205 frame->stack_pointer_ -= difference;
207 __ add(Operand(esp), Immediate(difference * kPointerSize)); 206 __ add(Operand(esp), Immediate(difference * kPointerSize));
208 } 207 }
209 } else { 208 } else {
210 ASSERT(direction_ == BIDIRECTIONAL); 209 ASSERT(direction_ == BIDIRECTIONAL);
211 // Fast case: no forward jumps, possible backward ones. Remove 210 // Fast case: no forward jumps, possible backward ones. Remove
212 // constants and copies above the watermark on the fall-through 211 // constants and copies above the watermark on the fall-through
213 // frame and use it as the entry frame. 212 // frame and use it as the entry frame.
214 cgen()->frame()->MakeMergable(mergable_elements); 213 cgen()->frame()->MakeMergable(mergable_elements);
215 entry_frame_ = new VirtualFrame(cgen()->frame()); 214 entry_frame_ = new VirtualFrame(cgen()->frame());
216 } 215 }
217 __ bind(&entry_label_); 216 __ bind(&entry_label_);
218 return; 217 return;
219 } 218 }
220 219
221 if (direction_ == FORWARD_ONLY && 220 if (direction_ == FORWARD_ONLY &&
222 !cgen()->has_valid_frame() && 221 !cgen()->has_valid_frame() &&
223 reaching_frames_.length() == 1) { 222 reaching_frames_.length() == 1) {
224 // Fast case: no fall-through, a single forward jump, and no 223 // Fast case: no fall-through, a single forward jump, and no
225 // possible backward jumps. Pick up the only reaching frame, take 224 // possible backward jumps. Pick up the only reaching frame, take
226 // ownership of it, and use it for the block about to be emitted. 225 // ownership of it, and use it for the block about to be emitted.
227 VirtualFrame* frame = reaching_frames_[0]; 226 VirtualFrame* frame = reaching_frames_[0];
228 RegisterFile reserved = RegisterAllocator::Reserved(); 227 RegisterFile empty;
229 cgen()->SetFrame(frame, &reserved); 228 cgen()->SetFrame(frame, &empty);
230 reaching_frames_[0] = NULL; 229 reaching_frames_[0] = NULL;
231 __ bind(&merge_labels_[0]); 230 __ bind(&merge_labels_[0]);
232 231
233 // The stack pointer can be floating above the top of the 232 // The stack pointer can be floating above the top of the
234 // virtual frame before the bind. Afterward, it should not. 233 // virtual frame before the bind. Afterward, it should not.
235 int difference = 234 int difference = frame->stack_pointer_ - (frame->element_count() - 1);
236 frame->stack_pointer_ - (frame->elements_.length() - 1);
237 if (difference > 0) { 235 if (difference > 0) {
238 frame->stack_pointer_ -= difference; 236 frame->stack_pointer_ -= difference;
239 __ add(Operand(esp), Immediate(difference * kPointerSize)); 237 __ add(Operand(esp), Immediate(difference * kPointerSize));
240 } 238 }
241 239
242 __ bind(&entry_label_); 240 __ bind(&entry_label_);
243 return; 241 return;
244 } 242 }
245 243
246 // If there is a current frame, record it as the fall-through. It 244 // If there is a current frame, record it as the fall-through. It
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 // We could have a valid frame as the fall through to the 282 // We could have a valid frame as the fall through to the
285 // binding site or as the fall through from a previous merge 283 // binding site or as the fall through from a previous merge
286 // code block. Jump around the code we are about to 284 // code block. Jump around the code we are about to
287 // generate. 285 // generate.
288 if (cgen()->has_valid_frame()) { 286 if (cgen()->has_valid_frame()) {
289 cgen()->DeleteFrame(); 287 cgen()->DeleteFrame();
290 __ jmp(&entry_label_); 288 __ jmp(&entry_label_);
291 } 289 }
292 // Pick up the frame for this block. Assume ownership if 290 // Pick up the frame for this block. Assume ownership if
293 // there cannot be backward jumps. 291 // there cannot be backward jumps.
294 RegisterFile reserved = RegisterAllocator::Reserved(); 292 RegisterFile empty;
295 if (direction_ == BIDIRECTIONAL) { 293 if (direction_ == BIDIRECTIONAL) {
296 cgen()->SetFrame(new VirtualFrame(frame), &reserved); 294 cgen()->SetFrame(new VirtualFrame(frame), &empty);
297 } else { 295 } else {
298 cgen()->SetFrame(frame, &reserved); 296 cgen()->SetFrame(frame, &empty);
299 reaching_frames_[i] = NULL; 297 reaching_frames_[i] = NULL;
300 } 298 }
301 __ bind(&merge_labels_[i]); 299 __ bind(&merge_labels_[i]);
302 300
303 // Loop over the remaining (non-null) reaching frames, 301 // Loop over the remaining (non-null) reaching frames,
304 // looking for any that can share merge code with this one. 302 // looking for any that can share merge code with this one.
305 for (int j = 0; j < i; j++) { 303 for (int j = 0; j < i; j++) {
306 VirtualFrame* other = reaching_frames_[j]; 304 VirtualFrame* other = reaching_frames_[j];
307 if (other != NULL && other->Equals(cgen()->frame())) { 305 if (other != NULL && other->Equals(cgen()->frame())) {
308 // Set the reaching frame element to null to avoid 306 // Set the reaching frame element to null to avoid
309 // processing it later, and then bind its entry label. 307 // processing it later, and then bind its entry label.
310 reaching_frames_[j] = NULL; 308 reaching_frames_[j] = NULL;
311 __ bind(&merge_labels_[j]); 309 __ bind(&merge_labels_[j]);
312 } 310 }
313 } 311 }
314 312
315 // Emit the merge code. 313 // Emit the merge code.
316 cgen()->frame()->MergeTo(entry_frame_); 314 cgen()->frame()->MergeTo(entry_frame_);
317 } else if (i == reaching_frames_.length() - 1 && had_fall_through) { 315 } else if (i == reaching_frames_.length() - 1 && had_fall_through) {
318 // If this is the fall through frame, and it didn't need 316 // If this is the fall through frame, and it didn't need
319 // merge code, we need to pick up the frame so we can jump 317 // merge code, we need to pick up the frame so we can jump
320 // around subsequent merge blocks if necessary. 318 // around subsequent merge blocks if necessary.
321 RegisterFile reserved = RegisterAllocator::Reserved(); 319 RegisterFile empty;
322 cgen()->SetFrame(frame, &reserved); 320 cgen()->SetFrame(frame, &empty);
323 reaching_frames_[i] = NULL; 321 reaching_frames_[i] = NULL;
324 } 322 }
325 } 323 }
326 } 324 }
327 325
328 // The code generator may not have a current frame if there was no 326 // The code generator may not have a current frame if there was no
329 // fall through and none of the reaching frames needed merging. 327 // fall through and none of the reaching frames needed merging.
330 // In that case, clone the entry frame as the current frame. 328 // In that case, clone the entry frame as the current frame.
331 if (!cgen()->has_valid_frame()) { 329 if (!cgen()->has_valid_frame()) {
332 RegisterFile reserved_registers = RegisterAllocator::Reserved(); 330 RegisterFile empty;
333 cgen()->SetFrame(new VirtualFrame(entry_frame_), &reserved_registers); 331 cgen()->SetFrame(new VirtualFrame(entry_frame_), &empty);
334 } 332 }
335 333
336 // There may be unprocessed reaching frames that did not need 334 // There may be unprocessed reaching frames that did not need
337 // merge code. They will have unbound merge labels. Bind their 335 // merge code. They will have unbound merge labels. Bind their
338 // merge labels to be the same as the entry label and deallocate 336 // merge labels to be the same as the entry label and deallocate
339 // them. 337 // them.
340 for (int i = 0; i < reaching_frames_.length(); i++) { 338 for (int i = 0; i < reaching_frames_.length(); i++) {
341 if (!merge_labels_[i].is_bound()) { 339 if (!merge_labels_[i].is_bound()) {
342 reaching_frames_[i] = NULL; 340 reaching_frames_[i] = NULL;
343 __ bind(&merge_labels_[i]); 341 __ bind(&merge_labels_[i]);
344 } 342 }
345 } 343 }
346 344
347 // There are non-NULL reaching frames with bound labels for each 345 // There are non-NULL reaching frames with bound labels for each
348 // merge block, but only on backward targets. 346 // merge block, but only on backward targets.
349 } else { 347 } else {
350 // There were no forward jumps. There must be a current frame and 348 // There were no forward jumps. There must be a current frame and
351 // this must be a bidirectional target. 349 // this must be a bidirectional target.
352 ASSERT(reaching_frames_.length() == 1); 350 ASSERT(reaching_frames_.length() == 1);
353 ASSERT(reaching_frames_[0] != NULL); 351 ASSERT(reaching_frames_[0] != NULL);
354 ASSERT(direction_ == BIDIRECTIONAL); 352 ASSERT(direction_ == BIDIRECTIONAL);
355 353
356 // Use a copy of the reaching frame so the original can be saved 354 // Use a copy of the reaching frame so the original can be saved
357 // for possible reuse as a backward merge block. 355 // for possible reuse as a backward merge block.
358 RegisterFile reserved = RegisterAllocator::Reserved(); 356 RegisterFile empty;
359 cgen()->SetFrame(new VirtualFrame(reaching_frames_[0]), &reserved); 357 cgen()->SetFrame(new VirtualFrame(reaching_frames_[0]), &empty);
360 __ bind(&merge_labels_[0]); 358 __ bind(&merge_labels_[0]);
361 cgen()->frame()->MergeTo(entry_frame_); 359 cgen()->frame()->MergeTo(entry_frame_);
362 } 360 }
363 361
364 __ bind(&entry_label_); 362 __ bind(&entry_label_);
365 } 363 }
366 364
367 #undef __ 365 #undef __
368 366
369 367
370 } } // namespace v8::internal 368 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698