| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 | 100 |
| 101 void clear_sync() { | 101 void clear_sync() { |
| 102 ASSERT(type() != MEMORY); | 102 ASSERT(type() != MEMORY); |
| 103 type_ = (type_ & ~SyncField::mask()) | SyncField::encode(NOT_SYNCED); | 103 type_ = (type_ & ~SyncField::mask()) | SyncField::encode(NOT_SYNCED); |
| 104 } | 104 } |
| 105 | 105 |
| 106 bool is_valid() const { return type() != INVALID; } | 106 bool is_valid() const { return type() != INVALID; } |
| 107 bool is_memory() const { return type() == MEMORY; } | 107 bool is_memory() const { return type() == MEMORY; } |
| 108 bool is_register() const { return type() == REGISTER; } | 108 bool is_register() const { return type() == REGISTER; } |
| 109 bool is_constant() const { return type() == CONSTANT; } | 109 bool is_constant() const { return type() == CONSTANT; } |
| 110 bool is_copy() const { return type() == COPY; } |
| 110 | 111 |
| 111 Register reg() const { | 112 Register reg() const { |
| 112 ASSERT(type() == REGISTER); | 113 ASSERT(is_register()); |
| 113 return data_.reg_; | 114 return data_.reg_; |
| 114 } | 115 } |
| 115 | 116 |
| 116 Handle<Object> handle() const { | 117 Handle<Object> handle() const { |
| 117 ASSERT(type() == CONSTANT); | 118 ASSERT(is_constant()); |
| 118 return Handle<Object>(data_.handle_); | 119 return Handle<Object>(data_.handle_); |
| 119 } | 120 } |
| 120 | 121 |
| 122 int index() const { |
| 123 ASSERT(is_copy()); |
| 124 return data_.index_; |
| 125 } |
| 126 |
| 121 private: | 127 private: |
| 122 enum Type { | 128 enum Type { |
| 123 INVALID, | 129 INVALID, |
| 124 MEMORY, | 130 MEMORY, |
| 125 REGISTER, | 131 REGISTER, |
| 126 CONSTANT | 132 CONSTANT, |
| 133 COPY |
| 127 }; | 134 }; |
| 128 | 135 |
| 129 // BitField is <type, shift, size>. | 136 // BitField is <type, shift, size>. |
| 130 class SyncField : public BitField<SyncFlag, 0, 1> {}; | 137 class SyncField : public BitField<SyncFlag, 0, 1> {}; |
| 131 class TypeField : public BitField<Type, 1, 32 - 1> {}; | 138 class TypeField : public BitField<Type, 1, 32 - 1> {}; |
| 132 | 139 |
| 133 Type type() const { return TypeField::decode(type_); } | 140 Type type() const { return TypeField::decode(type_); } |
| 134 | 141 |
| 135 // The element's type and a dirty bit. The dirty bit can be cleared | 142 // The element's type and a dirty bit. The dirty bit can be cleared |
| 136 // for non-memory elements to indicate that the element agrees with | 143 // for non-memory elements to indicate that the element agrees with |
| 137 // the value in memory in the actual frame. | 144 // the value in memory in the actual frame. |
| 138 int type_; | 145 int type_; |
| 139 | 146 |
| 140 union { | 147 union { |
| 141 Register reg_; | 148 Register reg_; |
| 142 Object** handle_; | 149 Object** handle_; |
| 150 int index_; |
| 143 } data_; | 151 } data_; |
| 152 |
| 153 friend class VirtualFrame; |
| 144 }; | 154 }; |
| 145 | 155 |
| 146 | 156 |
| 147 // ------------------------------------------------------------------------- | 157 // ------------------------------------------------------------------------- |
| 148 // Virtual frames | 158 // Virtual frames |
| 149 // | 159 // |
| 150 // The virtual frame is an abstraction of the physical stack frame. It | 160 // The virtual frame is an abstraction of the physical stack frame. It |
| 151 // encapsulates the parameters, frame-allocated locals, and the expression | 161 // encapsulates the parameters, frame-allocated locals, and the expression |
| 152 // stack. It supports push/pop operations on the expression stack, as well | 162 // stack. It supports push/pop operations on the expression stack, as well |
| 153 // as random access to the expression stack elements, locals, and | 163 // as random access to the expression stack elements, locals, and |
| (...skipping 16 matching lines...) Expand all Loading... |
| 170 CodeGenerator* cgen_; | 180 CodeGenerator* cgen_; |
| 171 bool previous_state_; | 181 bool previous_state_; |
| 172 }; | 182 }; |
| 173 | 183 |
| 174 // Construct an initial virtual frame on entry to a JS function. | 184 // Construct an initial virtual frame on entry to a JS function. |
| 175 explicit VirtualFrame(CodeGenerator* cgen); | 185 explicit VirtualFrame(CodeGenerator* cgen); |
| 176 | 186 |
| 177 // Construct a virtual frame as a clone of an existing one. | 187 // Construct a virtual frame as a clone of an existing one. |
| 178 explicit VirtualFrame(VirtualFrame* original); | 188 explicit VirtualFrame(VirtualFrame* original); |
| 179 | 189 |
| 190 // Create a duplicate of an existing valid frame element. |
| 191 FrameElement CopyElementAt(int index); |
| 192 |
| 180 // The height of the virtual expression stack. | 193 // The height of the virtual expression stack. |
| 181 int height() const { | 194 int height() const { |
| 182 return elements_.length() - expression_base_index(); | 195 return elements_.length() - expression_base_index(); |
| 183 } | 196 } |
| 184 | 197 |
| 185 int register_count(Register reg) { | 198 int register_count(Register reg) { |
| 186 return frame_registers_.count(reg); | 199 return frame_registers_.count(reg); |
| 187 } | 200 } |
| 188 | 201 |
| 189 // Add extra in-memory elements to the top of the frame to match an actual | 202 // Add extra in-memory elements to the top of the frame to match an actual |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 504 |
| 492 // Record that a register reference has been dropped from the frame. This | 505 // Record that a register reference has been dropped from the frame. This |
| 493 // decrements both the register's internal and external reference counts. | 506 // decrements both the register's internal and external reference counts. |
| 494 void Unuse(Register reg); | 507 void Unuse(Register reg); |
| 495 | 508 |
| 496 // Spill the element at a particular index---write it to memory if | 509 // Spill the element at a particular index---write it to memory if |
| 497 // necessary, free any associated register, and forget its value if | 510 // necessary, free any associated register, and forget its value if |
| 498 // constant. | 511 // constant. |
| 499 void SpillElementAt(int index); | 512 void SpillElementAt(int index); |
| 500 | 513 |
| 501 // Spill the element at an index without modifying its reference count (if | |
| 502 // it was in a register). | |
| 503 void RawSpillElementAt(int index); | |
| 504 | |
| 505 // Sync the element at a particular index. If it is a register or | 514 // Sync the element at a particular index. If it is a register or |
| 506 // constant that disagrees with the value on the stack, write it to memory. | 515 // constant that disagrees with the value on the stack, write it to memory. |
| 507 // Keep the element type as register or constant, and clear the dirty bit. | 516 // Keep the element type as register or constant, and clear the dirty bit. |
| 508 void SyncElementAt(int index); | 517 void SyncElementAt(int index); |
| 509 | 518 |
| 510 // Sync the range of elements in [begin, end). | 519 // Sync the range of elements in [begin, end). |
| 511 void SyncRange(int begin, int end); | 520 void SyncRange(int begin, int end); |
| 512 | 521 |
| 513 // Sync a single element, assuming that its index is less than | 522 // Sync a single element, assuming that its index is less than |
| 514 // or equal to stack pointer + 1. | 523 // or equal to stack pointer + 1. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 545 // Used in the implementation of MergeTo(). | 554 // Used in the implementation of MergeTo(). |
| 546 void MergeMoveRegistersToRegisters(VirtualFrame* expected); | 555 void MergeMoveRegistersToRegisters(VirtualFrame* expected); |
| 547 | 556 |
| 548 // Make the memory-to-register and constant-to-register moves | 557 // Make the memory-to-register and constant-to-register moves |
| 549 // needed to make this frame equal the expected frame. | 558 // needed to make this frame equal the expected frame. |
| 550 // Called after all register-to-memory and register-to-register | 559 // Called after all register-to-memory and register-to-register |
| 551 // moves have been made. After this function returns, the frames | 560 // moves have been made. After this function returns, the frames |
| 552 // should be equal. | 561 // should be equal. |
| 553 void MergeMoveMemoryToRegisters(VirtualFrame* expected); | 562 void MergeMoveMemoryToRegisters(VirtualFrame* expected); |
| 554 | 563 |
| 555 // Calls a code object which takes spilled_args frame arguments | 564 // Helper function to implement the copy-on-write semantics of an |
| 556 // and which drops dropped_args of them. | 565 // element's copies just before writing to the element. The copies |
| 557 Result RawCallCodeObject(Handle<Code> code, | 566 // are updated, but the element is not changed. A copy of the new |
| 558 RelocInfo::Mode rmode, | 567 // backing store of all the copies is returned if there were any |
| 559 int spilled_args, | 568 // copies and in invalid frame element is returned if there were no |
| 560 int dropped_args); | 569 // copies. |
| 570 FrameElement AdjustCopies(int index); |
| 571 |
| 572 // Call a code stub that has already been prepared for calling (via |
| 573 // PrepareForCall). |
| 574 Result RawCallStub(CodeStub* stub, int frame_arg_count); |
| 575 |
| 576 // Calls a code object which has already been prepared for calling |
| 577 // (via PrepareForCall). |
| 578 Result RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode); |
| 561 }; | 579 }; |
| 562 | 580 |
| 563 } } // namespace v8::internal | 581 } } // namespace v8::internal |
| 564 | 582 |
| 565 #endif // V8_VIRTUAL_FRAME_IA32_H_ | 583 #endif // V8_VIRTUAL_FRAME_IA32_H_ |
| OLD | NEW |