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

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

Issue 16412: Experimental: push the new code generator infrastructure into the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years 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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 SyncElementAt(i); 265 SyncElementAt(i);
266 } 266 }
267 } 267 }
268 268
269 // Forget the frame elements that will be popped by the call. 269 // Forget the frame elements that will be popped by the call.
270 Forget(frame_arg_count); 270 Forget(frame_arg_count);
271 } 271 }
272 272
273 273
274 bool VirtualFrame::RequiresMergeCode() { 274 bool VirtualFrame::RequiresMergeCode() {
275 // A frame requires merge code to be generated in the event that 275 // A frame requires code to be generated to make the frame mergable if
276 // there are duplicated non-synched registers or else elements not 276 // there are duplicated non-synched registers or else valid elements not
277 // in a (memory or register) location in the frame. We look for 277 // in a (memory or register) location in the frame. We look for valid
278 // non-synced non-location elements and count occurrences of 278 // non-synced non-location elements and count occurrences of non-synced
279 // non-synced registers. 279 // registers.
280 RegisterFile non_synced_regs; 280 RegisterFile non_synced_regs;
281 for (int i = 0; i < elements_.length(); i++) { 281 for (int i = 0; i < elements_.length(); i++) {
282 FrameElement element = elements_[i]; 282 FrameElement element = elements_[i];
283 if (!element.is_synced()) { 283 if (element.is_valid() && !element.is_synced()) {
284 if (element.is_register()) { 284 if (element.is_register()) {
285 non_synced_regs.Use(elements_[i].reg()); 285 non_synced_regs.Use(elements_[i].reg());
286 } else if (!element.is_memory()) { 286 } else if (!element.is_memory()) {
287 // Not memory or register and not synced. 287 // Not memory or register and not synced.
288 return true; 288 return true;
289 } 289 }
290 } 290 }
291 } 291 }
292 292
293 for (int i = 0; i < RegisterFile::kNumRegisters; i++) { 293 for (int i = 0; i < RegisterFile::kNumRegisters; i++) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } else { 354 } else {
355 // The element is in memory or a singly-frame-referenced register. 355 // The element is in memory or a singly-frame-referenced register.
356 new_elements[i] = element; 356 new_elements[i] = element;
357 } 357 }
358 } 358 }
359 359
360 // Perform the moves. 360 // Perform the moves.
361 for (int i = 0; i < elements_.length(); i++) { 361 for (int i = 0; i < elements_.length(); i++) {
362 FrameElement source = elements_[i]; 362 FrameElement source = elements_[i];
363 FrameElement target = new_elements[i]; 363 FrameElement target = new_elements[i];
364 ASSERT(target.is_register() || target.is_memory()); 364 ASSERT(!target.is_valid() || target.is_register() || target.is_memory());
365 if (target.is_register()) { 365 if (target.is_register()) {
366 if (source.is_constant()) { 366 if (source.is_constant()) {
367 __ Set(target.reg(), Immediate(source.handle())); 367 __ Set(target.reg(), Immediate(source.handle()));
368 } else if (source.is_register() && !source.reg().is(target.reg())) { 368 } else if (source.is_register() && !source.reg().is(target.reg())) {
369 __ mov(target.reg(), source.reg()); 369 __ mov(target.reg(), source.reg());
370 } 370 }
371 elements_[i] = target; 371 elements_[i] = target;
372 } else { 372 } else if (target.is_memory()) {
373 // The target is memory.
374 if (!source.is_memory()) { 373 if (!source.is_memory()) {
375 // Spilling a source register would decrement its reference count, 374 // Spilling a source register would decrement its reference count,
376 // but we have already done that when computing new target elements, 375 // but we have already done that when computing new target elements,
377 // so we use a raw spill. 376 // so we use a raw spill.
378 RawSpillElementAt(i); 377 RawSpillElementAt(i);
379 } 378 }
380 } 379 }
380 // Invalid elements do not need to be moved.
381 } 381 }
382 382
383 delete[] new_elements; 383 delete[] new_elements;
384 ASSERT(cgen_->HasValidEntryRegisters()); 384 ASSERT(cgen_->HasValidEntryRegisters());
385 cgen_->SetFrame(original_frame); 385 cgen_->SetFrame(original_frame);
386 ASSERT(cgen_->HasValidEntryRegisters()); 386 ASSERT(cgen_->HasValidEntryRegisters());
387 } 387 }
388 388
389 389
390 void VirtualFrame::MergeTo(VirtualFrame* expected) { 390 void VirtualFrame::MergeTo(VirtualFrame* expected) {
(...skipping 12 matching lines...) Expand all
403 // Mergable frames have all elements in locations, either memory or 403 // Mergable frames have all elements in locations, either memory or
404 // register. We thus have a series of to-memory and to-register moves. 404 // register. We thus have a series of to-memory and to-register moves.
405 // First perform all to-memory moves, register-to-memory moves because 405 // First perform all to-memory moves, register-to-memory moves because
406 // they can free registers and constant-to-memory moves because they do 406 // they can free registers and constant-to-memory moves because they do
407 // not use registers. 407 // not use registers.
408 MergeMoveRegistersToMemory(expected); 408 MergeMoveRegistersToMemory(expected);
409 MergeMoveRegistersToRegisters(expected); 409 MergeMoveRegistersToRegisters(expected);
410 MergeMoveMemoryToRegisters(expected); 410 MergeMoveMemoryToRegisters(expected);
411 411
412 // At this point, the frames should be identical. 412 // At this point, the frames should be identical.
413 // TODO(): Consider an "equals" method for frames.
413 ASSERT(stack_pointer_ == expected->stack_pointer_); 414 ASSERT(stack_pointer_ == expected->stack_pointer_);
414 #ifdef DEBUG 415 #ifdef DEBUG
415 for (int i = 0; i < elements_.length(); i++) { 416 for (int i = 0; i < elements_.length(); i++) {
416 FrameElement expect = expected->elements_[i]; 417 FrameElement expect = expected->elements_[i];
417 if (expect.is_memory()) { 418 if (!expect.is_valid()) {
419 ASSERT(!elements_[i].is_valid());
420 } else if (expect.is_memory()) {
418 ASSERT(elements_[i].is_memory()); 421 ASSERT(elements_[i].is_memory());
419 ASSERT(elements_[i].is_synced() && expect.is_synced()); 422 ASSERT(elements_[i].is_synced() && expect.is_synced());
420 } else if (expect.is_register()) { 423 } else if (expect.is_register()) {
421 ASSERT(elements_[i].is_register()); 424 ASSERT(elements_[i].is_register());
422 ASSERT(elements_[i].reg().is(expect.reg())); 425 ASSERT(elements_[i].reg().is(expect.reg()));
423 ASSERT(elements_[i].is_synced() == expect.is_synced()); 426 ASSERT(elements_[i].is_synced() == expect.is_synced());
424 } else { 427 } else {
425 ASSERT(expect.is_constant()); 428 ASSERT(expect.is_constant());
426 ASSERT(elements_[i].is_constant()); 429 ASSERT(elements_[i].is_constant());
427 ASSERT(elements_[i].handle().location() == 430 ASSERT(elements_[i].handle().location() ==
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 __ Set(temp.reg(), Immediate(undefined)); 645 __ Set(temp.reg(), Immediate(undefined));
643 for (int i = 0; i < count; i++) { 646 for (int i = 0; i < count; i++) {
644 elements_.Add(initial_value); 647 elements_.Add(initial_value);
645 stack_pointer_++; 648 stack_pointer_++;
646 __ push(temp.reg()); 649 __ push(temp.reg());
647 } 650 }
648 } 651 }
649 } 652 }
650 653
651 654
655 void VirtualFrame::SetElementAt(int index, Result* value) {
656 int frame_index = elements_.length() - index - 1;
657 ASSERT(frame_index >= 0);
658 ASSERT(frame_index < elements_.length());
659 ASSERT(value->is_valid());
660
661 // TODO(): if the element is backed by the same register or the same
662 // constant, consider preserving the sync bit.
663 if (elements_[frame_index].is_register()) {
664 Unuse(elements_[frame_index].reg());
665 }
666
667 if (value->is_register()) {
668 Use(value->reg());
669 elements_[frame_index] =
670 FrameElement::RegisterElement(value->reg(),
671 FrameElement::NOT_SYNCED);
672 } else {
673 ASSERT(value->is_constant());
674 elements_[frame_index] =
675 FrameElement::ConstantElement(value->handle(),
676 FrameElement::NOT_SYNCED);
677 }
678
679 value->Unuse();
680 }
681
682
652 void VirtualFrame::LoadFrameSlotAt(int index) { 683 void VirtualFrame::LoadFrameSlotAt(int index) {
653 ASSERT(index >= 0); 684 ASSERT(index >= 0);
654 ASSERT(index < elements_.length()); 685 ASSERT(index < elements_.length());
655 686
656 FrameElement element = elements_[index]; 687 FrameElement element = elements_[index];
657 688
658 if (element.is_memory()) { 689 if (element.is_memory()) {
659 ASSERT(index <= stack_pointer_); 690 ASSERT(index <= stack_pointer_);
660 // Eagerly load memory elements into a register. The element at 691 // Eagerly load memory elements into a register. The element at
661 // the index and the new top of the frame are backed by the same 692 // the index and the new top of the frame are backed by the same
(...skipping 17 matching lines...) Expand all
679 ASSERT(element.is_register() || element.is_constant()); 710 ASSERT(element.is_register() || element.is_constant());
680 if (element.is_register()) { 711 if (element.is_register()) {
681 Use(element.reg()); 712 Use(element.reg());
682 } 713 }
683 element.clear_sync(); 714 element.clear_sync();
684 elements_.Add(element); 715 elements_.Add(element);
685 } 716 }
686 } 717 }
687 718
688 719
720 void VirtualFrame::TakeFrameSlotAt(int index) {
721 LoadFrameSlotAt(index);
722
723 if (elements_[index].is_register()) {
724 Unuse(elements_[index].reg());
725 }
726 elements_[index] = FrameElement::InvalidElement();
727 }
728
729
689 void VirtualFrame::StoreToFrameSlotAt(int index) { 730 void VirtualFrame::StoreToFrameSlotAt(int index) {
690 // Store the value on top of the frame to the virtual frame slot at a 731 // Store the value on top of the frame to the virtual frame slot at a
691 // given index. The value on top of the frame is left in place. 732 // given index. The value on top of the frame is left in place.
692 ASSERT(index >= 0); 733 ASSERT(index >= 0);
693 ASSERT(index < elements_.length()); 734 ASSERT(index < elements_.length());
694 FrameElement top = elements_[elements_.length() - 1]; 735 FrameElement top = elements_[elements_.length() - 1];
695 736
696 if (elements_[index].is_register()) { 737 if (elements_[index].is_register()) {
697 Unuse(elements_[index].reg()); 738 Unuse(elements_[index].reg());
698 } 739 }
699 // The virtual frame slot will be of the same type and have the same value 740 // The virtual frame slot will be of the same type and have the same value
700 // as the frame top. 741 // as the frame top.
701 elements_[index] = top; 742 elements_[index] = top;
702 743
703 if (top.is_memory()) { 744 if (top.is_memory()) {
745 // TODO(): consider allocating the slot to a register.
746 //
704 // Emit code to store memory values into the required frame slot. 747 // Emit code to store memory values into the required frame slot.
705 Result temp = cgen_->allocator()->Allocate(); 748 Result temp = cgen_->allocator()->Allocate();
706 ASSERT(temp.is_valid()); 749 ASSERT(temp.is_valid());
707 __ mov(temp.reg(), Top()); 750 __ mov(temp.reg(), Top());
708 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); 751 __ mov(Operand(ebp, fp_relative(index)), temp.reg());
709 } else { 752 } else {
710 // We have not actually written the value to memory. 753 // We have not actually written the value to memory.
711 elements_[index].clear_sync(); 754 elements_[index].clear_sync();
712 755
713 if (top.is_register()) { 756 if (top.is_register()) {
(...skipping 18 matching lines...) Expand all
732 775
733 776
734 void VirtualFrame::CallStub(CodeStub* stub, int frame_arg_count) { 777 void VirtualFrame::CallStub(CodeStub* stub, int frame_arg_count) {
735 ASSERT(cgen_->HasValidEntryRegisters()); 778 ASSERT(cgen_->HasValidEntryRegisters());
736 PrepareForCall(frame_arg_count); 779 PrepareForCall(frame_arg_count);
737 __ CallStub(stub); 780 __ CallStub(stub);
738 } 781 }
739 782
740 783
741 Result VirtualFrame::CallStub(CodeStub* stub, 784 Result VirtualFrame::CallStub(CodeStub* stub,
785 Result* arg,
786 int frame_arg_count) {
787 arg->Unuse();
788 CallStub(stub, frame_arg_count);
789 Result result = cgen_->allocator()->Allocate(eax);
790 ASSERT(result.is_valid());
791 return result;
792 }
793
794
795 Result VirtualFrame::CallStub(CodeStub* stub,
742 Result* arg0, 796 Result* arg0,
743 Result* arg1, 797 Result* arg1,
744 int frame_arg_count) { 798 int frame_arg_count) {
745 arg0->Unuse(); 799 arg0->Unuse();
746 arg1->Unuse(); 800 arg1->Unuse();
747 CallStub(stub, frame_arg_count); 801 CallStub(stub, frame_arg_count);
748 Result result = cgen_->allocator()->Allocate(eax); 802 Result result = cgen_->allocator()->Allocate(eax);
749 ASSERT(result.is_valid()); 803 ASSERT(result.is_valid());
750 return result; 804 return result;
751 } 805 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 return false; 961 return false;
908 } 962 }
909 } 963 }
910 return true; 964 return true;
911 } 965 }
912 #endif 966 #endif
913 967
914 #undef __ 968 #undef __
915 969
916 } } // namespace v8::internal 970 } } // 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