OLD | NEW |
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 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_ARM_VIRTUAL_FRAME_ARM_H_ | 28 #ifndef V8_ARM_VIRTUAL_FRAME_ARM_H_ |
29 #define V8_ARM_VIRTUAL_FRAME_ARM_H_ | 29 #define V8_ARM_VIRTUAL_FRAME_ARM_H_ |
30 | 30 |
31 #include "register-allocator.h" | 31 #include "register-allocator.h" |
| 32 #include "scopes.h" |
32 | 33 |
33 namespace v8 { namespace internal { | 34 namespace v8 { namespace internal { |
34 | 35 |
35 // ------------------------------------------------------------------------- | 36 // ------------------------------------------------------------------------- |
36 // Virtual frames | 37 // Virtual frames |
37 // | 38 // |
38 // The virtual frame is an abstraction of the physical stack frame. It | 39 // The virtual frame is an abstraction of the physical stack frame. It |
39 // encapsulates the parameters, frame-allocated locals, and the expression | 40 // encapsulates the parameters, frame-allocated locals, and the expression |
40 // stack. It supports push/pop operations on the expression stack, as well | 41 // stack. It supports push/pop operations on the expression stack, as well |
41 // as random access to the expression stack elements, locals, and | 42 // as random access to the expression stack elements, locals, and |
42 // parameters. | 43 // parameters. |
43 | 44 |
44 class VirtualFrame : public ZoneObject { | 45 class VirtualFrame : public ZoneObject { |
45 public: | 46 public: |
46 // A utility class to introduce a scope where the virtual frame is | 47 // A utility class to introduce a scope where the virtual frame is |
47 // expected to remain spilled. The constructor spills the code | 48 // expected to remain spilled. The constructor spills the code |
48 // generator's current frame, but no attempt is made to require it | 49 // generator's current frame, but no attempt is made to require it |
49 // to stay spilled. It is intended as documentation while the code | 50 // to stay spilled. It is intended as documentation while the code |
50 // generator is being transformed. | 51 // generator is being transformed. |
51 class SpilledScope BASE_EMBEDDED { | 52 class SpilledScope BASE_EMBEDDED { |
52 public: | 53 public: |
53 explicit SpilledScope(CodeGenerator* cgen) | 54 SpilledScope() : previous_state_(cgen()->in_spilled_code()) { |
54 : cgen_(cgen), | 55 ASSERT(cgen()->has_valid_frame()); |
55 previous_state_(cgen->in_spilled_code()) { | 56 cgen()->frame()->SpillAll(); |
56 ASSERT(cgen->has_valid_frame()); | 57 cgen()->set_in_spilled_code(true); |
57 cgen->frame()->SpillAll(); | |
58 cgen->set_in_spilled_code(true); | |
59 } | 58 } |
60 | 59 |
61 ~SpilledScope() { | 60 ~SpilledScope() { |
62 cgen_->set_in_spilled_code(previous_state_); | 61 cgen()->set_in_spilled_code(previous_state_); |
63 } | 62 } |
64 | 63 |
65 private: | 64 private: |
66 CodeGenerator* cgen_; | |
67 bool previous_state_; | 65 bool previous_state_; |
| 66 |
| 67 CodeGenerator* cgen() { return CodeGeneratorScope::Current(); } |
68 }; | 68 }; |
69 | 69 |
70 // An illegal index into the virtual frame. | 70 // An illegal index into the virtual frame. |
71 static const int kIllegalIndex = -1; | 71 static const int kIllegalIndex = -1; |
72 | 72 |
73 // Construct an initial virtual frame on entry to a JS function. | 73 // Construct an initial virtual frame on entry to a JS function. |
74 explicit VirtualFrame(CodeGenerator* cgen); | 74 VirtualFrame(); |
75 | 75 |
76 // Construct a virtual frame as a clone of an existing one. | 76 // Construct a virtual frame as a clone of an existing one. |
77 explicit VirtualFrame(VirtualFrame* original); | 77 explicit VirtualFrame(VirtualFrame* original); |
78 | 78 |
| 79 CodeGenerator* cgen() { return CodeGeneratorScope::Current(); } |
| 80 MacroAssembler* masm() { return cgen()->masm(); } |
| 81 |
79 // Create a duplicate of an existing valid frame element. | 82 // Create a duplicate of an existing valid frame element. |
80 FrameElement CopyElementAt(int index); | 83 FrameElement CopyElementAt(int index); |
81 | 84 |
82 // The height of the virtual expression stack. | 85 // The height of the virtual expression stack. |
83 int height() const { | 86 int height() { |
84 return elements_.length() - expression_base_index(); | 87 return elements_.length() - expression_base_index(); |
85 } | 88 } |
86 | 89 |
87 int register_index(Register reg) { | 90 int register_index(Register reg) { |
88 return register_locations_[reg.code()]; | 91 return register_locations_[reg.code()]; |
89 } | 92 } |
90 | 93 |
91 bool is_used(int reg_code) { | 94 bool is_used(int reg_code) { |
92 return register_locations_[reg_code] != kIllegalIndex; | 95 return register_locations_[reg_code] != kIllegalIndex; |
93 } | 96 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 // Make this virtual frame have a state identical to an expected virtual | 139 // Make this virtual frame have a state identical to an expected virtual |
137 // frame. As a side effect, code may be emitted to make this frame match | 140 // frame. As a side effect, code may be emitted to make this frame match |
138 // the expected one. | 141 // the expected one. |
139 void MergeTo(VirtualFrame* expected); | 142 void MergeTo(VirtualFrame* expected); |
140 | 143 |
141 // Detach a frame from its code generator, perhaps temporarily. This | 144 // Detach a frame from its code generator, perhaps temporarily. This |
142 // tells the register allocator that it is free to use frame-internal | 145 // tells the register allocator that it is free to use frame-internal |
143 // registers. Used when the code generator's frame is switched from this | 146 // registers. Used when the code generator's frame is switched from this |
144 // one to NULL by an unconditional jump. | 147 // one to NULL by an unconditional jump. |
145 void DetachFromCodeGenerator() { | 148 void DetachFromCodeGenerator() { |
146 RegisterAllocator* cgen_allocator = cgen_->allocator(); | 149 RegisterAllocator* cgen_allocator = cgen()->allocator(); |
147 for (int i = 0; i < kNumRegisters; i++) { | 150 for (int i = 0; i < kNumRegisters; i++) { |
148 if (is_used(i)) { | 151 if (is_used(i)) { |
149 Register temp = { i }; | 152 Register temp = { i }; |
150 cgen_allocator->Unuse(temp); | 153 cgen_allocator->Unuse(temp); |
151 } | 154 } |
152 } | 155 } |
153 } | 156 } |
154 | 157 |
155 // (Re)attach a frame to its code generator. This informs the register | 158 // (Re)attach a frame to its code generator. This informs the register |
156 // allocator that the frame-internal register references are active again. | 159 // allocator that the frame-internal register references are active again. |
157 // Used when a code generator's frame is switched from NULL to this one by | 160 // Used when a code generator's frame is switched from NULL to this one by |
158 // binding a label. | 161 // binding a label. |
159 void AttachToCodeGenerator() { | 162 void AttachToCodeGenerator() { |
160 RegisterAllocator* cgen_allocator = cgen_->allocator(); | 163 RegisterAllocator* cgen_allocator = cgen()->allocator(); |
161 for (int i = 0; i < kNumRegisters; i++) { | 164 for (int i = 0; i < kNumRegisters; i++) { |
162 if (is_used(i)) { | 165 if (is_used(i)) { |
163 Register temp = { i }; | 166 Register temp = { i }; |
164 cgen_allocator->Use(temp); | 167 cgen_allocator->Use(temp); |
165 } | 168 } |
166 } | 169 } |
167 } | 170 } |
168 | 171 |
169 // Emit code for the physical JS entry and exit frame sequences. After | 172 // Emit code for the physical JS entry and exit frame sequences. After |
170 // calling Enter, the virtual frame is ready for use; and after calling | 173 // calling Enter, the virtual frame is ready for use; and after calling |
171 // Exit it should not be used. Note that Enter does not allocate space in | 174 // Exit it should not be used. Note that Enter does not allocate space in |
172 // the physical frame for storing frame-allocated locals. | 175 // the physical frame for storing frame-allocated locals. |
173 void Enter(); | 176 void Enter(); |
174 void Exit(); | 177 void Exit(); |
175 | 178 |
176 // Prepare for returning from the frame by spilling locals and | 179 // Prepare for returning from the frame by spilling locals and |
177 // dropping all non-locals elements in the virtual frame. This | 180 // dropping all non-locals elements in the virtual frame. This |
178 // avoids generating unnecessary merge code when jumping to the | 181 // avoids generating unnecessary merge code when jumping to the |
179 // shared return site. Emits code for spills. | 182 // shared return site. Emits code for spills. |
180 void PrepareForReturn(); | 183 void PrepareForReturn(); |
181 | 184 |
182 // Allocate and initialize the frame-allocated locals. | 185 // Allocate and initialize the frame-allocated locals. |
183 void AllocateStackSlots(int count); | 186 void AllocateStackSlots(); |
184 | 187 |
185 // The current top of the expression stack as an assembly operand. | 188 // The current top of the expression stack as an assembly operand. |
186 MemOperand Top() const { return MemOperand(sp, 0); } | 189 MemOperand Top() { return MemOperand(sp, 0); } |
187 | 190 |
188 // An element of the expression stack as an assembly operand. | 191 // An element of the expression stack as an assembly operand. |
189 MemOperand ElementAt(int index) const { | 192 MemOperand ElementAt(int index) { |
190 return MemOperand(sp, index * kPointerSize); | 193 return MemOperand(sp, index * kPointerSize); |
191 } | 194 } |
192 | 195 |
193 // Random-access store to a frame-top relative frame element. The result | 196 // Random-access store to a frame-top relative frame element. The result |
194 // becomes owned by the frame and is invalidated. | 197 // becomes owned by the frame and is invalidated. |
195 void SetElementAt(int index, Result* value); | 198 void SetElementAt(int index, Result* value); |
196 | 199 |
197 // Set a frame element to a constant. The index is frame-top relative. | 200 // Set a frame element to a constant. The index is frame-top relative. |
198 void SetElementAt(int index, Handle<Object> value) { | 201 void SetElementAt(int index, Handle<Object> value) { |
199 Result temp(value); | 202 Result temp(value); |
200 SetElementAt(index, &temp); | 203 SetElementAt(index, &temp); |
201 } | 204 } |
202 | 205 |
203 void PushElementAt(int index) { | 206 void PushElementAt(int index) { |
204 PushFrameSlotAt(elements_.length() - index - 1); | 207 PushFrameSlotAt(elements_.length() - index - 1); |
205 } | 208 } |
206 | 209 |
207 // A frame-allocated local as an assembly operand. | 210 // A frame-allocated local as an assembly operand. |
208 MemOperand LocalAt(int index) const { | 211 MemOperand LocalAt(int index) { |
209 ASSERT(0 <= index); | 212 ASSERT(0 <= index); |
210 ASSERT(index < local_count_); | 213 ASSERT(index < local_count()); |
211 return MemOperand(fp, kLocal0Offset - index * kPointerSize); | 214 return MemOperand(fp, kLocal0Offset - index * kPointerSize); |
212 } | 215 } |
213 | 216 |
214 // Push a copy of the value of a local frame slot on top of the frame. | 217 // Push a copy of the value of a local frame slot on top of the frame. |
215 void PushLocalAt(int index) { | 218 void PushLocalAt(int index) { |
216 PushFrameSlotAt(local0_index() + index); | 219 PushFrameSlotAt(local0_index() + index); |
217 } | 220 } |
218 | 221 |
219 // Push the value of a local frame slot on top of the frame and invalidate | 222 // Push the value of a local frame slot on top of the frame and invalidate |
220 // the local slot. The slot should be written to before trying to read | 223 // the local slot. The slot should be written to before trying to read |
221 // from it again. | 224 // from it again. |
222 void TakeLocalAt(int index) { | 225 void TakeLocalAt(int index) { |
223 TakeFrameSlotAt(local0_index() + index); | 226 TakeFrameSlotAt(local0_index() + index); |
224 } | 227 } |
225 | 228 |
226 // Store the top value on the virtual frame into a local frame slot. The | 229 // Store the top value on the virtual frame into a local frame slot. The |
227 // value is left in place on top of the frame. | 230 // value is left in place on top of the frame. |
228 void StoreToLocalAt(int index) { | 231 void StoreToLocalAt(int index) { |
229 StoreToFrameSlotAt(local0_index() + index); | 232 StoreToFrameSlotAt(local0_index() + index); |
230 } | 233 } |
231 | 234 |
232 // Push the address of the receiver slot on the frame. | 235 // Push the address of the receiver slot on the frame. |
233 void PushReceiverSlotAddress(); | 236 void PushReceiverSlotAddress(); |
234 | 237 |
235 // The function frame slot. | 238 // The function frame slot. |
236 MemOperand Function() const { return MemOperand(fp, kFunctionOffset); } | 239 MemOperand Function() { return MemOperand(fp, kFunctionOffset); } |
237 | 240 |
238 // Push the function on top of the frame. | 241 // Push the function on top of the frame. |
239 void PushFunction() { PushFrameSlotAt(function_index()); } | 242 void PushFunction() { PushFrameSlotAt(function_index()); } |
240 | 243 |
241 // The context frame slot. | 244 // The context frame slot. |
242 MemOperand Context() const { return MemOperand(fp, kContextOffset); } | 245 MemOperand Context() { return MemOperand(fp, kContextOffset); } |
243 | 246 |
244 // Save the value of the esi register to the context frame slot. | 247 // Save the value of the esi register to the context frame slot. |
245 void SaveContextRegister(); | 248 void SaveContextRegister(); |
246 | 249 |
247 // Restore the esi register from the value of the context frame | 250 // Restore the esi register from the value of the context frame |
248 // slot. | 251 // slot. |
249 void RestoreContextRegister(); | 252 void RestoreContextRegister(); |
250 | 253 |
251 // A parameter as an assembly operand. | 254 // A parameter as an assembly operand. |
252 MemOperand ParameterAt(int index) const { | 255 MemOperand ParameterAt(int index) { |
253 // Index -1 corresponds to the receiver. | 256 // Index -1 corresponds to the receiver. |
254 ASSERT(-1 <= index && index <= parameter_count_); | 257 ASSERT(-1 <= index); // -1 is the receiver. |
255 return MemOperand(fp, (1 + parameter_count_ - index) * kPointerSize); | 258 ASSERT(index <= parameter_count()); |
| 259 return MemOperand(fp, (1 + parameter_count() - index) * kPointerSize); |
256 } | 260 } |
257 | 261 |
258 // Push a copy of the value of a parameter frame slot on top of the frame. | 262 // Push a copy of the value of a parameter frame slot on top of the frame. |
259 void PushParameterAt(int index) { | 263 void PushParameterAt(int index) { |
260 PushFrameSlotAt(param0_index() + index); | 264 PushFrameSlotAt(param0_index() + index); |
261 } | 265 } |
262 | 266 |
263 // Push the value of a paramter frame slot on top of the frame and | 267 // Push the value of a paramter frame slot on top of the frame and |
264 // invalidate the parameter slot. The slot should be written to before | 268 // invalidate the parameter slot. The slot should be written to before |
265 // trying to read from it again. | 269 // trying to read from it again. |
266 void TakeParameterAt(int index) { | 270 void TakeParameterAt(int index) { |
267 TakeFrameSlotAt(param0_index() + index); | 271 TakeFrameSlotAt(param0_index() + index); |
268 } | 272 } |
269 | 273 |
270 // Store the top value on the virtual frame into a parameter frame slot. | 274 // Store the top value on the virtual frame into a parameter frame slot. |
271 // The value is left in place on top of the frame. | 275 // The value is left in place on top of the frame. |
272 void StoreToParameterAt(int index) { | 276 void StoreToParameterAt(int index) { |
273 StoreToFrameSlotAt(param0_index() + index); | 277 StoreToFrameSlotAt(param0_index() + index); |
274 } | 278 } |
275 | 279 |
276 // The receiver frame slot. | 280 // The receiver frame slot. |
277 MemOperand Receiver() const { return ParameterAt(-1); } | 281 MemOperand Receiver() { return ParameterAt(-1); } |
278 | 282 |
279 // Push a try-catch or try-finally handler on top of the virtual frame. | 283 // Push a try-catch or try-finally handler on top of the virtual frame. |
280 void PushTryHandler(HandlerType type); | 284 void PushTryHandler(HandlerType type); |
281 | 285 |
282 // Call stub given the number of arguments it expects on (and | 286 // Call stub given the number of arguments it expects on (and |
283 // removes from) the stack. | 287 // removes from) the stack. |
284 Result CallStub(CodeStub* stub, int arg_count) { | 288 Result CallStub(CodeStub* stub, int arg_count) { |
285 PrepareForCall(arg_count, arg_count); | 289 PrepareForCall(arg_count, arg_count); |
286 return RawCallStub(stub); | 290 return RawCallStub(stub); |
287 } | 291 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 void Nip(int num_dropped); | 371 void Nip(int num_dropped); |
368 | 372 |
369 private: | 373 private: |
370 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; | 374 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; |
371 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; | 375 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; |
372 static const int kContextOffset = StandardFrameConstants::kContextOffset; | 376 static const int kContextOffset = StandardFrameConstants::kContextOffset; |
373 | 377 |
374 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; | 378 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; |
375 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. | 379 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. |
376 | 380 |
377 CodeGenerator* cgen_; | |
378 MacroAssembler* masm_; | |
379 | |
380 ZoneList<FrameElement> elements_; | 381 ZoneList<FrameElement> elements_; |
381 | 382 |
382 // The number of frame-allocated locals and parameters respectively. | |
383 int parameter_count_; | |
384 int local_count_; | |
385 | |
386 // The index of the element that is at the processor's stack pointer | 383 // The index of the element that is at the processor's stack pointer |
387 // (the sp register). | 384 // (the sp register). |
388 int stack_pointer_; | 385 int stack_pointer_; |
389 | 386 |
390 // The index of the element that is at the processor's frame pointer | |
391 // (the fp register). | |
392 int frame_pointer_; | |
393 | |
394 // The index of the register frame element using each register, or | 387 // The index of the register frame element using each register, or |
395 // kIllegalIndex if a register is not on the frame. | 388 // kIllegalIndex if a register is not on the frame. |
396 int register_locations_[kNumRegisters]; | 389 int register_locations_[kNumRegisters]; |
397 | 390 |
| 391 // The number of frame-allocated locals and parameters respectively. |
| 392 int parameter_count() { return cgen()->scope()->num_parameters(); } |
| 393 int local_count() { return cgen()->scope()->num_stack_slots(); } |
| 394 |
| 395 // The index of the element that is at the processor's frame pointer |
| 396 // (the fp register). The parameters, receiver, function, and context |
| 397 // are below the frame pointer. |
| 398 int frame_pointer() { return parameter_count() + 3; } |
| 399 |
398 // The index of the first parameter. The receiver lies below the first | 400 // The index of the first parameter. The receiver lies below the first |
399 // parameter. | 401 // parameter. |
400 int param0_index() const { return 1; } | 402 int param0_index() { return 1; } |
401 | 403 |
402 // The index of the context slot in the frame. | 404 // The index of the context slot in the frame. It is immediately |
403 int context_index() const { | 405 // below the frame pointer. |
404 ASSERT(frame_pointer_ != kIllegalIndex); | 406 int context_index() { return frame_pointer() - 1; } |
405 return frame_pointer_ - 1; | |
406 } | |
407 | 407 |
408 // The index of the function slot in the frame. It lies above the context | 408 // The index of the function slot in the frame. It is below the frame |
409 // slot. | 409 // pointer and context slot. |
410 int function_index() const { | 410 int function_index() { return frame_pointer() - 2; } |
411 ASSERT(frame_pointer_ != kIllegalIndex); | |
412 return frame_pointer_ - 2; | |
413 } | |
414 | 411 |
415 // The index of the first local. Between the parameters and the locals | 412 // The index of the first local. Between the frame pointer and the |
416 // lie the return address, the saved frame pointer, the context, and the | 413 // locals lies the return address. |
417 // function. | 414 int local0_index() { return frame_pointer() + 2; } |
418 int local0_index() const { | |
419 ASSERT(frame_pointer_ != kIllegalIndex); | |
420 return frame_pointer_ + 2; | |
421 } | |
422 | 415 |
423 // The index of the base of the expression stack. | 416 // The index of the base of the expression stack. |
424 int expression_base_index() const { return local0_index() + local_count_; } | 417 int expression_base_index() { return local0_index() + local_count(); } |
425 | 418 |
426 // Convert a frame index into a frame pointer relative offset into the | 419 // Convert a frame index into a frame pointer relative offset into the |
427 // actual stack. | 420 // actual stack. |
428 int fp_relative(int index) const { | 421 int fp_relative(int index) { |
429 return (frame_pointer_ - index) * kPointerSize; | 422 ASSERT(index < elements_.length()); |
| 423 ASSERT(frame_pointer() < elements_.length()); // FP is on the frame. |
| 424 return (frame_pointer() - index) * kPointerSize; |
430 } | 425 } |
431 | 426 |
432 // Record an occurrence of a register in the virtual frame. This has the | 427 // Record an occurrence of a register in the virtual frame. This has the |
433 // effect of incrementing the register's external reference count and | 428 // effect of incrementing the register's external reference count and |
434 // of updating the index of the register's location in the frame. | 429 // of updating the index of the register's location in the frame. |
435 void Use(Register reg, int index) { | 430 void Use(Register reg, int index) { |
436 ASSERT(!is_used(reg)); | 431 ASSERT(!is_used(reg)); |
437 register_locations_[reg.code()] = index; | 432 register_locations_[reg.code()] = index; |
438 cgen_->allocator()->Use(reg); | 433 cgen()->allocator()->Use(reg); |
439 } | 434 } |
440 | 435 |
441 // Record that a register reference has been dropped from the frame. This | 436 // Record that a register reference has been dropped from the frame. This |
442 // decrements the register's external reference count and invalidates the | 437 // decrements the register's external reference count and invalidates the |
443 // index of the register's location in the frame. | 438 // index of the register's location in the frame. |
444 void Unuse(Register reg) { | 439 void Unuse(Register reg) { |
445 ASSERT(register_locations_[reg.code()] != kIllegalIndex); | 440 ASSERT(register_locations_[reg.code()] != kIllegalIndex); |
446 register_locations_[reg.code()] = kIllegalIndex; | 441 register_locations_[reg.code()] = kIllegalIndex; |
447 cgen_->allocator()->Unuse(reg); | 442 cgen()->allocator()->Unuse(reg); |
448 } | 443 } |
449 | 444 |
450 // Spill the element at a particular index---write it to memory if | 445 // Spill the element at a particular index---write it to memory if |
451 // necessary, free any associated register, and forget its value if | 446 // necessary, free any associated register, and forget its value if |
452 // constant. | 447 // constant. |
453 void SpillElementAt(int index); | 448 void SpillElementAt(int index); |
454 | 449 |
455 // Sync the element at a particular index. If it is a register or | 450 // Sync the element at a particular index. If it is a register or |
456 // constant that disagrees with the value on the stack, write it to memory. | 451 // constant that disagrees with the value on the stack, write it to memory. |
457 // Keep the element type as register or constant, and clear the dirty bit. | 452 // Keep the element type as register or constant, and clear the dirty bit. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 | 516 |
522 bool Equals(VirtualFrame* other); | 517 bool Equals(VirtualFrame* other); |
523 | 518 |
524 friend class JumpTarget; | 519 friend class JumpTarget; |
525 }; | 520 }; |
526 | 521 |
527 | 522 |
528 } } // namespace v8::internal | 523 } } // namespace v8::internal |
529 | 524 |
530 #endif // V8_ARM_VIRTUAL_FRAME_ARM_H_ | 525 #endif // V8_ARM_VIRTUAL_FRAME_ARM_H_ |
OLD | NEW |