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

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

Issue 115564: Size reduction of VirtualFrame objects. Remove the code generator and... (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
« no previous file with comments | « src/virtual-frame.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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_X64_VIRTUAL_FRAME_X64_H_ 28 #ifndef V8_X64_VIRTUAL_FRAME_X64_H_
29 #define V8_X64_VIRTUAL_FRAME_X64_H_ 29 #define V8_X64_VIRTUAL_FRAME_X64_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
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(rsp, index * kPointerSize); 199 return Operand(rsp, 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(rbp, kLocal0Offset - index * kPointerSize); 224 return Operand(rbp, 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
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(rbp, (1 + parameter_count_ - index) * kPointerSize); 262 return Operand(rbp, (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
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() const { 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
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_X64_VIRTUAL_FRAME_X64_H_ 545 #endif // V8_X64_VIRTUAL_FRAME_X64_H_
OLDNEW
« no previous file with comments | « src/virtual-frame.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698