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

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

Issue 11396: Begin counting references to registers, both in the frame and out.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 12 years 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
« no previous file with comments | « src/register-allocator-ia32.cc ('k') | src/virtual-frame-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11 matching lines...) Expand all
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_VIRTUAL_FRAME_IA32_H_ 28 #ifndef V8_VIRTUAL_FRAME_IA32_H_
29 #define V8_VIRTUAL_FRAME_IA32_H_ 29 #define V8_VIRTUAL_FRAME_IA32_H_
30 30
31 #include "macro-assembler.h" 31 #include "macro-assembler.h"
32 #include "register-allocator.h"
32 33
33 namespace v8 { namespace internal { 34 namespace v8 { namespace internal {
34 35
35 // ------------------------------------------------------------------------- 36 // -------------------------------------------------------------------------
36 // Virtual frame elements 37 // Virtual frame elements
37 // 38 //
38 // The internal elements of the virtual frames. Elements are (currently) of 39 // The internal elements of the virtual frames. There are several kinds of
39 // only one kind, in-memory. Their actual location is given by their 40 // elements:
40 // position in the virtual frame. 41 // * Memory: an element that resides in the actual frame. Its address is
42 // given by its position in the virtual frame.
43 // * Register: an element that resides in a register.
44 // * Constant: an element whose value is known at compile time.
41 45
42 class FrameElement BASE_EMBEDDED { 46 class FrameElement BASE_EMBEDDED {
43 public: 47 public:
48 enum SyncFlag { SYNCED, NOT_SYNCED };
49
50 // Construct an in-memory frame element.
44 FrameElement() { 51 FrameElement() {
45 type_ = TypeField::encode(MEMORY) | DirtyField::encode(false); 52 type_ = TypeField::encode(MEMORY) | SyncField::encode(SYNCED);
46 // Memory elements have no useful data. 53 // In-memory elements have no useful data.
47 data_.reg_ = no_reg; 54 data_.reg_ = no_reg;
48 } 55 }
49 56
50 explicit FrameElement(Register reg) { 57 // Construct an in-register frame element.
51 type_ = TypeField::encode(REGISTER) | DirtyField::encode(true); 58 FrameElement(Register reg, SyncFlag is_synced) {
59 type_ = TypeField::encode(REGISTER) | SyncField::encode(is_synced);
52 data_.reg_ = reg; 60 data_.reg_ = reg;
53 } 61 }
54 62
55 explicit FrameElement(Handle<Object> value) { 63 // Construct a frame element whose value is known at compile time.
56 type_ = TypeField::encode(CONSTANT) | DirtyField::encode(true); 64 FrameElement(Handle<Object> value, SyncFlag is_synced) {
65 type_ = TypeField::encode(CONSTANT) | SyncField::encode(is_synced);
57 data_.handle_ = value.location(); 66 data_.handle_ = value.location();
58 } 67 }
59 68
60 bool is_dirty() const { return DirtyField::decode(type_); } 69 bool is_synced() const { return SyncField::decode(type_) == SYNCED; }
61 70
62 void set_dirty() { 71 void set_sync() {
63 ASSERT(type() != MEMORY); 72 ASSERT(type() != MEMORY);
64 type_ = type_ | DirtyField::encode(true); 73 type_ = type_ | SyncField::encode(SYNCED);
65 } 74 }
66 75
67 void clear_dirty() { 76 void clear_sync() {
68 ASSERT(type() != MEMORY); 77 ASSERT(type() != MEMORY);
69 type_ = type_ & ~DirtyField::mask(); 78 type_ = type_ & ~SyncField::mask();
70 } 79 }
71 80
72 bool is_register() const { return type() == REGISTER; } 81 bool is_register() const { return type() == REGISTER; }
73 bool is_constant() const { return type() == CONSTANT; } 82 bool is_constant() const { return type() == CONSTANT; }
74 83
75 Register reg() const { 84 Register reg() const {
76 ASSERT(type() == REGISTER); 85 ASSERT(type() == REGISTER);
77 return data_.reg_; 86 return data_.reg_;
78 } 87 }
79 88
80 Handle<Object> handle() const { 89 Handle<Object> handle() const {
81 ASSERT(type() == CONSTANT); 90 ASSERT(type() == CONSTANT);
82 return Handle<Object>(data_.handle_); 91 return Handle<Object>(data_.handle_);
83 } 92 }
84 93
85 private: 94 private:
86 enum Type { MEMORY, REGISTER, CONSTANT }; 95 enum Type { MEMORY, REGISTER, CONSTANT };
87 96
88 // BitField is <type, shift, size>. 97 // BitField is <type, shift, size>.
89 class DirtyField : public BitField<bool, 0, 1> {}; 98 class SyncField : public BitField<SyncFlag, 0, 1> {};
90 class TypeField : public BitField<Type, 1, 32 - 1> {}; 99 class TypeField : public BitField<Type, 1, 32 - 1> {};
91 100
92 Type type() const { return TypeField::decode(type_); } 101 Type type() const { return TypeField::decode(type_); }
93 102
94 // The element's type and a dirty bit. The dirty bit can be cleared 103 // The element's type and a dirty bit. The dirty bit can be cleared
95 // for non-memory elements to indicate that the element agrees with 104 // for non-memory elements to indicate that the element agrees with
96 // the value in memory in the actual frame. 105 // the value in memory in the actual frame.
97 int type_; 106 int type_;
98 107
99 union { 108 union {
(...skipping 30 matching lines...) Expand all
130 // emitted. 139 // emitted.
131 void Adjust(int count); 140 void Adjust(int count);
132 141
133 // Forget elements from the top of the frame to match an actual frame (eg, 142 // Forget elements from the top of the frame to match an actual frame (eg,
134 // the frame after a runtime call). No code is emitted. 143 // the frame after a runtime call). No code is emitted.
135 void Forget(int count); 144 void Forget(int count);
136 145
137 // Spill all values from the frame to memory. 146 // Spill all values from the frame to memory.
138 void SpillAll(); 147 void SpillAll();
139 148
149 // Spill a register if possible. Return the register spilled or no_reg if
150 // it was not possible to spill one.
151 Register SpillAnyRegister();
152
140 // Ensure that this frame is in a state where an arbitrary frame of the 153 // Ensure that this frame is in a state where an arbitrary frame of the
141 // right size could be merged to it. May emit code. 154 // right size could be merged to it. May emit code.
142 void EnsureMergable(); 155 void EnsureMergable();
143 156
144 // Make this virtual frame have a state identical to an expected virtual 157 // Make this virtual frame have a state identical to an expected virtual
145 // frame. As a side effect, code may be emitted to make this frame match 158 // frame. As a side effect, code may be emitted to make this frame match
146 // the expected one. 159 // the expected one.
147 void MergeTo(VirtualFrame* expected); 160 void MergeTo(VirtualFrame* expected);
148 161
149 // Emit code for the physical JS entry and exit frame sequences. After 162 // Emit code for the physical JS entry and exit frame sequences. After
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 // corresponding pop instruction. 237 // corresponding pop instruction.
225 void EmitPop(Register reg); 238 void EmitPop(Register reg);
226 void EmitPop(Operand operand); 239 void EmitPop(Operand operand);
227 240
228 // Push an element on top of the expression stack and emit a corresponding 241 // Push an element on top of the expression stack and emit a corresponding
229 // push instruction. 242 // push instruction.
230 void EmitPush(Register reg); 243 void EmitPush(Register reg);
231 void EmitPush(Operand operand); 244 void EmitPush(Operand operand);
232 void EmitPush(Immediate immediate); 245 void EmitPush(Immediate immediate);
233 246
247 // Push an element on the virtual frame.
248 void Push(Register reg);
249 void Push(Handle<Object> value);
250
234 private: 251 private:
235 // An illegal index into the virtual frame. 252 // An illegal index into the virtual frame.
236 static const int kIllegalIndex = -1; 253 static const int kIllegalIndex = -1;
237 254
238 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; 255 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
239 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; 256 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
240 static const int kContextOffset = StandardFrameConstants::kContextOffset; 257 static const int kContextOffset = StandardFrameConstants::kContextOffset;
241 258
242 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; 259 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
243 260
261 CodeGenerator* cgen_;
244 MacroAssembler* masm_; 262 MacroAssembler* masm_;
245 263
246 List<FrameElement> elements_; 264 List<FrameElement> elements_;
247 265
248 int parameter_count_; 266 int parameter_count_;
249 int local_count_; 267 int local_count_;
250 268
251 // The index of the element that is at the processor's stack pointer 269 // The index of the element that is at the processor's stack pointer
252 // (the esp register). 270 // (the esp register).
253 int stack_pointer_; 271 int stack_pointer_;
254 272
255 // The index of the element that is at the processor's frame pointer 273 // The index of the element that is at the processor's frame pointer
256 // (the ebp register). 274 // (the ebp register).
257 int frame_pointer_; 275 int frame_pointer_;
258 276
277 // The frame has an embedded register file that it uses to track registers
278 // used in the frame.
279 RegisterFile frame_registers_;
280
259 // The index of the first parameter. The receiver lies below the first 281 // The index of the first parameter. The receiver lies below the first
260 // parameter. 282 // parameter.
261 int param0_index() const { return 1; } 283 int param0_index() const { return 1; }
262 284
285 // The index of the context slot in the frame.
286 int context_index() const {
287 ASSERT(frame_pointer_ != kIllegalIndex);
288 return frame_pointer_ + 1;
289 }
290
291 // The index of the function slot in the frame. It lies above the context
292 // slot.
293 int function_index() const {
294 ASSERT(frame_pointer_ != kIllegalIndex);
295 return frame_pointer_ + 2;
296 }
297
263 // The index of the first local. Between the parameters and the locals 298 // The index of the first local. Between the parameters and the locals
264 // lie the return address, the saved frame pointer, the context, and the 299 // lie the return address, the saved frame pointer, the context, and the
265 // function. 300 // function.
266 int local0_index() const { return param0_index() + parameter_count_ + 4; } 301 int local0_index() const {
302 ASSERT(frame_pointer_ != kIllegalIndex);
303 return frame_pointer_ + 3;
304 }
267 305
268 // The index of the base of the expression stack. 306 // The index of the base of the expression stack.
269 int expression_base_index() const { return local0_index() + local_count_; } 307 int expression_base_index() const { return local0_index() + local_count_; }
270 308
271 // Convert a frame index into a frame pointer relative offset into the 309 // Convert a frame index into a frame pointer relative offset into the
272 // actual stack. 310 // actual stack.
273 int fp_relative(int index) const { 311 int fp_relative(int index) const {
274 return (frame_pointer_ - index) * kPointerSize; 312 return (frame_pointer_ - index) * kPointerSize;
275 } 313 }
276 314
315 // Record an occurrence of a register in the virtual frame. This has the
316 // effect of incrementing both the register's frame-internal reference
317 // count and its external reference count.
318 void Use(Register reg);
319
320 // Record that a register reference has been dropped from the frame. This
321 // decrements both the register's internal and external reference counts.
322 void Unuse(Register reg);
323
277 // Sync the element at a particular index---write it to memory if 324 // Sync the element at a particular index---write it to memory if
278 // necessary, but do not free any associated register or forget its value 325 // necessary, but do not free any associated register or forget its value
279 // if constant. Space should have already been allocated in the actual 326 // if constant. Space should have already been allocated in the actual
280 // frame for all the elements below this one (at least). 327 // frame for all the elements below this one (at least).
281 void SyncElementAt(int index); 328 void SyncElementAt(int index);
282 329
283 // Spill the element at a particular index---write it to memory if 330 // Spill the element at a particular index---write it to memory if
284 // necessary, free any associated register, and forget its value if 331 // necessary, free any associated register, and forget its value if
285 // constant. Space should have already been allocated in the actual frame 332 // constant. Space should have already been allocated in the actual frame
286 // for all the elements below this one (at least). 333 // for all the elements below this one (at least).
287 void SpillElementAt(int index); 334 void SpillElementAt(int index);
288 335
336 // Sync all elements in the frame.
337 void SyncAll();
338
289 // Spill the topmost elements of the frame to memory (eg, they are the 339 // Spill the topmost elements of the frame to memory (eg, they are the
290 // arguments to a call) and all registers. 340 // arguments to a call) and all registers.
291 void PrepareForCall(int count); 341 void PrepareForCall(int count);
292 }; 342 };
293 343
294 344
295 } } // namespace v8::internal 345 } } // namespace v8::internal
296 346
297 #endif // V8_VIRTUAL_FRAME_IA32_H_ 347 #endif // V8_VIRTUAL_FRAME_IA32_H_
OLDNEW
« no previous file with comments | « src/register-allocator-ia32.cc ('k') | src/virtual-frame-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698