| 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_IA32_VIRTUAL_FRAME_IA32_H_ | 28 #ifndef V8_IA32_VIRTUAL_FRAME_IA32_H_ |
| 29 #define V8_IA32_VIRTUAL_FRAME_IA32_H_ | 29 #define V8_IA32_VIRTUAL_FRAME_IA32_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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 // Make this virtual frame have a state identical to an expected virtual | 149 // Make this virtual frame have a state identical to an expected virtual |
| 147 // frame. As a side effect, code may be emitted to make this frame match | 150 // frame. As a side effect, code may be emitted to make this frame match |
| 148 // the expected one. | 151 // the expected one. |
| 149 void MergeTo(VirtualFrame* expected); | 152 void MergeTo(VirtualFrame* expected); |
| 150 | 153 |
| 151 // Detach a frame from its code generator, perhaps temporarily. This | 154 // Detach a frame from its code generator, perhaps temporarily. This |
| 152 // tells the register allocator that it is free to use frame-internal | 155 // tells the register allocator that it is free to use frame-internal |
| 153 // registers. Used when the code generator's frame is switched from this | 156 // registers. Used when the code generator's frame is switched from this |
| 154 // one to NULL by an unconditional jump. | 157 // one to NULL by an unconditional jump. |
| 155 void DetachFromCodeGenerator() { | 158 void DetachFromCodeGenerator() { |
| 156 RegisterAllocator* cgen_allocator = cgen_->allocator(); | 159 RegisterAllocator* cgen_allocator = cgen()->allocator(); |
| 157 for (int i = 0; i < kNumRegisters; i++) { | 160 for (int i = 0; i < kNumRegisters; i++) { |
| 158 if (is_used(i)) { | 161 if (is_used(i)) { |
| 159 Register temp = { i }; | 162 Register temp = { i }; |
| 160 cgen_allocator->Unuse(temp); | 163 cgen_allocator->Unuse(temp); |
| 161 } | 164 } |
| 162 } | 165 } |
| 163 } | 166 } |
| 164 | 167 |
| 165 // (Re)attach a frame to its code generator. This informs the register | 168 // (Re)attach a frame to its code generator. This informs the register |
| 166 // allocator that the frame-internal register references are active again. | 169 // allocator that the frame-internal register references are active again. |
| 167 // Used when a code generator's frame is switched from NULL to this one by | 170 // Used when a code generator's frame is switched from NULL to this one by |
| 168 // binding a label. | 171 // binding a label. |
| 169 void AttachToCodeGenerator() { | 172 void AttachToCodeGenerator() { |
| 170 RegisterAllocator* cgen_allocator = cgen_->allocator(); | 173 RegisterAllocator* cgen_allocator = cgen()->allocator(); |
| 171 for (int i = 0; i < kNumRegisters; i++) { | 174 for (int i = 0; i < kNumRegisters; i++) { |
| 172 if (is_used(i)) { | 175 if (is_used(i)) { |
| 173 Register temp = { i }; | 176 Register temp = { i }; |
| 174 cgen_allocator->Use(temp); | 177 cgen_allocator->Use(temp); |
| 175 } | 178 } |
| 176 } | 179 } |
| 177 } | 180 } |
| 178 | 181 |
| 179 // Emit code for the physical JS entry and exit frame sequences. After | 182 // Emit code for the physical JS entry and exit frame sequences. After |
| 180 // calling Enter, the virtual frame is ready for use; and after calling | 183 // calling Enter, the virtual frame is ready for use; and after calling |
| 181 // Exit it should not be used. Note that Enter does not allocate space in | 184 // Exit it should not be used. Note that Enter does not allocate space in |
| 182 // the physical frame for storing frame-allocated locals. | 185 // the physical frame for storing frame-allocated locals. |
| 183 void Enter(); | 186 void Enter(); |
| 184 void Exit(); | 187 void Exit(); |
| 185 | 188 |
| 186 // Prepare for returning from the frame by spilling locals. This | 189 // Prepare for returning from the frame by spilling locals. This |
| 187 // avoids generating unnecessary merge code when jumping to the | 190 // avoids generating unnecessary merge code when jumping to the |
| 188 // shared return site. Emits code for spills. | 191 // shared return site. Emits code for spills. |
| 189 void PrepareForReturn(); | 192 void PrepareForReturn(); |
| 190 | 193 |
| 191 // Allocate and initialize the frame-allocated locals. | 194 // Allocate and initialize the frame-allocated locals. |
| 192 void AllocateStackSlots(int count); | 195 void AllocateStackSlots(); |
| 193 | 196 |
| 194 // An element of the expression stack as an assembly operand. | 197 // An element of the expression stack as an assembly operand. |
| 195 Operand ElementAt(int index) const { | 198 Operand ElementAt(int index) const { |
| 196 return Operand(esp, index * kPointerSize); | 199 return Operand(esp, index * kPointerSize); |
| 197 } | 200 } |
| 198 | 201 |
| 199 // Random-access store to a frame-top relative frame element. The result | 202 // Random-access store to a frame-top relative frame element. The result |
| 200 // becomes owned by the frame and is invalidated. | 203 // becomes owned by the frame and is invalidated. |
| 201 void SetElementAt(int index, Result* value); | 204 void SetElementAt(int index, Result* value); |
| 202 | 205 |
| 203 // Set a frame element to a constant. The index is frame-top relative. | 206 // Set a frame element to a constant. The index is frame-top relative. |
| 204 void SetElementAt(int index, Handle<Object> value) { | 207 void SetElementAt(int index, Handle<Object> value) { |
| 205 Result temp(value); | 208 Result temp(value); |
| 206 SetElementAt(index, &temp); | 209 SetElementAt(index, &temp); |
| 207 } | 210 } |
| 208 | 211 |
| 209 void PushElementAt(int index) { | 212 void PushElementAt(int index) { |
| 210 PushFrameSlotAt(elements_.length() - index - 1); | 213 PushFrameSlotAt(elements_.length() - index - 1); |
| 211 } | 214 } |
| 212 | 215 |
| 213 void StoreToElementAt(int index) { | 216 void StoreToElementAt(int index) { |
| 214 StoreToFrameSlotAt(elements_.length() - index - 1); | 217 StoreToFrameSlotAt(elements_.length() - index - 1); |
| 215 } | 218 } |
| 216 | 219 |
| 217 // A frame-allocated local as an assembly operand. | 220 // A frame-allocated local as an assembly operand. |
| 218 Operand LocalAt(int index) const { | 221 Operand LocalAt(int index) { |
| 219 ASSERT(0 <= index); | 222 ASSERT(0 <= index); |
| 220 ASSERT(index < local_count_); | 223 ASSERT(index < local_count()); |
| 221 return Operand(ebp, kLocal0Offset - index * kPointerSize); | 224 return Operand(ebp, kLocal0Offset - index * kPointerSize); |
| 222 } | 225 } |
| 223 | 226 |
| 224 // Push a copy of the value of a local frame slot on top of the frame. | 227 // Push a copy of the value of a local frame slot on top of the frame. |
| 225 void PushLocalAt(int index) { | 228 void PushLocalAt(int index) { |
| 226 PushFrameSlotAt(local0_index() + index); | 229 PushFrameSlotAt(local0_index() + index); |
| 227 } | 230 } |
| 228 | 231 |
| 229 // Push the value of a local frame slot on top of the frame and invalidate | 232 // Push the value of a local frame slot on top of the frame and invalidate |
| 230 // the local slot. The slot should be written to before trying to read | 233 // the local slot. The slot should be written to before trying to read |
| (...skipping 15 matching lines...) Expand all Loading... |
| 246 void PushFunction() { PushFrameSlotAt(function_index()); } | 249 void PushFunction() { PushFrameSlotAt(function_index()); } |
| 247 | 250 |
| 248 // Save the value of the esi register to the context frame slot. | 251 // Save the value of the esi register to the context frame slot. |
| 249 void SaveContextRegister(); | 252 void SaveContextRegister(); |
| 250 | 253 |
| 251 // Restore the esi register from the value of the context frame | 254 // Restore the esi register from the value of the context frame |
| 252 // slot. | 255 // slot. |
| 253 void RestoreContextRegister(); | 256 void RestoreContextRegister(); |
| 254 | 257 |
| 255 // A parameter as an assembly operand. | 258 // A parameter as an assembly operand. |
| 256 Operand ParameterAt(int index) const { | 259 Operand ParameterAt(int index) { |
| 257 ASSERT(-1 <= index); // -1 is the receiver. | 260 ASSERT(-1 <= index); // -1 is the receiver. |
| 258 ASSERT(index < parameter_count_); | 261 ASSERT(index <= parameter_count()); |
| 259 return Operand(ebp, (1 + parameter_count_ - index) * kPointerSize); | 262 return Operand(ebp, (1 + parameter_count() - index) * kPointerSize); |
| 260 } | 263 } |
| 261 | 264 |
| 262 // Push a copy of the value of a parameter frame slot on top of the frame. | 265 // Push a copy of the value of a parameter frame slot on top of the frame. |
| 263 void PushParameterAt(int index) { | 266 void PushParameterAt(int index) { |
| 264 PushFrameSlotAt(param0_index() + index); | 267 PushFrameSlotAt(param0_index() + index); |
| 265 } | 268 } |
| 266 | 269 |
| 267 // Push the value of a paramter frame slot on top of the frame and | 270 // Push the value of a paramter frame slot on top of the frame and |
| 268 // invalidate the parameter slot. The slot should be written to before | 271 // invalidate the parameter slot. The slot should be written to before |
| 269 // trying to read from it again. | 272 // trying to read from it again. |
| 270 void TakeParameterAt(int index) { | 273 void TakeParameterAt(int index) { |
| 271 TakeFrameSlotAt(param0_index() + index); | 274 TakeFrameSlotAt(param0_index() + index); |
| 272 } | 275 } |
| 273 | 276 |
| 274 // Store the top value on the virtual frame into a parameter frame slot. | 277 // Store the top value on the virtual frame into a parameter frame slot. |
| 275 // The value is left in place on top of the frame. | 278 // The value is left in place on top of the frame. |
| 276 void StoreToParameterAt(int index) { | 279 void StoreToParameterAt(int index) { |
| 277 StoreToFrameSlotAt(param0_index() + index); | 280 StoreToFrameSlotAt(param0_index() + index); |
| 278 } | 281 } |
| 279 | 282 |
| 280 // The receiver frame slot. | 283 // The receiver frame slot. |
| 281 Operand Receiver() const { return ParameterAt(-1); } | 284 Operand Receiver() { return ParameterAt(-1); } |
| 282 | 285 |
| 283 // Push a try-catch or try-finally handler on top of the virtual frame. | 286 // Push a try-catch or try-finally handler on top of the virtual frame. |
| 284 void PushTryHandler(HandlerType type); | 287 void PushTryHandler(HandlerType type); |
| 285 | 288 |
| 286 // Call stub given the number of arguments it expects on (and | 289 // Call stub given the number of arguments it expects on (and |
| 287 // removes from) the stack. | 290 // removes from) the stack. |
| 288 Result CallStub(CodeStub* stub, int arg_count) { | 291 Result CallStub(CodeStub* stub, int arg_count) { |
| 289 PrepareForCall(arg_count, arg_count); | 292 PrepareForCall(arg_count, arg_count); |
| 290 return RawCallStub(stub); | 293 return RawCallStub(stub); |
| 291 } | 294 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 void Nip(int num_dropped); | 391 void Nip(int num_dropped); |
| 389 | 392 |
| 390 private: | 393 private: |
| 391 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; | 394 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; |
| 392 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; | 395 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; |
| 393 static const int kContextOffset = StandardFrameConstants::kContextOffset; | 396 static const int kContextOffset = StandardFrameConstants::kContextOffset; |
| 394 | 397 |
| 395 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; | 398 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; |
| 396 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. | 399 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. |
| 397 | 400 |
| 398 CodeGenerator* cgen_; | |
| 399 MacroAssembler* masm_; | |
| 400 | |
| 401 ZoneList<FrameElement> elements_; | 401 ZoneList<FrameElement> elements_; |
| 402 | 402 |
| 403 // The number of frame-allocated locals and parameters respectively. | |
| 404 int parameter_count_; | |
| 405 int local_count_; | |
| 406 | |
| 407 // The index of the element that is at the processor's stack pointer | 403 // The index of the element that is at the processor's stack pointer |
| 408 // (the esp register). | 404 // (the esp register). |
| 409 int stack_pointer_; | 405 int stack_pointer_; |
| 410 | 406 |
| 411 // The index of the element that is at the processor's frame pointer | |
| 412 // (the ebp register). | |
| 413 int frame_pointer_; | |
| 414 | |
| 415 // The index of the register frame element using each register, or | 407 // The index of the register frame element using each register, or |
| 416 // kIllegalIndex if a register is not on the frame. | 408 // kIllegalIndex if a register is not on the frame. |
| 417 int register_locations_[kNumRegisters]; | 409 int register_locations_[kNumRegisters]; |
| 418 | 410 |
| 411 // The number of frame-allocated locals and parameters respectively. |
| 412 int parameter_count() { return cgen()->scope()->num_parameters(); } |
| 413 int local_count() { return cgen()->scope()->num_stack_slots(); } |
| 414 |
| 415 // The index of the element that is at the processor's frame pointer |
| 416 // (the ebp register). The parameters, receiver, and return address |
| 417 // are below the frame pointer. |
| 418 int frame_pointer() { return parameter_count() + 2; } |
| 419 |
| 419 // The index of the first parameter. The receiver lies below the first | 420 // The index of the first parameter. The receiver lies below the first |
| 420 // parameter. | 421 // parameter. |
| 421 int param0_index() const { return 1; } | 422 int param0_index() { return 1; } |
| 422 | 423 |
| 423 // The index of the context slot in the frame. | 424 // The index of the context slot in the frame. It is immediately |
| 424 int context_index() const { | 425 // above the frame pointer. |
| 425 ASSERT(frame_pointer_ != kIllegalIndex); | 426 int context_index() { return frame_pointer() + 1; } |
| 426 return frame_pointer_ + 1; | |
| 427 } | |
| 428 | 427 |
| 429 // The index of the function slot in the frame. It lies above the context | 428 // The index of the function slot in the frame. It is above the frame |
| 430 // slot. | 429 // pointer and the context slot. |
| 431 int function_index() const { | 430 int function_index() { return frame_pointer() + 2; } |
| 432 ASSERT(frame_pointer_ != kIllegalIndex); | |
| 433 return frame_pointer_ + 2; | |
| 434 } | |
| 435 | 431 |
| 436 // The index of the first local. Between the parameters and the locals | 432 // The index of the first local. Between the frame pointer and the |
| 437 // lie the return address, the saved frame pointer, the context, and the | 433 // locals lie the context and the function. |
| 438 // function. | 434 int local0_index() { return frame_pointer() + 3; } |
| 439 int local0_index() const { | |
| 440 ASSERT(frame_pointer_ != kIllegalIndex); | |
| 441 return frame_pointer_ + 3; | |
| 442 } | |
| 443 | 435 |
| 444 // The index of the base of the expression stack. | 436 // The index of the base of the expression stack. |
| 445 int expression_base_index() const { return local0_index() + local_count_; } | 437 int expression_base_index() { return local0_index() + local_count(); } |
| 446 | 438 |
| 447 // Convert a frame index into a frame pointer relative offset into the | 439 // Convert a frame index into a frame pointer relative offset into the |
| 448 // actual stack. | 440 // actual stack. |
| 449 int fp_relative(int index) const { | 441 int fp_relative(int index) { |
| 450 return (frame_pointer_ - index) * kPointerSize; | 442 ASSERT(index < elements_.length()); |
| 443 ASSERT(frame_pointer() < elements_.length()); // FP is on the frame. |
| 444 return (frame_pointer() - index) * kPointerSize; |
| 451 } | 445 } |
| 452 | 446 |
| 453 // Record an occurrence of a register in the virtual frame. This has the | 447 // Record an occurrence of a register in the virtual frame. This has the |
| 454 // effect of incrementing the register's external reference count and | 448 // effect of incrementing the register's external reference count and |
| 455 // of updating the index of the register's location in the frame. | 449 // of updating the index of the register's location in the frame. |
| 456 void Use(Register reg, int index) { | 450 void Use(Register reg, int index) { |
| 457 ASSERT(!is_used(reg)); | 451 ASSERT(!is_used(reg)); |
| 458 register_locations_[reg.code()] = index; | 452 register_locations_[reg.code()] = index; |
| 459 cgen_->allocator()->Use(reg); | 453 cgen()->allocator()->Use(reg); |
| 460 } | 454 } |
| 461 | 455 |
| 462 // Record that a register reference has been dropped from the frame. This | 456 // Record that a register reference has been dropped from the frame. This |
| 463 // decrements the register's external reference count and invalidates the | 457 // decrements the register's external reference count and invalidates the |
| 464 // index of the register's location in the frame. | 458 // index of the register's location in the frame. |
| 465 void Unuse(Register reg) { | 459 void Unuse(Register reg) { |
| 466 ASSERT(register_locations_[reg.code()] != kIllegalIndex); | 460 ASSERT(register_locations_[reg.code()] != kIllegalIndex); |
| 467 register_locations_[reg.code()] = kIllegalIndex; | 461 register_locations_[reg.code()] = kIllegalIndex; |
| 468 cgen_->allocator()->Unuse(reg); | 462 cgen()->allocator()->Unuse(reg); |
| 469 } | 463 } |
| 470 | 464 |
| 471 // Spill the element at a particular index---write it to memory if | 465 // Spill the element at a particular index---write it to memory if |
| 472 // necessary, free any associated register, and forget its value if | 466 // necessary, free any associated register, and forget its value if |
| 473 // constant. | 467 // constant. |
| 474 void SpillElementAt(int index); | 468 void SpillElementAt(int index); |
| 475 | 469 |
| 476 // Sync the element at a particular index. If it is a register or | 470 // Sync the element at a particular index. If it is a register or |
| 477 // constant that disagrees with the value on the stack, write it to memory. | 471 // constant that disagrees with the value on the stack, write it to memory. |
| 478 // Keep the element type as register or constant, and clear the dirty bit. | 472 // Keep the element type as register or constant, and clear the dirty bit. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 | 532 |
| 539 // Calls a code object which has already been prepared for calling | 533 // Calls a code object which has already been prepared for calling |
| 540 // (via PrepareForCall). | 534 // (via PrepareForCall). |
| 541 Result RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode); | 535 Result RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode); |
| 542 | 536 |
| 543 bool Equals(VirtualFrame* other); | 537 bool Equals(VirtualFrame* other); |
| 544 | 538 |
| 545 friend class JumpTarget; | 539 friend class JumpTarget; |
| 546 }; | 540 }; |
| 547 | 541 |
| 542 |
| 548 } } // namespace v8::internal | 543 } } // namespace v8::internal |
| 549 | 544 |
| 550 #endif // V8_IA32_VIRTUAL_FRAME_IA32_H_ | 545 #endif // V8_IA32_VIRTUAL_FRAME_IA32_H_ |
| OLD | NEW |