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

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

Issue 50012: Change VirtualFrame::AdjustCopies to mark target as invalid. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 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 | « src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 491
492 492
493 void VirtualFrame::PushReceiverSlotAddress() { 493 void VirtualFrame::PushReceiverSlotAddress() {
494 Result temp = cgen_->allocator()->Allocate(); 494 Result temp = cgen_->allocator()->Allocate();
495 ASSERT(temp.is_valid()); 495 ASSERT(temp.is_valid());
496 __ lea(temp.reg(), ParameterAt(-1)); 496 __ lea(temp.reg(), ParameterAt(-1));
497 Push(&temp); 497 Push(&temp);
498 } 498 }
499 499
500 500
501 // Before changing an element which is copied, adjust so that the 501 int VirtualFrame::InvalidateFrameSlotAt(int index) {
502 // first copy becomes the new backing store and all the other copies
503 // are updated. If the original was in memory, the new backing store
504 // is allocated to a register. Return a copy of the new backing store
505 // or an invalid element if the original was not a copy.
506 FrameElement VirtualFrame::AdjustCopies(int index) {
507 FrameElement original = elements_[index]; 502 FrameElement original = elements_[index];
508 ASSERT(original.is_memory() || original.is_register());
509 503
510 // Go looking for a first copy above index. 504 // Is this element the backing store of any copies?
511 int i = index + 1; 505 int new_backing_index = kIllegalIndex;
512 while (i < elements_.length()) { 506 if (original.is_copied()) {
513 FrameElement elt = elements_[i]; 507 // Verify it is copied, and find first copy.
514 if (elt.is_copy() && elt.index() == index) break; 508 for (int i = index + 1; i < elements_.length(); i++) {
515 i++; 509 if (elements_[i].is_copy() && elements_[i].index() == index) {
510 new_backing_index = i;
511 break;
512 }
513 }
516 } 514 }
517 515
518 if (i < elements_.length()) { 516 if (new_backing_index == kIllegalIndex) {
519 // There was a first copy. Make it the new backing element. 517 // No copies found, return kIllegalIndex.
520 Register backing_reg; 518 if (original.is_register()) {
521 if (original.is_memory()) { 519 Unuse(original.reg());
522 Result fresh = cgen_->allocator()->Allocate();
523 ASSERT(fresh.is_valid());
524 backing_reg = fresh.reg();
525 __ mov(backing_reg, Operand(ebp, fp_relative(index)));
526 } else {
527 // The original was in a register.
528 backing_reg = original.reg();
529 } 520 }
530 FrameElement new_backing_element = 521 elements_[index] = FrameElement::InvalidElement();
531 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); 522 return kIllegalIndex;
532 if (elements_[i].is_synced()) {
533 new_backing_element.set_sync();
534 }
535 Use(backing_reg);
536 elements_[i] = new_backing_element;
537
538 // Update the other copies.
539 FrameElement copy = CopyElementAt(i);
540 for (int j = i; j < elements_.length(); j++) {
541 FrameElement elt = elements_[j];
542 if (elt.is_copy() && elt.index() == index) {
543 if (elt.is_synced()) {
544 copy.set_sync();
545 } else {
546 copy.clear_sync();
547 }
548 elements_[j] = copy;
549 }
550 }
551
552 copy.clear_sync();
553 return copy;
554 } 523 }
555 524
556 elements_[index].clear_copied(); 525 // This is the backing store of copies.
557 return FrameElement::InvalidElement(); 526 Register backing_reg;
527 if (original.is_memory()) {
528 Result fresh = cgen_->allocator()->Allocate();
529 ASSERT(fresh.is_valid());
530 Use(fresh.reg());
531 backing_reg = fresh.reg();
532 __ mov(backing_reg, Operand(ebp, fp_relative(index)));
533 } else {
534 // The original was in a register.
535 backing_reg = original.reg();
536 }
537 if (elements_[new_backing_index].is_synced()) {
538 elements_[new_backing_index] =
539 FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED);
540 } else {
541 elements_[new_backing_index] =
542 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED);
543 }
544 // Update the other copies.
545 for (int i = new_backing_index + 1; i < elements_.length(); i++) {
546 if (elements_[i].is_copy() && elements_[i].index() == index) {
547 elements_[i].set_index(new_backing_index);
548 elements_[new_backing_index].set_copied();
549 }
550 }
551 return new_backing_index;
558 } 552 }
559 553
560 554
561 void VirtualFrame::TakeFrameSlotAt(int index) { 555 void VirtualFrame::TakeFrameSlotAt(int index) {
562 ASSERT(index >= 0); 556 ASSERT(index >= 0);
563 ASSERT(index <= elements_.length()); 557 ASSERT(index <= elements_.length());
564 FrameElement original = elements_[index]; 558 FrameElement original = elements_[index];
559 int new_backing_store_index = InvalidateFrameSlotAt(index);
560 if (new_backing_store_index != kIllegalIndex) {
561 elements_.Add(CopyElementAt(new_backing_store_index));
562 return;
563 }
565 564
566 switch (original.type()) { 565 switch (original.type()) {
567 case FrameElement::INVALID:
568 UNREACHABLE();
569 break;
570
571 case FrameElement::MEMORY: { 566 case FrameElement::MEMORY: {
572 // Allocate the element to a register. If it is not copied, 567 // Emit code to load the original element's data into a register.
573 // push that register on top of the frame. If it is copied, 568 // Push that register as a FrameElement on top of the frame.
574 // make the first copy the backing store and push a fresh copy 569 Result fresh = cgen_->allocator()->Allocate();
575 // on top of the frame. 570 ASSERT(fresh.is_valid());
576 FrameElement copy = original.is_copied() 571 FrameElement new_element =
577 ? AdjustCopies(index) 572 FrameElement::RegisterElement(fresh.reg(),
578 : FrameElement::InvalidElement(); 573 FrameElement::NOT_SYNCED);
579 if (copy.is_valid()) { 574 Use(fresh.reg());
580 // The original element was a copy. Push the copy of the new 575 elements_.Add(new_element);
581 // backing store. 576 __ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
582 elements_.Add(copy);
583 } else {
584 // The element was not a copy. Move it to a register and push
585 // that.
586 Result fresh = cgen_->allocator()->Allocate();
587 ASSERT(fresh.is_valid());
588 FrameElement new_element =
589 FrameElement::RegisterElement(fresh.reg(),
590 FrameElement::NOT_SYNCED);
591 Use(fresh.reg());
592 elements_.Add(new_element);
593 __ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
594 }
595 break; 577 break;
596 } 578 }
597 579 case FrameElement::REGISTER:
598 case FrameElement::REGISTER: { 580 Use(original.reg());
599 // If the element is not copied, push it on top of the frame. 581 // Fall through.
600 // If it is copied, make the first copy be the new backing store
601 // and push a fresh copy on top of the frame.
602 FrameElement copy = original.is_copied()
603 ? AdjustCopies(index)
604 : FrameElement::InvalidElement();
605 if (copy.is_valid()) {
606 // The original element was a copy. Push the copy of the new
607 // backing store.
608 elements_.Add(copy);
609 // This is the only case where we have to unuse the original
610 // register. The original is still counted and so is the new
611 // backing store of the copies.
612 Unuse(original.reg());
613 } else {
614 // The element was not a copy. Push it.
615 original.clear_sync();
616 elements_.Add(original);
617 }
618 break;
619 }
620
621 case FrameElement::CONSTANT: 582 case FrameElement::CONSTANT:
622 original.clear_sync();
623 elements_.Add(original);
624 break;
625
626 case FrameElement::COPY: 583 case FrameElement::COPY:
627 original.clear_sync(); 584 original.clear_sync();
628 elements_.Add(original); 585 elements_.Add(original);
629 break; 586 break;
587 case FrameElement::INVALID:
588 UNREACHABLE();
589 break;
630 } 590 }
631 elements_[index] = FrameElement::InvalidElement();
632 } 591 }
633 592
634 593
635 void VirtualFrame::StoreToFrameSlotAt(int index) { 594 void VirtualFrame::StoreToFrameSlotAt(int index) {
636 // Store the value on top of the frame to the virtual frame slot at 595 // Store the value on top of the frame to the virtual frame slot at
637 // a given index. The value on top of the frame is left in place. 596 // a given index. The value on top of the frame is left in place.
638 // This is a duplicating operation, so it can create copies. 597 // This is a duplicating operation, so it can create copies.
639 ASSERT(index >= 0); 598 ASSERT(index >= 0);
640 ASSERT(index < elements_.length()); 599 ASSERT(index < elements_.length());
641 600
642 FrameElement original = elements_[index];
643 // If the stored-to slot may be copied, adjust to preserve the
644 // copy-on-write semantics of copied elements.
645 if (original.is_copied() &&
646 (original.is_register() || original.is_memory())) {
647 FrameElement ignored = AdjustCopies(index);
648 }
649
650 // If the stored-to slot is a register reference, deallocate it.
651 if (original.is_register()) {
652 Unuse(original.reg());
653 }
654
655 int top_index = elements_.length() - 1; 601 int top_index = elements_.length() - 1;
656 FrameElement top = elements_[top_index]; 602 FrameElement top = elements_[top_index];
603 FrameElement original = elements_[index];
604 if (top.is_copy() && top.index() == index) return;
657 ASSERT(top.is_valid()); 605 ASSERT(top.is_valid());
658 606
607 InvalidateFrameSlotAt(index);
608
659 if (top.is_copy()) { 609 if (top.is_copy()) {
660 // There are two cases based on the relative positions of the 610 // There are two cases based on the relative positions of the
661 // stored-to slot and the backing slot of the top element. 611 // stored-to slot and the backing slot of the top element.
662 int backing_index = top.index(); 612 int backing_index = top.index();
663 ASSERT(backing_index != index); 613 ASSERT(backing_index != index);
664 if (backing_index < index) { 614 if (backing_index < index) {
665 // 1. The top element is a copy of a slot below the stored-to 615 // 1. The top element is a copy of a slot below the stored-to
666 // slot. The stored-to slot becomes an unsynced copy of that 616 // slot. The stored-to slot becomes an unsynced copy of that
667 // same backing slot. 617 // same backing slot.
668 elements_[index] = CopyElementAt(backing_index); 618 elements_[index] = CopyElementAt(backing_index);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 // element. 650 // element.
701 FrameElement new_element = CopyElementAt(index); 651 FrameElement new_element = CopyElementAt(index);
702 elements_[backing_index] = new_element; 652 elements_[backing_index] = new_element;
703 if (backing_element.is_synced()) { 653 if (backing_element.is_synced()) {
704 elements_[backing_index].set_sync(); 654 elements_[backing_index].set_sync();
705 } 655 }
706 656
707 // All the copies of the old backing element (including the top 657 // All the copies of the old backing element (including the top
708 // element) become copies of the new backing element. 658 // element) become copies of the new backing element.
709 for (int i = backing_index + 1; i < elements_.length(); i++) { 659 for (int i = backing_index + 1; i < elements_.length(); i++) {
710 FrameElement current = elements_[i]; 660 if (elements_[i].is_copy() && elements_[i].index() == backing_index) {
711 if (current.is_copy() && current.index() == backing_index) { 661 elements_[i].set_index(index);
712 elements_[i] = new_element;
713 if (current.is_synced()) {
714 elements_[i].set_sync();
715 }
716 } 662 }
717 } 663 }
718 } 664 }
719
720 return; 665 return;
721 } 666 }
722 667
723 // Move the top element to the stored-to slot and replace it (the 668 // Move the top element to the stored-to slot and replace it (the
724 // top element) with a copy. 669 // top element) with a copy.
725 elements_[index] = top; 670 elements_[index] = top;
726 if (top.is_memory()) { 671 if (top.is_memory()) {
727 // TODO(209): consider allocating the stored-to slot to the temp 672 // TODO(209): consider allocating the stored-to slot to the temp
728 // register. Alternatively, allow copies to appear in any order 673 // register. Alternatively, allow copies to appear in any order
729 // in the frame and lazily move the value down to the slot. 674 // in the frame and lazily move the value down to the slot.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 ASSERT(stack_pointer_ == elements_.length() - 1); 940 ASSERT(stack_pointer_ == elements_.length() - 1);
996 elements_.Add(FrameElement::MemoryElement()); 941 elements_.Add(FrameElement::MemoryElement());
997 stack_pointer_++; 942 stack_pointer_++;
998 __ push(immediate); 943 __ push(immediate);
999 } 944 }
1000 945
1001 946
1002 #undef __ 947 #undef __
1003 948
1004 } } // namespace v8::internal 949 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698