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

Side by Side Diff: src/x64/virtual-frame-x64.h

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, 6 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 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 // Construct a virtual frame as a clone of an existing one. 77 // Construct a virtual frame as a clone of an existing one.
78 explicit VirtualFrame(VirtualFrame* original); 78 explicit VirtualFrame(VirtualFrame* original);
79 79
80 CodeGenerator* cgen() { return CodeGeneratorScope::Current(); } 80 CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
81 MacroAssembler* masm() { return cgen()->masm(); } 81 MacroAssembler* masm() { return cgen()->masm(); }
82 82
83 // Create a duplicate of an existing valid frame element. 83 // Create a duplicate of an existing valid frame element.
84 FrameElement CopyElementAt(int index); 84 FrameElement CopyElementAt(int index);
85 85
86 // The number of elements on the virtual frame.
87 int element_count() { return elements_.length(); }
88
86 // The height of the virtual expression stack. 89 // The height of the virtual expression stack.
87 int height() { 90 int height() {
88 return elements_.length() - expression_base_index(); 91 return element_count() - expression_base_index();
89 } 92 }
90 93
91 int register_index(Register reg) { 94 int register_location(int num) {
92 return register_locations_[reg.code()]; 95 ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters);
96 return register_locations_[num];
93 } 97 }
94 98
95 bool is_used(int reg_code) { 99 int register_location(Register reg) {
96 return register_locations_[reg_code] != kIllegalIndex; 100 return register_locations_[RegisterAllocator::ToNumber(reg)];
101 }
102
103 void set_register_location(Register reg, int index) {
104 register_locations_[RegisterAllocator::ToNumber(reg)] = index;
105 }
106
107 bool is_used(int num) {
108 ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters);
109 return register_locations_[num] != kIllegalIndex;
97 } 110 }
98 111
99 bool is_used(Register reg) { 112 bool is_used(Register reg) {
100 return is_used(reg.code()); 113 return register_locations_[RegisterAllocator::ToNumber(reg)]
114 != kIllegalIndex;
101 } 115 }
102 116
103 // Add extra in-memory elements to the top of the frame to match an actual 117 // Add extra in-memory elements to the top of the frame to match an actual
104 // frame (eg, the frame after an exception handler is pushed). No code is 118 // frame (eg, the frame after an exception handler is pushed). No code is
105 // emitted. 119 // emitted.
106 void Adjust(int count); 120 void Adjust(int count);
107 121
108 // Forget count elements from the top of the frame all in-memory 122 // Forget count elements from the top of the frame all in-memory
109 // (including synced) and adjust the stack pointer downward, to 123 // (including synced) and adjust the stack pointer downward, to
110 // match an external frame effect (examples include a call removing 124 // match an external frame effect (examples include a call removing
111 // its arguments, and exiting a try/catch removing an exception 125 // its arguments, and exiting a try/catch removing an exception
112 // handler). No code will be emitted. 126 // handler). No code will be emitted.
113 void Forget(int count) { 127 void Forget(int count) {
114 ASSERT(count >= 0); 128 ASSERT(count >= 0);
115 ASSERT(stack_pointer_ == elements_.length() - 1); 129 ASSERT(stack_pointer_ == element_count() - 1);
116 stack_pointer_ -= count; 130 stack_pointer_ -= count;
117 ForgetElements(count); 131 ForgetElements(count);
118 } 132 }
119 133
120 // Forget count elements from the top of the frame without adjusting 134 // Forget count elements from the top of the frame without adjusting
121 // the stack pointer downward. This is used, for example, before 135 // the stack pointer downward. This is used, for example, before
122 // merging frames at break, continue, and return targets. 136 // merging frames at break, continue, and return targets.
123 void ForgetElements(int count); 137 void ForgetElements(int count);
124 138
125 // Spill all values from the frame to memory. 139 // Spill all values from the frame to memory.
126 void SpillAll(); 140 void SpillAll();
127 141
128 // Spill all occurrences of a specific register from the frame. 142 // Spill all occurrences of a specific register from the frame.
129 void Spill(Register reg) { 143 void Spill(Register reg) {
130 if (is_used(reg)) SpillElementAt(register_index(reg)); 144 if (is_used(reg)) SpillElementAt(register_location(reg));
131 } 145 }
132 146
133 // Spill all occurrences of an arbitrary register if possible. Return the 147 // Spill all occurrences of an arbitrary register if possible. Return the
134 // register spilled or no_reg if it was not possible to free any register 148 // register spilled or no_reg if it was not possible to free any register
135 // (ie, they all have frame-external references). 149 // (ie, they all have frame-external references).
136 Register SpillAnyRegister(); 150 Register SpillAnyRegister();
137 151
152 // Sync the range of elements in [begin, end] with memory.
153 void SyncRange(int begin, int end);
154
138 // Make this frame so that an arbitrary frame of the same height can 155 // Make this frame so that an arbitrary frame of the same height can
139 // be merged to it. Copies and constants are removed from the 156 // be merged to it. Copies and constants are removed from the
140 // topmost mergable_elements elements of the frame. A 157 // topmost mergable_elements elements of the frame. A
141 // mergable_elements of JumpTarget::kAllElements indicates constants 158 // mergable_elements of JumpTarget::kAllElements indicates constants
142 // and copies are should be removed from the entire frame. 159 // and copies are should be removed from the entire frame.
143 void MakeMergable(int mergable_elements); 160 void MakeMergable(int mergable_elements);
144 161
145 // Prepare this virtual frame for merging to an expected frame by 162 // Prepare this virtual frame for merging to an expected frame by
146 // performing some state changes that do not require generating 163 // performing some state changes that do not require generating
147 // code. It is guaranteed that no code will be generated. 164 // code. It is guaranteed that no code will be generated.
148 void PrepareMergeTo(VirtualFrame* expected); 165 void PrepareMergeTo(VirtualFrame* expected);
149 166
150 // Make this virtual frame have a state identical to an expected virtual 167 // Make this virtual frame have a state identical to an expected virtual
151 // frame. As a side effect, code may be emitted to make this frame match 168 // frame. As a side effect, code may be emitted to make this frame match
152 // the expected one. 169 // the expected one.
153 void MergeTo(VirtualFrame* expected); 170 void MergeTo(VirtualFrame* expected);
154 171
155 // Detach a frame from its code generator, perhaps temporarily. This 172 // Detach a frame from its code generator, perhaps temporarily. This
156 // tells the register allocator that it is free to use frame-internal 173 // tells the register allocator that it is free to use frame-internal
157 // registers. Used when the code generator's frame is switched from this 174 // registers. Used when the code generator's frame is switched from this
158 // one to NULL by an unconditional jump. 175 // one to NULL by an unconditional jump.
159 void DetachFromCodeGenerator() { 176 void DetachFromCodeGenerator() {
160 RegisterAllocator* cgen_allocator = cgen()->allocator(); 177 RegisterAllocator* cgen_allocator = cgen()->allocator();
161 for (int i = 0; i < kNumRegisters; i++) { 178 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
162 if (is_used(i)) { 179 if (is_used(i)) cgen_allocator->Unuse(i);
163 Register temp = { i };
164 cgen_allocator->Unuse(temp);
165 }
166 } 180 }
167 } 181 }
168 182
169 // (Re)attach a frame to its code generator. This informs the register 183 // (Re)attach a frame to its code generator. This informs the register
170 // allocator that the frame-internal register references are active again. 184 // allocator that the frame-internal register references are active again.
171 // Used when a code generator's frame is switched from NULL to this one by 185 // Used when a code generator's frame is switched from NULL to this one by
172 // binding a label. 186 // binding a label.
173 void AttachToCodeGenerator() { 187 void AttachToCodeGenerator() {
174 RegisterAllocator* cgen_allocator = cgen()->allocator(); 188 RegisterAllocator* cgen_allocator = cgen()->allocator();
175 for (int i = 0; i < kNumRegisters; i++) { 189 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
176 if (is_used(i)) { 190 if (is_used(i)) cgen_allocator->Use(i);
177 Register temp = { i };
178 cgen_allocator->Use(temp);
179 }
180 } 191 }
181 } 192 }
182 193
183 // Emit code for the physical JS entry and exit frame sequences. After 194 // Emit code for the physical JS entry and exit frame sequences. After
184 // calling Enter, the virtual frame is ready for use; and after calling 195 // calling Enter, the virtual frame is ready for use; and after calling
185 // Exit it should not be used. Note that Enter does not allocate space in 196 // Exit it should not be used. Note that Enter does not allocate space in
186 // the physical frame for storing frame-allocated locals. 197 // the physical frame for storing frame-allocated locals.
187 void Enter(); 198 void Enter();
188 void Exit(); 199 void Exit();
189 200
(...skipping 14 matching lines...) Expand all
204 // becomes owned by the frame and is invalidated. 215 // becomes owned by the frame and is invalidated.
205 void SetElementAt(int index, Result* value); 216 void SetElementAt(int index, Result* value);
206 217
207 // Set a frame element to a constant. The index is frame-top relative. 218 // Set a frame element to a constant. The index is frame-top relative.
208 void SetElementAt(int index, Handle<Object> value) { 219 void SetElementAt(int index, Handle<Object> value) {
209 Result temp(value); 220 Result temp(value);
210 SetElementAt(index, &temp); 221 SetElementAt(index, &temp);
211 } 222 }
212 223
213 void PushElementAt(int index) { 224 void PushElementAt(int index) {
214 PushFrameSlotAt(elements_.length() - index - 1); 225 PushFrameSlotAt(element_count() - index - 1);
215 } 226 }
216 227
217 void StoreToElementAt(int index) { 228 void StoreToElementAt(int index) {
218 StoreToFrameSlotAt(elements_.length() - index - 1); 229 StoreToFrameSlotAt(element_count() - index - 1);
219 } 230 }
220 231
221 // A frame-allocated local as an assembly operand. 232 // A frame-allocated local as an assembly operand.
222 Operand LocalAt(int index) { 233 Operand LocalAt(int index) {
223 ASSERT(0 <= index); 234 ASSERT(0 <= index);
224 ASSERT(index < local_count()); 235 ASSERT(index < local_count());
225 return Operand(rbp, kLocal0Offset - index * kPointerSize); 236 return Operand(rbp, kLocal0Offset - index * kPointerSize);
226 } 237 }
227 238
228 // Push a copy of the value of a local frame slot on top of the frame. 239 // Push a copy of the value of a local frame slot on top of the frame.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 356
346 // Drop a number of elements from the top of the expression stack. May 357 // Drop a number of elements from the top of the expression stack. May
347 // emit code to affect the physical frame. Does not clobber any registers 358 // emit code to affect the physical frame. Does not clobber any registers
348 // excepting possibly the stack pointer. 359 // excepting possibly the stack pointer.
349 void Drop(int count); 360 void Drop(int count);
350 361
351 // Drop one element. 362 // Drop one element.
352 void Drop() { Drop(1); } 363 void Drop() { Drop(1); }
353 364
354 // Duplicate the top element of the frame. 365 // Duplicate the top element of the frame.
355 void Dup() { PushFrameSlotAt(elements_.length() - 1); } 366 void Dup() { PushFrameSlotAt(element_count() - 1); }
356 367
357 // Pop an element from the top of the expression stack. Returns a 368 // Pop an element from the top of the expression stack. Returns a
358 // Result, which may be a constant or a register. 369 // Result, which may be a constant or a register.
359 Result Pop(); 370 Result Pop();
360 371
361 // Pop and save an element from the top of the expression stack and 372 // Pop and save an element from the top of the expression stack and
362 // emit a corresponding pop instruction. 373 // emit a corresponding pop instruction.
363 void EmitPop(Register reg); 374 void EmitPop(Register reg);
364 void EmitPop(Operand operand); 375 void EmitPop(Operand operand);
365 376
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. 411 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots.
401 412
402 ZoneList<FrameElement> elements_; 413 ZoneList<FrameElement> elements_;
403 414
404 // The index of the element that is at the processor's stack pointer 415 // The index of the element that is at the processor's stack pointer
405 // (the esp register). 416 // (the esp register).
406 int stack_pointer_; 417 int stack_pointer_;
407 418
408 // The index of the register frame element using each register, or 419 // The index of the register frame element using each register, or
409 // kIllegalIndex if a register is not on the frame. 420 // kIllegalIndex if a register is not on the frame.
410 int register_locations_[kNumRegisters]; 421 int register_locations_[RegisterAllocator::kNumRegisters];
411 422
412 // The number of frame-allocated locals and parameters respectively. 423 // The number of frame-allocated locals and parameters respectively.
413 int parameter_count() { return cgen()->scope()->num_parameters(); } 424 int parameter_count() { return cgen()->scope()->num_parameters(); }
414 int local_count() { return cgen()->scope()->num_stack_slots(); } 425 int local_count() { return cgen()->scope()->num_stack_slots(); }
415 426
416 // The index of the element that is at the processor's frame pointer 427 // The index of the element that is at the processor's frame pointer
417 // (the ebp register). The parameters, receiver, and return address 428 // (the ebp register). The parameters, receiver, and return address
418 // are below the frame pointer. 429 // are below the frame pointer.
419 int frame_pointer() { return parameter_count() + 2; } 430 int frame_pointer() { return parameter_count() + 2; }
420 431
421 // The index of the first parameter. The receiver lies below the first 432 // The index of the first parameter. The receiver lies below the first
422 // parameter. 433 // parameter.
423 int param0_index() const { return 1; } 434 int param0_index() { return 1; }
424 435
425 // The index of the context slot in the frame. It is immediately 436 // The index of the context slot in the frame. It is immediately
426 // above the frame pointer. 437 // above the frame pointer.
427 int context_index() { return frame_pointer() + 1; } 438 int context_index() { return frame_pointer() + 1; }
428 439
429 // The index of the function slot in the frame. It is above the frame 440 // The index of the function slot in the frame. It is above the frame
430 // pointer and the context slot. 441 // pointer and the context slot.
431 int function_index() { return frame_pointer() + 2; } 442 int function_index() { return frame_pointer() + 2; }
432 443
433 // The index of the first local. Between the frame pointer and the 444 // The index of the first local. Between the frame pointer and the
434 // locals lie the context and the function. 445 // locals lie the context and the function.
435 int local0_index() { return frame_pointer() + 3; } 446 int local0_index() { return frame_pointer() + 3; }
436 447
437 // The index of the base of the expression stack. 448 // The index of the base of the expression stack.
438 int expression_base_index() { return local0_index() + local_count(); } 449 int expression_base_index() { return local0_index() + local_count(); }
439 450
440 // Convert a frame index into a frame pointer relative offset into the 451 // Convert a frame index into a frame pointer relative offset into the
441 // actual stack. 452 // actual stack.
442 int fp_relative(int index) { 453 int fp_relative(int index) {
443 ASSERT(index < elements_.length()); 454 ASSERT(index < element_count());
444 ASSERT(frame_pointer() < elements_.length()); // FP is on the frame. 455 ASSERT(frame_pointer() < element_count()); // FP is on the frame.
445 return (frame_pointer() - index) * kPointerSize; 456 return (frame_pointer() - index) * kPointerSize;
446 } 457 }
447 458
448 // Record an occurrence of a register in the virtual frame. This has the 459 // Record an occurrence of a register in the virtual frame. This has the
449 // effect of incrementing the register's external reference count and 460 // effect of incrementing the register's external reference count and
450 // of updating the index of the register's location in the frame. 461 // of updating the index of the register's location in the frame.
451 void Use(Register reg, int index) { 462 void Use(Register reg, int index) {
452 ASSERT(!is_used(reg)); 463 ASSERT(!is_used(reg));
453 register_locations_[reg.code()] = index; 464 set_register_location(reg, index);
454 cgen()->allocator()->Use(reg); 465 cgen()->allocator()->Use(reg);
455 } 466 }
456 467
457 // Record that a register reference has been dropped from the frame. This 468 // Record that a register reference has been dropped from the frame. This
458 // decrements the register's external reference count and invalidates the 469 // decrements the register's external reference count and invalidates the
459 // index of the register's location in the frame. 470 // index of the register's location in the frame.
460 void Unuse(Register reg) { 471 void Unuse(Register reg) {
461 ASSERT(register_locations_[reg.code()] != kIllegalIndex); 472 ASSERT(is_used(reg));
462 register_locations_[reg.code()] = kIllegalIndex; 473 set_register_location(reg, kIllegalIndex);
463 cgen()->allocator()->Unuse(reg); 474 cgen()->allocator()->Unuse(reg);
464 } 475 }
465 476
466 // Spill the element at a particular index---write it to memory if 477 // Spill the element at a particular index---write it to memory if
467 // necessary, free any associated register, and forget its value if 478 // necessary, free any associated register, and forget its value if
468 // constant. 479 // constant.
469 void SpillElementAt(int index); 480 void SpillElementAt(int index);
470 481
471 // Sync the element at a particular index. If it is a register or 482 // Sync the element at a particular index. If it is a register or
472 // constant that disagrees with the value on the stack, write it to memory. 483 // constant that disagrees with the value on the stack, write it to memory.
473 // Keep the element type as register or constant, and clear the dirty bit. 484 // Keep the element type as register or constant, and clear the dirty bit.
474 void SyncElementAt(int index); 485 void SyncElementAt(int index);
475 486
476 // Sync the range of elements in [begin, end).
477 void SyncRange(int begin, int end);
478
479 // Sync a single unsynced element that lies beneath or at the stack pointer. 487 // Sync a single unsynced element that lies beneath or at the stack pointer.
480 void SyncElementBelowStackPointer(int index); 488 void SyncElementBelowStackPointer(int index);
481 489
482 // Sync a single unsynced element that lies just above the stack pointer. 490 // Sync a single unsynced element that lies just above the stack pointer.
483 void SyncElementByPushing(int index); 491 void SyncElementByPushing(int index);
484 492
485 // Push a copy of a frame slot (typically a local or parameter) on top of 493 // Push a copy of a frame slot (typically a local or parameter) on top of
486 // the frame. 494 // the frame.
487 void PushFrameSlotAt(int index); 495 void PushFrameSlotAt(int index);
488 496
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 545
538 bool Equals(VirtualFrame* other); 546 bool Equals(VirtualFrame* other);
539 547
540 friend class JumpTarget; 548 friend class JumpTarget;
541 }; 549 };
542 550
543 551
544 } } // namespace v8::internal 552 } } // namespace v8::internal
545 553
546 #endif // V8_X64_VIRTUAL_FRAME_X64_H_ 554 #endif // V8_X64_VIRTUAL_FRAME_X64_H_
OLDNEW
« src/ia32/virtual-frame-ia32.h ('K') | « src/x64/register-allocator-x64-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698