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

Side by Side Diff: src/ia32/virtual-frame-ia32.cc

Issue 99052: Change MergeTo code for virtual frames to use register indices. (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
« no previous file with comments | « no previous file | src/virtual-frame.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (esi_caches != kIllegalIndex) { 303 if (esi_caches != kIllegalIndex) {
304 __ mov(esi, Operand(ebp, fp_relative(context_index()))); 304 __ mov(esi, Operand(ebp, fp_relative(context_index())));
305 } 305 }
306 } 306 }
307 307
308 308
309 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) { 309 void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) {
310 // We have already done X-to-memory moves. 310 // We have already done X-to-memory moves.
311 ASSERT(stack_pointer_ >= expected->stack_pointer_); 311 ASSERT(stack_pointer_ >= expected->stack_pointer_);
312 312
313 // Perform register-to-register moves. 313 for (int i = 0; i < kNumRegisters; i++) {
314 int start = 0; 314 // Move the right value into register i if it is currently in a register.
315 int end = elements_.length() - 1; 315 int index = expected->register_locations_[i];
316 bool any_moves_blocked; // Did we fail to make some moves this iteration? 316 int use_index = register_locations_[i];
317 bool should_break_cycles = false; 317 // Fast check if register is unused in target or already correct
318 bool any_moves_made; // Did we make any progress this iteration? 318 if (index != kIllegalIndex
319 do { 319 && index != use_index
320 any_moves_blocked = false; 320 && elements_[index].is_register()) {
321 any_moves_made = false; 321 Register source = elements_[index].reg();
322 int first_move_blocked = kIllegalIndex; 322 Register target = { i };
323 int last_move_blocked = kIllegalIndex; 323 if (use_index == kIllegalIndex) { // Target is currently unused.
324 for (int i = start; i <= end; i++) { 324 // Copy contents of source from source to target.
325 FrameElement source = elements_[i]; 325 // Set frame element register to target.
326 FrameElement target = expected->elements_[i]; 326 elements_[index].set_reg(target);
327 if (source.is_register() && target.is_register()) { 327 Use(target, index);
328 if (target.reg().is(source.reg())) { 328 Unuse(source);
329 if (target.is_synced() && !source.is_synced()) { 329 __ mov(target, source);
330 __ mov(Operand(ebp, fp_relative(i)), source.reg()); 330 } else {
331 } 331 // Exchange contents of registers source and target.
332 elements_[i] = target; 332 elements_[use_index].set_reg(source);
333 } else { 333 elements_[index].set_reg(target);
334 // We need to move source to target. 334 register_locations_[target.code()] = index;
335 if (is_used(target.reg())) { 335 register_locations_[source.code()] = use_index;
336 // The move is blocked because the target contains valid data. 336 __ xchg(source, target);
337 // If we are stuck with only cycles remaining, then we spill source.
338 // Otherwise, we just need more iterations.
339 if (should_break_cycles) {
340 SpillElementAt(i);
341 should_break_cycles = false;
342 } else { // Record a blocked move.
343 if (!any_moves_blocked) {
344 first_move_blocked = i;
345 }
346 last_move_blocked = i;
347 any_moves_blocked = true;
348 }
349 } else {
350 // The move is not blocked. This frame element can be moved from
351 // its source register to its target register.
352 if (target.is_synced() && !source.is_synced()) {
353 SyncElementAt(i);
354 }
355 Use(target.reg(), i);
356 Unuse(source.reg());
357 elements_[i] = target;
358 __ mov(target.reg(), source.reg());
359 any_moves_made = true;
360 }
361 }
362 } 337 }
363 } 338 }
364 // Update control flags for next iteration. 339 }
365 should_break_cycles = (any_moves_blocked && !any_moves_made);
366 if (any_moves_blocked) {
367 start = first_move_blocked;
368 end = last_move_blocked;
369 }
370 } while (any_moves_blocked);
371 } 340 }
372 341
373 342
374 void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame *expected) { 343 void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame *expected) {
375 // Move memory, constants, and copies to registers. This is the 344 // Move memory, constants, and copies to registers. This is the
376 // final step and is done from the bottom up so that the backing 345 // final step and is done from the bottom up so that the backing
377 // elements of copies are in their correct locations when we 346 // elements of copies are in their correct locations when we
378 // encounter the copies. 347 // encounter the copies.
379 for (int i = 0; i < elements_.length(); i++) { 348 for (int i = 0; i < kNumRegisters; i++) {
380 FrameElement source = elements_[i]; 349 int index = expected->register_locations_[i];
381 FrameElement target = expected->elements_[i]; 350 if (index != kIllegalIndex) {
382 if (target.is_register() && !source.is_register()) { 351 FrameElement source = elements_[index];
352 FrameElement target = expected->elements_[index];
383 switch (source.type()) { 353 switch (source.type()) {
384 case FrameElement::INVALID: // Fall through. 354 case FrameElement::INVALID: // Fall through.
385 case FrameElement::REGISTER:
386 UNREACHABLE(); 355 UNREACHABLE();
387 break; 356 break;
388 357 case FrameElement::REGISTER:
358 ASSERT(source.reg().is(target.reg()));
359 continue; // Go to next iteration. Skips Use(target.reg()) below.
360 break;
389 case FrameElement::MEMORY: 361 case FrameElement::MEMORY:
390 ASSERT(i <= stack_pointer_); 362 ASSERT(index <= stack_pointer_);
391 __ mov(target.reg(), Operand(ebp, fp_relative(i))); 363 __ mov(target.reg(), Operand(ebp, fp_relative(index)));
392 break; 364 break;
393 365
394 case FrameElement::CONSTANT: 366 case FrameElement::CONSTANT:
395 if (cgen_->IsUnsafeSmi(source.handle())) { 367 if (cgen_->IsUnsafeSmi(source.handle())) {
396 cgen_->LoadUnsafeSmi(target.reg(), source.handle()); 368 cgen_->LoadUnsafeSmi(target.reg(), source.handle());
397 } else { 369 } else {
398 __ Set(target.reg(), Immediate(source.handle())); 370 __ Set(target.reg(), Immediate(source.handle()));
399 } 371 }
400 break; 372 break;
401 373
402 case FrameElement::COPY: { 374 case FrameElement::COPY: {
403 FrameElement backing = elements_[source.index()]; 375 int backing_index = source.index();
376 FrameElement backing = elements_[backing_index];
404 ASSERT(backing.is_memory() || backing.is_register()); 377 ASSERT(backing.is_memory() || backing.is_register());
405 if (backing.is_memory()) { 378 if (backing.is_memory()) {
406 ASSERT(source.index() <= stack_pointer_); 379 ASSERT(backing_index <= stack_pointer_);
407 __ mov(target.reg(), Operand(ebp, fp_relative(source.index()))); 380 // Code optimization if backing store should also move
381 // to a register: move backing store to its register first.
382 if (expected->elements_[backing_index].is_register()) {
383 FrameElement new_backing = expected->elements_[backing_index];
384 Register new_backing_reg = new_backing.reg();
385 ASSERT(!is_used(new_backing_reg));
386 elements_[backing_index] = new_backing;
387 Use(new_backing_reg, backing_index);
388 __ mov(new_backing_reg,
389 Operand(ebp, fp_relative(backing_index)));
390 __ mov(target.reg(), new_backing_reg);
391 } else {
392 __ mov(target.reg(), Operand(ebp, fp_relative(backing_index)));
393 }
408 } else { 394 } else {
409 __ mov(target.reg(), backing.reg()); 395 __ mov(target.reg(), backing.reg());
410 } 396 }
411 } 397 }
412 } 398 }
413 // Ensure the proper sync state. If the source was memory no 399 // Ensure the proper sync state. If the source was memory no
414 // code needs to be emitted. 400 // code needs to be emitted.
415 if (target.is_synced() && !source.is_memory()) { 401 if (target.is_synced() && !source.is_synced()) {
416 SyncElementAt(i); 402 __ mov(Operand(ebp, fp_relative(index)), target.reg());
417 } 403 }
418 Use(target.reg(), i); 404 Use(target.reg(), index);
419 elements_[i] = target; 405 elements_[index] = target;
420 } 406 }
421 } 407 }
422 } 408 }
423 409
424 410
425 void VirtualFrame::Enter() { 411 void VirtualFrame::Enter() {
426 // Registers live on entry: esp, ebp, esi, edi. 412 // Registers live on entry: esp, ebp, esi, edi.
427 Comment cmnt(masm_, "[ Enter JS frame"); 413 Comment cmnt(masm_, "[ Enter JS frame");
428 414
429 #ifdef DEBUG 415 #ifdef DEBUG
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 ASSERT(stack_pointer_ == elements_.length() - 1); 1039 ASSERT(stack_pointer_ == elements_.length() - 1);
1054 elements_.Add(FrameElement::MemoryElement()); 1040 elements_.Add(FrameElement::MemoryElement());
1055 stack_pointer_++; 1041 stack_pointer_++;
1056 __ push(immediate); 1042 __ push(immediate);
1057 } 1043 }
1058 1044
1059 1045
1060 #undef __ 1046 #undef __
1061 1047
1062 } } // namespace v8::internal 1048 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/virtual-frame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698