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

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

Issue 13807: Experimental: introduce factory functions for the FrameElement type.... (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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 // On entry to a function, the virtual frame already contains the receiver, 90 // On entry to a function, the virtual frame already contains the receiver,
91 // the parameters, and a return address. All frame elements are in memory. 91 // the parameters, and a return address. All frame elements are in memory.
92 VirtualFrame::VirtualFrame(CodeGenerator* cgen) 92 VirtualFrame::VirtualFrame(CodeGenerator* cgen)
93 : cgen_(cgen), 93 : cgen_(cgen),
94 masm_(cgen->masm()), 94 masm_(cgen->masm()),
95 elements_(0), 95 elements_(0),
96 parameter_count_(cgen->scope()->num_parameters()), 96 parameter_count_(cgen->scope()->num_parameters()),
97 local_count_(0), 97 local_count_(0),
98 stack_pointer_(parameter_count_ + 1), // 0-based index of TOS. 98 stack_pointer_(parameter_count_ + 1), // 0-based index of TOS.
99 frame_pointer_(kIllegalIndex) { 99 frame_pointer_(kIllegalIndex) {
100 FrameElement memory_element;
101 for (int i = 0; i < parameter_count_ + 2; i++) { 100 for (int i = 0; i < parameter_count_ + 2; i++) {
102 elements_.Add(memory_element); 101 elements_.Add(FrameElement::MemoryElement());
103 } 102 }
104 } 103 }
105 104
106 105
107 // When cloned, a frame is a deep copy of the original. 106 // When cloned, a frame is a deep copy of the original.
108 VirtualFrame::VirtualFrame(VirtualFrame* original) 107 VirtualFrame::VirtualFrame(VirtualFrame* original)
109 : cgen_(original->cgen_), 108 : cgen_(original->cgen_),
110 masm_(original->masm_), 109 masm_(original->masm_),
111 elements_(original->elements_.length()), 110 elements_(original->elements_.length()),
112 parameter_count_(original->parameter_count_), 111 parameter_count_(original->parameter_count_),
(...skipping 10 matching lines...) Expand all
123 122
124 // Modify the state of the virtual frame to match the actual frame by adding 123 // Modify the state of the virtual frame to match the actual frame by adding
125 // extra in-memory elements to the top of the virtual frame. The extra 124 // extra in-memory elements to the top of the virtual frame. The extra
126 // elements will be externally materialized on the actual frame (eg, by 125 // elements will be externally materialized on the actual frame (eg, by
127 // pushing an exception handler). No code is emitted. 126 // pushing an exception handler). No code is emitted.
128 void VirtualFrame::Adjust(int count) { 127 void VirtualFrame::Adjust(int count) {
129 ASSERT(count >= 0); 128 ASSERT(count >= 0);
130 ASSERT(stack_pointer_ == elements_.length() - 1); 129 ASSERT(stack_pointer_ == elements_.length() - 1);
131 130
132 for (int i = 0; i < count; i++) { 131 for (int i = 0; i < count; i++) {
133 elements_.Add(FrameElement()); 132 elements_.Add(FrameElement::MemoryElement());
134 } 133 }
135 stack_pointer_ += count; 134 stack_pointer_ += count;
136 } 135 }
137 136
138 137
139 // Modify the state of the virtual frame to match the actual frame by 138 // Modify the state of the virtual frame to match the actual frame by
140 // removing elements from the top of the virtual frame. The elements will 139 // removing elements from the top of the virtual frame. The elements will
141 // be externally popped from the actual frame (eg, by a runtime call). No 140 // be externally popped from the actual frame (eg, by a runtime call). No
142 // code is emitted. 141 // code is emitted.
143 void VirtualFrame::Forget(int count) { 142 void VirtualFrame::Forget(int count) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 244
246 245
247 // Spill an element, making its type be MEMORY. If it is a register the 246 // Spill an element, making its type be MEMORY. If it is a register the
248 // reference count is not decremented, so it must be done externally. 247 // reference count is not decremented, so it must be done externally.
249 void VirtualFrame::RawSpillElementAt(int index) { 248 void VirtualFrame::RawSpillElementAt(int index) {
250 if (index > stack_pointer_ + 1) { 249 if (index > stack_pointer_ + 1) {
251 SyncRange(stack_pointer_ + 1, index); 250 SyncRange(stack_pointer_ + 1, index);
252 } 251 }
253 SyncElementAt(index); 252 SyncElementAt(index);
254 // The element is now in memory. 253 // The element is now in memory.
255 FrameElement memory_element; 254 elements_[index] = FrameElement::MemoryElement();
256 elements_[index] = memory_element;
257 } 255 }
258 256
259 257
260 // Make the type of the element at a given index be MEMORY. We can only 258 // Make the type of the element at a given index be MEMORY. We can only
261 // allocate space in the actual frame for the virtual element immediately 259 // allocate space in the actual frame for the virtual element immediately
262 // above the stack pointer. 260 // above the stack pointer.
263 void VirtualFrame::SpillElementAt(int index) { 261 void VirtualFrame::SpillElementAt(int index) {
264 if (elements_[index].is_register()) { 262 if (elements_[index].is_register()) {
265 Unuse(elements_[index].reg()); 263 Unuse(elements_[index].reg());
266 } 264 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 363
366 void VirtualFrame::MakeMergable() { 364 void VirtualFrame::MakeMergable() {
367 Comment cmnt(masm_, "[ Make frame mergable"); 365 Comment cmnt(masm_, "[ Make frame mergable");
368 // Remove constants from the frame and ensure that no registers are 366 // Remove constants from the frame and ensure that no registers are
369 // multiply referenced within the frame. Allocate elements to their 367 // multiply referenced within the frame. Allocate elements to their
370 // new locations from the top down so that the topmost elements have 368 // new locations from the top down so that the topmost elements have
371 // a chance to be in registers, then fill them into memory from the 369 // a chance to be in registers, then fill them into memory from the
372 // bottom up. (NB: Currently when spilling registers that are 370 // bottom up. (NB: Currently when spilling registers that are
373 // multiply referenced, it is the lowermost occurrence that gets to 371 // multiply referenced, it is the lowermost occurrence that gets to
374 // stay in the register.) 372 // stay in the register.)
373
374 // The elements of new_elements are initially invalid.
375 FrameElement* new_elements = new FrameElement[elements_.length()]; 375 FrameElement* new_elements = new FrameElement[elements_.length()];
376 FrameElement memory_element; 376 FrameElement memory_element = FrameElement::MemoryElement();
377 for (int i = elements_.length() - 1; i >= 0; i--) { 377 for (int i = elements_.length() - 1; i >= 0; i--) {
378 FrameElement element = elements_[i]; 378 FrameElement element = elements_[i];
379 if (element.is_constant() || 379 if (element.is_constant() ||
380 (element.is_register() && 380 (element.is_register() &&
381 frame_registers_.count(element.reg().code()) > 1)) { 381 frame_registers_.count(element.reg().code()) > 1)) {
382 // A simple strategy is to locate these elements in memory if they are 382 // A simple strategy is to locate these elements in memory if they are
383 // synced (avoiding a spill right now) and otherwise to prefer a 383 // synced (avoiding a spill right now) and otherwise to prefer a
384 // register for them. 384 // register for them.
385 if (element.is_synced()) { 385 if (element.is_synced()) {
386 new_elements[i] = memory_element; 386 new_elements[i] = memory_element;
387 } else { 387 } else {
388 Register reg = cgen_->allocator()->AllocateWithoutSpilling(); 388 Register reg = cgen_->allocator()->AllocateWithoutSpilling();
389 if (reg.is(no_reg)) { 389 if (reg.is(no_reg)) {
390 new_elements[i] = memory_element; 390 new_elements[i] = memory_element;
391 } else { 391 } else {
392 FrameElement register_element(reg, FrameElement::NOT_SYNCED); 392 new_elements[i] =
393 new_elements[i] = register_element; 393 FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED);
394 } 394 }
395 } 395 }
396 396
397 // We have not moved register references, but record that we will so 397 // We have not moved register references, but record that we will so
398 // that we do not unnecessarily spill the last reference within the 398 // that we do not unnecessarily spill the last reference within the
399 // frame. 399 // frame.
400 if (element.is_register()) { 400 if (element.is_register()) {
401 Unuse(element.reg()); 401 Unuse(element.reg());
402 } 402 }
403 } else { 403 } else {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 local_count_ = count; 663 local_count_ = count;
664 664
665 if (count > 0) { 665 if (count > 0) {
666 Comment cmnt(masm_, "[ Allocate space for locals"); 666 Comment cmnt(masm_, "[ Allocate space for locals");
667 // The locals are initialized to a constant (the undefined value), but 667 // The locals are initialized to a constant (the undefined value), but
668 // we sync them with the actual frame to allocate space for spilling 668 // we sync them with the actual frame to allocate space for spilling
669 // them later. First sync everything above the stack pointer so we can 669 // them later. First sync everything above the stack pointer so we can
670 // use pushes to allocate and initialize the locals. 670 // use pushes to allocate and initialize the locals.
671 SyncRange(stack_pointer_ + 1, elements_.length()); 671 SyncRange(stack_pointer_ + 1, elements_.length());
672 Handle<Object> undefined = Factory::undefined_value(); 672 Handle<Object> undefined = Factory::undefined_value();
673 FrameElement initial_value(undefined, FrameElement::SYNCED); 673 FrameElement initial_value =
674 FrameElement::ConstantElement(undefined, FrameElement::SYNCED);
674 Register temp = cgen_->allocator()->Allocate(); 675 Register temp = cgen_->allocator()->Allocate();
675 __ Set(temp, Immediate(undefined)); 676 __ Set(temp, Immediate(undefined));
676 for (int i = 0; i < count; i++) { 677 for (int i = 0; i < count; i++) {
677 elements_.Add(initial_value); 678 elements_.Add(initial_value);
678 stack_pointer_++; 679 stack_pointer_++;
679 __ push(temp); 680 __ push(temp);
680 } 681 }
681 cgen_->allocator()->Unuse(temp); 682 cgen_->allocator()->Unuse(temp);
682 } 683 }
683 } 684 }
684 685
685 686
686 void VirtualFrame::LoadFrameSlotAt(int index) { 687 void VirtualFrame::LoadFrameSlotAt(int index) {
687 ASSERT(index >= 0); 688 ASSERT(index >= 0);
688 ASSERT(index < elements_.length()); 689 ASSERT(index < elements_.length());
689 690
690 FrameElement element = elements_[index]; 691 FrameElement element = elements_[index];
691 692
692 if (element.is_memory()) { 693 if (element.is_memory()) {
693 ASSERT(index <= stack_pointer_); 694 ASSERT(index <= stack_pointer_);
694 // Eagerly load memory elements into a register. The element at 695 // Eagerly load memory elements into a register. The element at
695 // the index and the new top of the frame are backed by the same 696 // the index and the new top of the frame are backed by the same
696 // register location. 697 // register location.
697 Register temp = cgen_->allocator()->Allocate(); 698 Register temp = cgen_->allocator()->Allocate();
698 ASSERT(!temp.is(no_reg)); 699 ASSERT(!temp.is(no_reg));
699 FrameElement new_element(temp, FrameElement::NOT_SYNCED); 700 FrameElement new_element
701 = FrameElement::RegisterElement(temp, FrameElement::NOT_SYNCED);
700 Use(temp); 702 Use(temp);
701 elements_[index] = new_element; 703 elements_[index] = new_element;
702 Use(temp); 704 Use(temp);
703 elements_.Add(new_element); 705 elements_.Add(new_element);
704 706
705 // Finally, move the element at the index into its new location. 707 // Finally, move the element at the index into its new location.
706 elements_[index].set_sync(); 708 elements_[index].set_sync();
707 __ mov(temp, Operand(ebp, fp_relative(index))); 709 __ mov(temp, Operand(ebp, fp_relative(index)));
708 710
709 cgen_->allocator()->Unuse(temp); 711 cgen_->allocator()->Unuse(temp);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 void VirtualFrame::EmitPop(Operand operand) { 876 void VirtualFrame::EmitPop(Operand operand) {
875 ASSERT(stack_pointer_ == elements_.length() - 1); 877 ASSERT(stack_pointer_ == elements_.length() - 1);
876 stack_pointer_--; 878 stack_pointer_--;
877 elements_.RemoveLast(); 879 elements_.RemoveLast();
878 __ pop(operand); 880 __ pop(operand);
879 } 881 }
880 882
881 883
882 void VirtualFrame::EmitPush(Register reg) { 884 void VirtualFrame::EmitPush(Register reg) {
883 ASSERT(stack_pointer_ == elements_.length() - 1); 885 ASSERT(stack_pointer_ == elements_.length() - 1);
884 elements_.Add(FrameElement()); 886 elements_.Add(FrameElement::MemoryElement());
885 stack_pointer_++; 887 stack_pointer_++;
886 __ push(reg); 888 __ push(reg);
887 } 889 }
888 890
889 891
890 void VirtualFrame::EmitPush(Operand operand) { 892 void VirtualFrame::EmitPush(Operand operand) {
891 ASSERT(stack_pointer_ == elements_.length() - 1); 893 ASSERT(stack_pointer_ == elements_.length() - 1);
892 elements_.Add(FrameElement()); 894 elements_.Add(FrameElement::MemoryElement());
893 stack_pointer_++; 895 stack_pointer_++;
894 __ push(operand); 896 __ push(operand);
895 } 897 }
896 898
897 899
898 void VirtualFrame::EmitPush(Immediate immediate) { 900 void VirtualFrame::EmitPush(Immediate immediate) {
899 ASSERT(stack_pointer_ == elements_.length() - 1); 901 ASSERT(stack_pointer_ == elements_.length() - 1);
900 FrameElement memory_element; 902 elements_.Add(FrameElement::MemoryElement());
901 elements_.Add(memory_element);
902 stack_pointer_++; 903 stack_pointer_++;
903 __ push(immediate); 904 __ push(immediate);
904 } 905 }
905 906
906 907
907 void VirtualFrame::Push(Register reg) { 908 void VirtualFrame::Push(Register reg) {
908 FrameElement register_element(reg, FrameElement::NOT_SYNCED);
909 Use(reg); 909 Use(reg);
910 elements_.Add(register_element); 910 elements_.Add(FrameElement::RegisterElement(reg,
911 FrameElement::NOT_SYNCED));
911 } 912 }
912 913
913 914
914 void VirtualFrame::Push(Handle<Object> value) { 915 void VirtualFrame::Push(Handle<Object> value) {
915 FrameElement constant_element(value, FrameElement::NOT_SYNCED); 916 elements_.Add(FrameElement::ConstantElement(value,
916 elements_.Add(constant_element); 917 FrameElement::NOT_SYNCED));
917 } 918 }
918 919
919 920
920 #ifdef DEBUG 921 #ifdef DEBUG
921 bool VirtualFrame::IsSpilled() { 922 bool VirtualFrame::IsSpilled() {
922 for (int i = 0; i < elements_.length(); i++) { 923 for (int i = 0; i < elements_.length(); i++) {
923 if (!elements_[i].is_memory()) { 924 if (!elements_[i].is_memory()) {
924 return false; 925 return false;
925 } 926 }
926 } 927 }
927 return true; 928 return true;
928 } 929 }
929 #endif 930 #endif
930 931
931 #undef __ 932 #undef __
932 933
933 } } // namespace v8::internal 934 } } // 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