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

Side by Side Diff: src/arm/virtual-frame-arm.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, 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
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 elements from the top of the frame to match an actual frame (eg, 122 // Forget elements from the top of the frame to match an actual frame (eg,
109 // the frame after a runtime call). No code is emitted. 123 // the frame after a runtime call). No code is emitted.
110 void Forget(int count) { 124 void Forget(int count) {
111 ASSERT(count >= 0); 125 ASSERT(count >= 0);
112 ASSERT(stack_pointer_ == elements_.length() - 1); 126 ASSERT(stack_pointer_ == element_count() - 1);
113 stack_pointer_ -= count; 127 stack_pointer_ -= count;
114 ForgetElements(count); 128 ForgetElements(count);
115 } 129 }
116 130
117 // Forget count elements from the top of the frame without adjusting 131 // Forget count elements from the top of the frame without adjusting
118 // the stack pointer downward. This is used, for example, before 132 // the stack pointer downward. This is used, for example, before
119 // merging frames at break, continue, and return targets. 133 // merging frames at break, continue, and return targets.
120 void ForgetElements(int count); 134 void ForgetElements(int count);
121 135
122 // Spill all values from the frame to memory. 136 // Spill all values from the frame to memory.
123 void SpillAll(); 137 void SpillAll();
124 138
125 // Spill all occurrences of a specific register from the frame. 139 // Spill all occurrences of a specific register from the frame.
126 void Spill(Register reg) { 140 void Spill(Register reg) {
127 if (is_used(reg)) SpillElementAt(register_index(reg)); 141 if (is_used(reg)) SpillElementAt(register_location(reg));
128 } 142 }
129 143
130 // Spill all occurrences of an arbitrary register if possible. Return the 144 // Spill all occurrences of an arbitrary register if possible. Return the
131 // register spilled or no_reg if it was not possible to free any register 145 // register spilled or no_reg if it was not possible to free any register
132 // (ie, they all have frame-external references). 146 // (ie, they all have frame-external references).
133 Register SpillAnyRegister(); 147 Register SpillAnyRegister();
134 148
135 // Prepare this virtual frame for merging to an expected frame by 149 // Prepare this virtual frame for merging to an expected frame by
136 // performing some state changes that do not require generating 150 // performing some state changes that do not require generating
137 // code. It is guaranteed that no code will be generated. 151 // code. It is guaranteed that no code will be generated.
138 void PrepareMergeTo(VirtualFrame* expected); 152 void PrepareMergeTo(VirtualFrame* expected);
139 153
140 // Make this virtual frame have a state identical to an expected virtual 154 // Make this virtual frame have a state identical to an expected virtual
141 // frame. As a side effect, code may be emitted to make this frame match 155 // frame. As a side effect, code may be emitted to make this frame match
142 // the expected one. 156 // the expected one.
143 void MergeTo(VirtualFrame* expected); 157 void MergeTo(VirtualFrame* expected);
144 158
145 // Detach a frame from its code generator, perhaps temporarily. This 159 // Detach a frame from its code generator, perhaps temporarily. This
146 // tells the register allocator that it is free to use frame-internal 160 // tells the register allocator that it is free to use frame-internal
147 // registers. Used when the code generator's frame is switched from this 161 // registers. Used when the code generator's frame is switched from this
148 // one to NULL by an unconditional jump. 162 // one to NULL by an unconditional jump.
149 void DetachFromCodeGenerator() { 163 void DetachFromCodeGenerator() {
150 RegisterAllocator* cgen_allocator = cgen()->allocator(); 164 RegisterAllocator* cgen_allocator = cgen()->allocator();
151 for (int i = 0; i < kNumRegisters; i++) { 165 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
152 if (is_used(i)) { 166 if (is_used(i)) cgen_allocator->Unuse(i);
153 Register temp = { i };
154 cgen_allocator->Unuse(temp);
155 }
156 } 167 }
157 } 168 }
158 169
159 // (Re)attach a frame to its code generator. This informs the register 170 // (Re)attach a frame to its code generator. This informs the register
160 // allocator that the frame-internal register references are active again. 171 // allocator that the frame-internal register references are active again.
161 // Used when a code generator's frame is switched from NULL to this one by 172 // Used when a code generator's frame is switched from NULL to this one by
162 // binding a label. 173 // binding a label.
163 void AttachToCodeGenerator() { 174 void AttachToCodeGenerator() {
164 RegisterAllocator* cgen_allocator = cgen()->allocator(); 175 RegisterAllocator* cgen_allocator = cgen()->allocator();
165 for (int i = 0; i < kNumRegisters; i++) { 176 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
166 if (is_used(i)) { 177 if (is_used(i)) cgen_allocator->Unuse(i);
167 Register temp = { i };
168 cgen_allocator->Use(temp);
169 }
170 } 178 }
171 } 179 }
172 180
173 // Emit code for the physical JS entry and exit frame sequences. After 181 // Emit code for the physical JS entry and exit frame sequences. After
174 // calling Enter, the virtual frame is ready for use; and after calling 182 // calling Enter, the virtual frame is ready for use; and after calling
175 // Exit it should not be used. Note that Enter does not allocate space in 183 // Exit it should not be used. Note that Enter does not allocate space in
176 // the physical frame for storing frame-allocated locals. 184 // the physical frame for storing frame-allocated locals.
177 void Enter(); 185 void Enter();
178 void Exit(); 186 void Exit();
179 187
(...skipping 18 matching lines...) Expand all
198 // becomes owned by the frame and is invalidated. 206 // becomes owned by the frame and is invalidated.
199 void SetElementAt(int index, Result* value); 207 void SetElementAt(int index, Result* value);
200 208
201 // Set a frame element to a constant. The index is frame-top relative. 209 // Set a frame element to a constant. The index is frame-top relative.
202 void SetElementAt(int index, Handle<Object> value) { 210 void SetElementAt(int index, Handle<Object> value) {
203 Result temp(value); 211 Result temp(value);
204 SetElementAt(index, &temp); 212 SetElementAt(index, &temp);
205 } 213 }
206 214
207 void PushElementAt(int index) { 215 void PushElementAt(int index) {
208 PushFrameSlotAt(elements_.length() - index - 1); 216 PushFrameSlotAt(element_count() - index - 1);
209 } 217 }
210 218
211 // A frame-allocated local as an assembly operand. 219 // A frame-allocated local as an assembly operand.
212 MemOperand LocalAt(int index) { 220 MemOperand LocalAt(int index) {
213 ASSERT(0 <= index); 221 ASSERT(0 <= index);
214 ASSERT(index < local_count()); 222 ASSERT(index < local_count());
215 return MemOperand(fp, kLocal0Offset - index * kPointerSize); 223 return MemOperand(fp, kLocal0Offset - index * kPointerSize);
216 } 224 }
217 225
218 // Push a copy of the value of a local frame slot on top of the frame. 226 // Push a copy of the value of a local frame slot on top of the frame.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 337
330 // Drop a number of elements from the top of the expression stack. May 338 // Drop a number of elements from the top of the expression stack. May
331 // emit code to affect the physical frame. Does not clobber any registers 339 // emit code to affect the physical frame. Does not clobber any registers
332 // excepting possibly the stack pointer. 340 // excepting possibly the stack pointer.
333 void Drop(int count); 341 void Drop(int count);
334 342
335 // Drop one element. 343 // Drop one element.
336 void Drop() { Drop(1); } 344 void Drop() { Drop(1); }
337 345
338 // Duplicate the top element of the frame. 346 // Duplicate the top element of the frame.
339 void Dup() { PushFrameSlotAt(elements_.length() - 1); } 347 void Dup() { PushFrameSlotAt(element_count() - 1); }
340 348
341 // Pop an element from the top of the expression stack. Returns a 349 // Pop an element from the top of the expression stack. Returns a
342 // Result, which may be a constant or a register. 350 // Result, which may be a constant or a register.
343 Result Pop(); 351 Result Pop();
344 352
345 // Pop and save an element from the top of the expression stack and 353 // Pop and save an element from the top of the expression stack and
346 // emit a corresponding pop instruction. 354 // emit a corresponding pop instruction.
347 void EmitPop(Register reg); 355 void EmitPop(Register reg);
348 356
349 // Push an element on top of the expression stack and emit a 357 // Push an element on top of the expression stack and emit a
(...skipping 30 matching lines...) Expand all
380 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. 388 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots.
381 389
382 ZoneList<FrameElement> elements_; 390 ZoneList<FrameElement> elements_;
383 391
384 // The index of the element that is at the processor's stack pointer 392 // The index of the element that is at the processor's stack pointer
385 // (the sp register). 393 // (the sp register).
386 int stack_pointer_; 394 int stack_pointer_;
387 395
388 // The index of the register frame element using each register, or 396 // The index of the register frame element using each register, or
389 // kIllegalIndex if a register is not on the frame. 397 // kIllegalIndex if a register is not on the frame.
390 int register_locations_[kNumRegisters]; 398 int register_locations_[RegisterAllocator::kNumRegisters];
391 399
392 // The number of frame-allocated locals and parameters respectively. 400 // The number of frame-allocated locals and parameters respectively.
393 int parameter_count() { return cgen()->scope()->num_parameters(); } 401 int parameter_count() { return cgen()->scope()->num_parameters(); }
394 int local_count() { return cgen()->scope()->num_stack_slots(); } 402 int local_count() { return cgen()->scope()->num_stack_slots(); }
395 403
396 // The index of the element that is at the processor's frame pointer 404 // The index of the element that is at the processor's frame pointer
397 // (the fp register). The parameters, receiver, function, and context 405 // (the fp register). The parameters, receiver, function, and context
398 // are below the frame pointer. 406 // are below the frame pointer.
399 int frame_pointer() { return parameter_count() + 3; } 407 int frame_pointer() { return parameter_count() + 3; }
400 408
(...skipping 12 matching lines...) Expand all
413 // The index of the first local. Between the frame pointer and the 421 // The index of the first local. Between the frame pointer and the
414 // locals lies the return address. 422 // locals lies the return address.
415 int local0_index() { return frame_pointer() + 2; } 423 int local0_index() { return frame_pointer() + 2; }
416 424
417 // The index of the base of the expression stack. 425 // The index of the base of the expression stack.
418 int expression_base_index() { return local0_index() + local_count(); } 426 int expression_base_index() { return local0_index() + local_count(); }
419 427
420 // Convert a frame index into a frame pointer relative offset into the 428 // Convert a frame index into a frame pointer relative offset into the
421 // actual stack. 429 // actual stack.
422 int fp_relative(int index) { 430 int fp_relative(int index) {
423 ASSERT(index < elements_.length()); 431 ASSERT(index < element_count());
424 ASSERT(frame_pointer() < elements_.length()); // FP is on the frame. 432 ASSERT(frame_pointer() < element_count()); // FP is on the frame.
425 return (frame_pointer() - index) * kPointerSize; 433 return (frame_pointer() - index) * kPointerSize;
426 } 434 }
427 435
428 // Record an occurrence of a register in the virtual frame. This has the 436 // Record an occurrence of a register in the virtual frame. This has the
429 // effect of incrementing the register's external reference count and 437 // effect of incrementing the register's external reference count and
430 // of updating the index of the register's location in the frame. 438 // of updating the index of the register's location in the frame.
431 void Use(Register reg, int index) { 439 void Use(Register reg, int index) {
432 ASSERT(!is_used(reg)); 440 ASSERT(!is_used(reg));
433 register_locations_[reg.code()] = index; 441 set_register_location(reg, index);
434 cgen()->allocator()->Use(reg); 442 cgen()->allocator()->Use(reg);
435 } 443 }
436 444
437 // Record that a register reference has been dropped from the frame. This 445 // Record that a register reference has been dropped from the frame. This
438 // decrements the register's external reference count and invalidates the 446 // decrements the register's external reference count and invalidates the
439 // index of the register's location in the frame. 447 // index of the register's location in the frame.
440 void Unuse(Register reg) { 448 void Unuse(Register reg) {
441 ASSERT(register_locations_[reg.code()] != kIllegalIndex); 449 ASSERT(is_used(reg));
442 register_locations_[reg.code()] = kIllegalIndex; 450 set_register_location(reg, kIllegalIndex);
443 cgen()->allocator()->Unuse(reg); 451 cgen()->allocator()->Unuse(reg);
444 } 452 }
445 453
446 // Spill the element at a particular index---write it to memory if 454 // Spill the element at a particular index---write it to memory if
447 // necessary, free any associated register, and forget its value if 455 // necessary, free any associated register, and forget its value if
448 // constant. 456 // constant.
449 void SpillElementAt(int index); 457 void SpillElementAt(int index);
450 458
451 // Sync the element at a particular index. If it is a register or 459 // Sync the element at a particular index. If it is a register or
452 // constant that disagrees with the value on the stack, write it to memory. 460 // constant that disagrees with the value on the stack, write it to memory.
453 // Keep the element type as register or constant, and clear the dirty bit. 461 // Keep the element type as register or constant, and clear the dirty bit.
454 void SyncElementAt(int index); 462 void SyncElementAt(int index);
455 463
456 // Sync the range of elements in [begin, end). 464 // Sync the range of elements in [begin, end] with memory.
457 void SyncRange(int begin, int end); 465 void SyncRange(int begin, int end);
458 466
459 // Sync a single unsynced element that lies beneath or at the stack pointer. 467 // Sync a single unsynced element that lies beneath or at the stack pointer.
460 void SyncElementBelowStackPointer(int index); 468 void SyncElementBelowStackPointer(int index);
461 469
462 // Sync a single unsynced element that lies just above the stack pointer. 470 // Sync a single unsynced element that lies just above the stack pointer.
463 void SyncElementByPushing(int index); 471 void SyncElementByPushing(int index);
464 472
465 // Push a copy of a frame slot (typically a local or parameter) on top of 473 // Push a copy of a frame slot (typically a local or parameter) on top of
466 // the frame. 474 // the frame.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 525
518 bool Equals(VirtualFrame* other); 526 bool Equals(VirtualFrame* other);
519 527
520 friend class JumpTarget; 528 friend class JumpTarget;
521 }; 529 };
522 530
523 531
524 } } // namespace v8::internal 532 } } // namespace v8::internal
525 533
526 #endif // V8_ARM_VIRTUAL_FRAME_ARM_H_ 534 #endif // V8_ARM_VIRTUAL_FRAME_ARM_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698