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

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

Issue 1140004: MIPS simple function calls... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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/mips/stub-cache-mips.cc ('k') | src/mips/virtual-frame-mips.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 21 matching lines...) Expand all
32 #include "register-allocator.h" 32 #include "register-allocator.h"
33 #include "scopes.h" 33 #include "scopes.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 38
39 // ------------------------------------------------------------------------- 39 // -------------------------------------------------------------------------
40 // Virtual frames 40 // Virtual frames
41 // 41 //
42 // The virtual frame is an abstraction of the physical stack frame. It 42 // The virtual frame is an abstraction of the physical stack frame. It
43 // encapsulates the parameters, frame-allocated locals, and the expression 43 // encapsulates the parameters, frame-allocated locals, and the expression
44 // stack. It supports push/pop operations on the expression stack, as well 44 // stack. It supports push/pop operations on the expression stack, as well
45 // as random access to the expression stack elements, locals, and 45 // as random access to the expression stack elements, locals, and
46 // parameters. 46 // parameters.
47 47
48 class VirtualFrame : public ZoneObject { 48 class VirtualFrame : public ZoneObject {
49 public: 49 public:
50 // A utility class to introduce a scope where the virtual frame is 50 // A utility class to introduce a scope where the virtual frame is
51 // expected to remain spilled. The constructor spills the code 51 // expected to remain spilled. The constructor spills the code
52 // generator's current frame, but no attempt is made to require it 52 // generator's current frame, but no attempt is made to require it
53 // to stay spilled. It is intended as documentation while the code 53 // to stay spilled. It is intended as documentation while the code
54 // generator is being transformed. 54 // generator is being transformed.
55 class SpilledScope BASE_EMBEDDED { 55 class SpilledScope BASE_EMBEDDED {
56 public: 56 public:
57 SpilledScope() {} 57 SpilledScope() {}
58 }; 58 };
59 59
60 // An illegal index into the virtual frame. 60 // An illegal index into the virtual frame.
61 static const int kIllegalIndex = -1; 61 static const int kIllegalIndex = -1;
62 62
63 // Construct an initial virtual frame on entry to a JS function. 63 // Construct an initial virtual frame on entry to a JS function.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters); 98 ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters);
99 return register_locations_[num] != kIllegalIndex; 99 return register_locations_[num] != kIllegalIndex;
100 } 100 }
101 101
102 bool is_used(Register reg) { 102 bool is_used(Register reg) {
103 return register_locations_[RegisterAllocator::ToNumber(reg)] 103 return register_locations_[RegisterAllocator::ToNumber(reg)]
104 != kIllegalIndex; 104 != kIllegalIndex;
105 } 105 }
106 106
107 // Add extra in-memory elements to the top of the frame to match an actual 107 // Add extra in-memory elements to the top of the frame to match an actual
108 // frame (eg, the frame after an exception handler is pushed). No code is 108 // frame (eg, the frame after an exception handler is pushed). No code is
109 // emitted. 109 // emitted.
110 void Adjust(int count); 110 void Adjust(int count);
111 111
112 // Forget elements from the top of the frame to match an actual frame (eg, 112 // Forget elements from the top of the frame to match an actual frame (eg,
113 // the frame after a runtime call). No code is emitted. 113 // the frame after a runtime call). No code is emitted.
114 void Forget(int count) { 114 void Forget(int count) {
115 ASSERT(count >= 0); 115 ASSERT(count >= 0);
116 ASSERT(stack_pointer_ == element_count() - 1); 116 ASSERT(stack_pointer_ == element_count() - 1);
117 stack_pointer_ -= count; 117 stack_pointer_ -= count;
118 // On mips, all elements are in memory, so there is no extra bookkeeping 118 // On mips, all elements are in memory, so there is no extra bookkeeping
119 // (registers, copies, etc.) beyond dropping the elements. 119 // (registers, copies, etc.) beyond dropping the elements.
120 elements_.Rewind(stack_pointer_ + 1); 120 elements_.Rewind(stack_pointer_ + 1);
121 } 121 }
122 122
123 // Forget count elements from the top of the frame and adjust the stack 123 // Forget count elements from the top of the frame and adjust the stack
124 // pointer downward. This is used, for example, before merging frames at 124 // pointer downward. This is used, for example, before merging frames at
125 // break, continue, and return targets. 125 // break, continue, and return targets.
126 void ForgetElements(int count); 126 void ForgetElements(int count);
127 127
128 // Spill all values from the frame to memory. 128 // Spill all values from the frame to memory.
129 void SpillAll(); 129 void SpillAll();
130 130
131 // Spill all occurrences of a specific register from the frame. 131 // Spill all occurrences of a specific register from the frame.
132 void Spill(Register reg) { 132 void Spill(Register reg) {
133 if (is_used(reg)) SpillElementAt(register_location(reg)); 133 if (is_used(reg)) SpillElementAt(register_location(reg));
134 } 134 }
135 135
136 // Spill all occurrences of an arbitrary register if possible. Return the 136 // Spill all occurrences of an arbitrary register if possible. Return the
137 // register spilled or no_reg if it was not possible to free any register 137 // register spilled or no_reg if it was not possible to free any register
138 // (ie, they all have frame-external references). 138 // (ie, they all have frame-external references).
139 Register SpillAnyRegister(); 139 Register SpillAnyRegister();
140 140
141 // Prepare this virtual frame for merging to an expected frame by 141 // Prepare this virtual frame for merging to an expected frame by
142 // performing some state changes that do not require generating 142 // performing some state changes that do not require generating
143 // code. It is guaranteed that no code will be generated. 143 // code. It is guaranteed that no code will be generated.
144 void PrepareMergeTo(VirtualFrame* expected); 144 void PrepareMergeTo(VirtualFrame* expected);
145 145
146 // Make this virtual frame have a state identical to an expected virtual 146 // 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 147 // frame. As a side effect, code may be emitted to make this frame match
148 // the expected one. 148 // the expected one.
149 void MergeTo(VirtualFrame* expected); 149 void MergeTo(VirtualFrame* expected);
150 150
151 // Detach a frame from its code generator, perhaps temporarily. This 151 // Detach a frame from its code generator, perhaps temporarily. This
152 // tells the register allocator that it is free to use frame-internal 152 // 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 153 // registers. Used when the code generator's frame is switched from this
154 // one to NULL by an unconditional jump. 154 // one to NULL by an unconditional jump.
155 void DetachFromCodeGenerator() { 155 void DetachFromCodeGenerator() {
156 RegisterAllocator* cgen_allocator = cgen()->allocator(); 156 RegisterAllocator* cgen_allocator = cgen()->allocator();
157 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { 157 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
158 if (is_used(i)) cgen_allocator->Unuse(i); 158 if (is_used(i)) cgen_allocator->Unuse(i);
159 } 159 }
160 } 160 }
161 161
162 // (Re)attach a frame to its code generator. This informs the register 162 // (Re)attach a frame to its code generator. This informs the register
163 // allocator that the frame-internal register references are active again. 163 // allocator that the frame-internal register references are active again.
164 // Used when a code generator's frame is switched from NULL to this one by 164 // Used when a code generator's frame is switched from NULL to this one by
165 // binding a label. 165 // binding a label.
166 void AttachToCodeGenerator() { 166 void AttachToCodeGenerator() {
167 RegisterAllocator* cgen_allocator = cgen()->allocator(); 167 RegisterAllocator* cgen_allocator = cgen()->allocator();
168 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { 168 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
169 if (is_used(i)) cgen_allocator->Unuse(i); 169 if (is_used(i)) cgen_allocator->Unuse(i);
170 } 170 }
171 } 171 }
172 172
173 // Emit code for the physical JS entry and exit frame sequences. After 173 // Emit code for the physical JS entry and exit frame sequences. After
174 // calling Enter, the virtual frame is ready for use; and after calling 174 // calling Enter, the virtual frame is ready for use; and after calling
175 // Exit it should not be used. Note that Enter does not allocate space in 175 // Exit it should not be used. Note that Enter does not allocate space in
176 // the physical frame for storing frame-allocated locals. 176 // the physical frame for storing frame-allocated locals.
177 void Enter(); 177 void Enter();
178 void Exit(); 178 void Exit();
179 179
180 // Prepare for returning from the frame by spilling locals and 180 // Prepare for returning from the frame by spilling locals and
181 // dropping all non-locals elements in the virtual frame. This 181 // dropping all non-locals elements in the virtual frame. This
182 // avoids generating unnecessary merge code when jumping to the 182 // avoids generating unnecessary merge code when jumping to the
183 // shared return site. Emits code for spills. 183 // shared return site. Emits code for spills.
184 void PrepareForReturn(); 184 void PrepareForReturn();
185 185
186 // Allocate and initialize the frame-allocated locals. 186 // Allocate and initialize the frame-allocated locals.
187 void AllocateStackSlots(); 187 void AllocateStackSlots();
188 188
189 // The current top of the expression stack as an assembly operand. 189 // The current top of the expression stack as an assembly operand.
190 MemOperand Top() { return MemOperand(sp, 0); } 190 MemOperand Top() { return MemOperand(sp, 0); }
191 191
192 // An element of the expression stack as an assembly operand. 192 // An element of the expression stack as an assembly operand.
193 MemOperand ElementAt(int index) { 193 MemOperand ElementAt(int index) {
194 return MemOperand(sp, index * kPointerSize); 194 return MemOperand(sp, index * kPointerSize);
195 } 195 }
196 196
197 // Random-access store to a frame-top relative frame element. The result 197 // Random-access store to a frame-top relative frame element. The result
198 // becomes owned by the frame and is invalidated. 198 // becomes owned by the frame and is invalidated.
199 void SetElementAt(int index, Result* value); 199 void SetElementAt(int index, Result* value);
200 200
201 // Set a frame element to a constant. The index is frame-top relative. 201 // Set a frame element to a constant. The index is frame-top relative.
202 void SetElementAt(int index, Handle<Object> value) { 202 void SetElementAt(int index, Handle<Object> value) {
203 Result temp(value); 203 Result temp(value);
204 SetElementAt(index, &temp); 204 SetElementAt(index, &temp);
205 } 205 }
206 206
207 void PushElementAt(int index) { 207 void PushElementAt(int index) {
208 PushFrameSlotAt(element_count() - index - 1); 208 PushFrameSlotAt(element_count() - index - 1);
209 } 209 }
210 210
211 // A frame-allocated local as an assembly operand. 211 // A frame-allocated local as an assembly operand.
212 MemOperand LocalAt(int index) { 212 MemOperand LocalAt(int index) {
213 ASSERT(0 <= index); 213 ASSERT(0 <= index);
214 ASSERT(index < local_count()); 214 ASSERT(index < local_count());
215 return MemOperand(s8_fp, kLocal0Offset - index * kPointerSize); 215 return MemOperand(s8_fp, kLocal0Offset - index * kPointerSize);
216 } 216 }
217 217
218 // Push a copy of the value of a local frame slot on top of the frame. 218 // Push a copy of the value of a local frame slot on top of the frame.
219 void PushLocalAt(int index) { 219 void PushLocalAt(int index) {
220 PushFrameSlotAt(local0_index() + index); 220 PushFrameSlotAt(local0_index() + index);
221 } 221 }
222 222
223 // Push the value of a local frame slot on top of the frame and invalidate 223 // Push the value of a local frame slot on top of the frame and invalidate
224 // the local slot. The slot should be written to before trying to read 224 // the local slot. The slot should be written to before trying to read
225 // from it again. 225 // from it again.
226 void TakeLocalAt(int index) { 226 void TakeLocalAt(int index) {
227 TakeFrameSlotAt(local0_index() + index); 227 TakeFrameSlotAt(local0_index() + index);
228 } 228 }
229 229
230 // Store the top value on the virtual frame into a local frame slot. The 230 // Store the top value on the virtual frame into a local frame slot. The
231 // value is left in place on top of the frame. 231 // value is left in place on top of the frame.
232 void StoreToLocalAt(int index) { 232 void StoreToLocalAt(int index) {
233 StoreToFrameSlotAt(local0_index() + index); 233 StoreToFrameSlotAt(local0_index() + index);
234 } 234 }
235 235
236 // Push the address of the receiver slot on the frame. 236 // Push the address of the receiver slot on the frame.
237 void PushReceiverSlotAddress(); 237 void PushReceiverSlotAddress();
238 238
239 // The function frame slot. 239 // The function frame slot.
240 MemOperand Function() { return MemOperand(s8_fp, kFunctionOffset); } 240 MemOperand Function() { return MemOperand(s8_fp, kFunctionOffset); }
(...skipping 19 matching lines...) Expand all
260 uint16_t a = 0; // Number of argument slots. 260 uint16_t a = 0; // Number of argument slots.
261 return MemOperand(s8_fp, (1 + parameter_count() + a - index) *kPointerSize); 261 return MemOperand(s8_fp, (1 + parameter_count() + a - index) *kPointerSize);
262 } 262 }
263 263
264 // Push a copy of the value of a parameter frame slot on top of the frame. 264 // Push a copy of the value of a parameter frame slot on top of the frame.
265 void PushParameterAt(int index) { 265 void PushParameterAt(int index) {
266 PushFrameSlotAt(param0_index() + index); 266 PushFrameSlotAt(param0_index() + index);
267 } 267 }
268 268
269 // Push the value of a paramter frame slot on top of the frame and 269 // Push the value of a paramter frame slot on top of the frame and
270 // invalidate the parameter slot. The slot should be written to before 270 // invalidate the parameter slot. The slot should be written to before
271 // trying to read from it again. 271 // trying to read from it again.
272 void TakeParameterAt(int index) { 272 void TakeParameterAt(int index) {
273 TakeFrameSlotAt(param0_index() + index); 273 TakeFrameSlotAt(param0_index() + index);
274 } 274 }
275 275
276 // Store the top value on the virtual frame into a parameter frame slot. 276 // Store the top value on the virtual frame into a parameter frame slot.
277 // The value is left in place on top of the frame. 277 // The value is left in place on top of the frame.
278 void StoreToParameterAt(int index) { 278 void StoreToParameterAt(int index) {
279 StoreToFrameSlotAt(param0_index() + index); 279 StoreToFrameSlotAt(param0_index() + index);
280 } 280 }
281 281
282 // The receiver frame slot. 282 // The receiver frame slot.
283 MemOperand Receiver() { return ParameterAt(-1); } 283 MemOperand Receiver() { return ParameterAt(-1); }
284 284
285 // Push a try-catch or try-finally handler on top of the virtual frame. 285 // Push a try-catch or try-finally handler on top of the virtual frame.
286 void PushTryHandler(HandlerType type); 286 void PushTryHandler(HandlerType type);
287 287
288 // Call stub given the number of arguments it expects on (and 288 // Call stub given the number of arguments it expects on (and
289 // removes from) the stack. 289 // removes from) the stack.
290 void CallStub(CodeStub* stub, int arg_count) { 290 void CallStub(CodeStub* stub, int arg_count) {
291 PrepareForCall(arg_count, arg_count); 291 PrepareForCall(arg_count, arg_count);
292 RawCallStub(stub); 292 RawCallStub(stub);
293 } 293 }
294 294
295 // Call stub that expects its argument in r0. The argument is given
296 // as a result which must be the register r0.
297 void CallStub(CodeStub* stub, Result* arg); 295 void CallStub(CodeStub* stub, Result* arg);
298 296
299 // Call stub that expects its arguments in r1 and r0. The arguments
300 // are given as results which must be the appropriate registers.
301 void CallStub(CodeStub* stub, Result* arg0, Result* arg1); 297 void CallStub(CodeStub* stub, Result* arg0, Result* arg1);
302 298
303 // Call runtime given the number of arguments expected on (and 299 // Call runtime given the number of arguments expected on (and
304 // removed from) the stack. 300 // removed from) the stack.
305 void CallRuntime(Runtime::Function* f, int arg_count); 301 void CallRuntime(Runtime::Function* f, int arg_count);
306 void CallRuntime(Runtime::FunctionId id, int arg_count); 302 void CallRuntime(Runtime::FunctionId id, int arg_count);
307 303
308 // Call runtime with sp aligned to 8 bytes. 304 // Call runtime with sp aligned to 8 bytes.
309 void CallAlignedRuntime(Runtime::Function* f, int arg_count); 305 void CallAlignedRuntime(Runtime::Function* f, int arg_count);
310 void CallAlignedRuntime(Runtime::FunctionId id, int arg_count); 306 void CallAlignedRuntime(Runtime::FunctionId id, int arg_count);
311 307
312 // Invoke builtin given the number of arguments it expects on (and 308 // Invoke builtin given the number of arguments it expects on (and
313 // removes from) the stack. 309 // removes from) the stack.
314 void InvokeBuiltin(Builtins::JavaScript id, 310 void InvokeBuiltin(Builtins::JavaScript id,
315 InvokeJSFlags flag, 311 InvokeJSFlags flag,
316 Result* arg_count_register, 312 Result* arg_count_register,
317 int arg_count); 313 int arg_count);
318 314
319 // Call into an IC stub given the number of arguments it removes 315 // Call into an IC stub given the number of arguments it removes
320 // from the stack. Register arguments are passed as results and 316 // from the stack. Register arguments are passed as results and
321 // consumed by the call. 317 // consumed by the call.
322 void CallCodeObject(Handle<Code> ic, 318 void CallCodeObject(Handle<Code> ic,
323 RelocInfo::Mode rmode, 319 RelocInfo::Mode rmode,
324 int dropped_args); 320 int dropped_args);
325 void CallCodeObject(Handle<Code> ic, 321 void CallCodeObject(Handle<Code> ic,
326 RelocInfo::Mode rmode, 322 RelocInfo::Mode rmode,
327 Result* arg, 323 Result* arg,
328 int dropped_args); 324 int dropped_args);
329 void CallCodeObject(Handle<Code> ic, 325 void CallCodeObject(Handle<Code> ic,
330 RelocInfo::Mode rmode, 326 RelocInfo::Mode rmode,
331 Result* arg0, 327 Result* arg0,
332 Result* arg1, 328 Result* arg1,
333 int dropped_args, 329 int dropped_args,
334 bool set_auto_args_slots = false); 330 bool set_auto_args_slots = false);
335 331
336 // Drop a number of elements from the top of the expression stack. May 332 // Drop a number of elements from the top of the expression stack. May
337 // emit code to affect the physical frame. Does not clobber any registers 333 // emit code to affect the physical frame. Does not clobber any registers
338 // excepting possibly the stack pointer. 334 // excepting possibly the stack pointer.
339 void Drop(int count); 335 void Drop(int count);
340 // Similar to VirtualFrame::Drop but we don't modify the actual stack. 336 // Similar to VirtualFrame::Drop but we don't modify the actual stack.
341 // This is because we need to manually restore sp to the correct position. 337 // This is because we need to manually restore sp to the correct position.
342 void DropFromVFrameOnly(int count); 338 void DropFromVFrameOnly(int count);
343 339
344 // Drop one element. 340 // Drop one element.
345 void Drop() { Drop(1); } 341 void Drop() { Drop(1); }
346 void DropFromVFrameOnly() { DropFromVFrameOnly(1); } 342 void DropFromVFrameOnly() { DropFromVFrameOnly(1); }
347 343
348 // Duplicate the top element of the frame. 344 // Duplicate the top element of the frame.
349 void Dup() { PushFrameSlotAt(element_count() - 1); } 345 void Dup() { PushFrameSlotAt(element_count() - 1); }
350 346
351 // Pop an element from the top of the expression stack. Returns a 347 // Pop an element from the top of the expression stack. Returns a
352 // Result, which may be a constant or a register. 348 // Result, which may be a constant or a register.
353 Result Pop(); 349 Result Pop();
354 350
355 // Pop and save an element from the top of the expression stack and 351 // Pop and save an element from the top of the expression stack and
356 // emit a corresponding pop instruction. 352 // emit a corresponding pop instruction.
357 void EmitPop(Register reg); 353 void EmitPop(Register reg);
358 // Same but for multiple registers 354 // Same but for multiple registers
359 void EmitMultiPop(RegList regs); // higher indexed registers popped first 355 void EmitMultiPop(RegList regs);
360 void EmitMultiPopReversed(RegList regs); // lower first 356 void EmitMultiPopReversed(RegList regs);
361 357
362 // Push an element on top of the expression stack and emit a 358 // Push an element on top of the expression stack and emit a
363 // corresponding push instruction. 359 // corresponding push instruction.
364 void EmitPush(Register reg); 360 void EmitPush(Register reg);
365 // Same but for multiple registers. 361 // Same but for multiple registers.
366 void EmitMultiPush(RegList regs); // lower indexed registers are pushed first 362 void EmitMultiPush(RegList regs);
367 void EmitMultiPushReversed(RegList regs); // higher first 363 void EmitMultiPushReversed(RegList regs);
368 364
369 // Push an element on the virtual frame. 365 // Push an element on the virtual frame.
370 inline void Push(Register reg, NumberInfo info = NumberInfo::Unknown()); 366 inline void Push(Register reg, NumberInfo info = NumberInfo::Unknown());
371 inline void Push(Handle<Object> value); 367 inline void Push(Handle<Object> value);
372 inline void Push(Smi* value); 368 inline void Push(Smi* value);
373 369
374 // Pushing a result invalidates it (its contents become owned by the frame). 370 // Pushing a result invalidates it (its contents become owned by the frame).
375 void Push(Result* result) { 371 void Push(Result* result) {
376 if (result->is_register()) { 372 if (result->is_register()) {
377 Push(result->reg()); 373 Push(result->reg());
378 } else { 374 } else {
379 ASSERT(result->is_constant()); 375 ASSERT(result->is_constant());
380 Push(result->handle()); 376 Push(result->handle());
381 } 377 }
382 result->Unuse(); 378 result->Unuse();
383 } 379 }
384 380
385 // Nip removes zero or more elements from immediately below the top 381 // Nip removes zero or more elements from immediately below the top
386 // of the frame, leaving the previous top-of-frame value on top of 382 // of the frame, leaving the previous top-of-frame value on top of
387 // the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x). 383 // the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
388 inline void Nip(int num_dropped); 384 inline void Nip(int num_dropped);
389 385
390 // This pushes 4 arguments slots on the stack and saves asked 'a' registers 386 // This pushes 4 arguments slots on the stack and saves asked 'a' registers
391 // 'a' registers are arguments register a0 to a3. 387 // 'a' registers are arguments register a0 to a3.
392 void EmitArgumentSlots(RegList reglist); 388 void EmitArgumentSlots(RegList reglist);
393 389
394 inline void SetTypeForLocalAt(int index, NumberInfo info); 390 inline void SetTypeForLocalAt(int index, NumberInfo info);
391 inline void SetTypeForParamAt(int index, NumberInfo info);
395 392
396 private: 393 private:
397 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset; 394 static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
398 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset; 395 static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
399 static const int kContextOffset = StandardFrameConstants::kContextOffset; 396 static const int kContextOffset = StandardFrameConstants::kContextOffset;
400 397
401 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; 398 static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
402 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. 399 static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots.
403 400
404 ZoneList<FrameElement> elements_; 401 ZoneList<FrameElement> elements_;
405 402
406 // 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
407 // (the sp register). 404 // (the sp register).
408 int stack_pointer_; 405 int stack_pointer_;
409 406
410 // The index of the register frame element using each register, or 407 // The index of the register frame element using each register, or
411 // kIllegalIndex if a register is not on the frame. 408 // kIllegalIndex if a register is not on the frame.
412 int register_locations_[RegisterAllocator::kNumRegisters]; 409 int register_locations_[RegisterAllocator::kNumRegisters];
413 410
414 // The number of frame-allocated locals and parameters respectively. 411 // The number of frame-allocated locals and parameters respectively.
415 int parameter_count() { return cgen()->scope()->num_parameters(); } 412 int parameter_count() { return cgen()->scope()->num_parameters(); }
416 int local_count() { return cgen()->scope()->num_stack_slots(); } 413 int local_count() { return cgen()->scope()->num_stack_slots(); }
417 414
418 // The index of the element that is at the processor's frame pointer 415 // The index of the element that is at the processor's frame pointer
419 // (the fp register). The parameters, receiver, function, and context 416 // (the fp register). The parameters, receiver, function, and context
420 // are below the frame pointer. 417 // are below the frame pointer.
421 int frame_pointer() { return parameter_count() + 3; } 418 int frame_pointer() { return parameter_count() + 3; }
422 419
423 // 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
424 // parameter. 421 // parameter.
425 int param0_index() { return 1; } 422 int param0_index() { return 1; }
426 423
427 // The index of the context slot in the frame. It is immediately 424 // The index of the context slot in the frame. It is immediately
428 // below the frame pointer. 425 // below the frame pointer.
429 int context_index() { return frame_pointer() - 1; } 426 int context_index() { return frame_pointer() - 1; }
430 427
431 // The index of the function slot in the frame. It is below the frame 428 // The index of the function slot in the frame. It is below the frame
432 // pointer and context slot. 429 // pointer and context slot.
433 int function_index() { return frame_pointer() - 2; } 430 int function_index() { return frame_pointer() - 2; }
434 431
435 // The index of the first local. Between the frame pointer and the 432 // The index of the first local. Between the frame pointer and the
436 // locals lies the return address. 433 // locals lies the return address.
437 int local0_index() { return frame_pointer() + 2; } 434 int local0_index() { return frame_pointer() + 2; }
438 435
439 // The index of the base of the expression stack. 436 // The index of the base of the expression stack.
440 int expression_base_index() { return local0_index() + local_count(); } 437 int expression_base_index() { return local0_index() + local_count(); }
441 438
442 // 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
443 // actual stack. 440 // actual stack.
444 int fp_relative(int index) { 441 int fp_relative(int index) {
445 ASSERT(index < element_count()); 442 ASSERT(index < element_count());
446 ASSERT(frame_pointer() < element_count()); // FP is on the frame. 443 ASSERT(frame_pointer() < element_count()); // FP is on the frame.
447 return (frame_pointer() - index) * kPointerSize; 444 return (frame_pointer() - index) * kPointerSize;
448 } 445 }
449 446
450 // 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
451 // effect of incrementing the register's external reference count and 448 // effect of incrementing the register's external reference count and
452 // 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.
453 void Use(Register reg, int index) { 450 void Use(Register reg, int index) {
454 ASSERT(!is_used(reg)); 451 ASSERT(!is_used(reg));
455 set_register_location(reg, index); 452 set_register_location(reg, index);
456 cgen()->allocator()->Use(reg); 453 cgen()->allocator()->Use(reg);
457 } 454 }
458 455
459 // 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
460 // decrements the register's external reference count and invalidates the 457 // decrements the register's external reference count and invalidates the
461 // index of the register's location in the frame. 458 // index of the register's location in the frame.
462 void Unuse(Register reg) { 459 void Unuse(Register reg) {
463 ASSERT(is_used(reg)); 460 ASSERT(is_used(reg));
464 set_register_location(reg, kIllegalIndex); 461 set_register_location(reg, kIllegalIndex);
465 cgen()->allocator()->Unuse(reg); 462 cgen()->allocator()->Unuse(reg);
466 } 463 }
467 464
468 // 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
469 // necessary, free any associated register, and forget its value if 466 // necessary, free any associated register, and forget its value if
470 // constant. 467 // constant.
471 void SpillElementAt(int index); 468 void SpillElementAt(int index);
472 469
473 // 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
474 // 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.
475 // 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.
476 void SyncElementAt(int index); 473 void SyncElementAt(int index);
477 474
478 // Sync the range of elements in [begin, end] with memory. 475 // Sync the range of elements in [begin, end] with memory.
479 void SyncRange(int begin, int end); 476 void SyncRange(int begin, int end);
480 477
481 // Sync a single unsynced element that lies beneath or at the stack pointer. 478 // Sync a single unsynced element that lies beneath or at the stack pointer.
482 void SyncElementBelowStackPointer(int index); 479 void SyncElementBelowStackPointer(int index);
483 480
484 // Sync a single unsynced element that lies just above the stack pointer. 481 // Sync a single unsynced element that lies just above the stack pointer.
485 void SyncElementByPushing(int index); 482 void SyncElementByPushing(int index);
486 483
487 // Push a copy of a frame slot (typically a local or parameter) on top of 484 // Push a copy of a frame slot (typically a local or parameter) on top of
488 // the frame. 485 // the frame.
489 inline void PushFrameSlotAt(int index); 486 inline void PushFrameSlotAt(int index);
490 487
491 // Push a the value of a frame slot (typically a local or parameter) on 488 // Push a the value of a frame slot (typically a local or parameter) on
492 // top of the frame and invalidate the slot. 489 // top of the frame and invalidate the slot.
493 void TakeFrameSlotAt(int index); 490 void TakeFrameSlotAt(int index);
494 491
495 // Store the value on top of the frame to a frame slot (typically a local 492 // Store the value on top of the frame to a frame slot (typically a local
496 // or parameter). 493 // or parameter).
497 void StoreToFrameSlotAt(int index); 494 void StoreToFrameSlotAt(int index);
498 495
499 // Spill all elements in registers. Spill the top spilled_args elements 496 // Spill all elements in registers. Spill the top spilled_args elements
500 // on the frame. Sync all other frame elements. 497 // on the frame. Sync all other frame elements.
501 // Then drop dropped_args elements from the virtual frame, to match 498 // Then drop dropped_args elements from the virtual frame, to match
502 // the effect of an upcoming call that will drop them from the stack. 499 // the effect of an upcoming call that will drop them from the stack.
503 void PrepareForCall(int spilled_args, int dropped_args); 500 void PrepareForCall(int spilled_args, int dropped_args);
504 501
505 // Move frame elements currently in registers or constants, that 502 // Move frame elements currently in registers or constants, that
506 // should be in memory in the expected frame, to memory. 503 // should be in memory in the expected frame, to memory.
507 void MergeMoveRegistersToMemory(VirtualFrame* expected); 504 void MergeMoveRegistersToMemory(VirtualFrame* expected);
508 505
509 // Make the register-to-register moves necessary to 506 // Make the register-to-register moves necessary to
510 // merge this frame with the expected frame. 507 // merge this frame with the expected frame.
511 // Register to memory moves must already have been made, 508 // Register to memory moves must already have been made,
512 // and memory to register moves must follow this call. 509 // and memory to register moves must follow this call.
513 // This is because some new memory-to-register moves are 510 // This is because some new memory-to-register moves are
514 // created in order to break cycles of register moves. 511 // created in order to break cycles of register moves.
515 // Used in the implementation of MergeTo(). 512 // Used in the implementation of MergeTo().
516 void MergeMoveRegistersToRegisters(VirtualFrame* expected); 513 void MergeMoveRegistersToRegisters(VirtualFrame* expected);
517 514
518 // Make the memory-to-register and constant-to-register moves 515 // Make the memory-to-register and constant-to-register moves
519 // needed to make this frame equal the expected frame. 516 // needed to make this frame equal the expected frame.
520 // Called after all register-to-memory and register-to-register 517 // Called after all register-to-memory and register-to-register
521 // moves have been made. After this function returns, the frames 518 // moves have been made. After this function returns, the frames
522 // should be equal. 519 // should be equal.
523 void MergeMoveMemoryToRegisters(VirtualFrame* expected); 520 void MergeMoveMemoryToRegisters(VirtualFrame* expected);
524 521
525 // Invalidates a frame slot (puts an invalid frame element in it). 522 // Invalidates a frame slot (puts an invalid frame element in it).
526 // Copies on the frame are correctly handled, and if this slot was 523 // Copies on the frame are correctly handled, and if this slot was
527 // the backing store of copies, the index of the new backing store 524 // the backing store of copies, the index of the new backing store
528 // is returned. Otherwise, returns kIllegalIndex. 525 // is returned. Otherwise, returns kIllegalIndex.
529 // Register counts are correctly updated. 526 // Register counts are correctly updated.
530 int InvalidateFrameSlotAt(int index); 527 int InvalidateFrameSlotAt(int index);
531 528
532 // Call a code stub that has already been prepared for calling (via 529 // Call a code stub that has already been prepared for calling (via
533 // PrepareForCall). 530 // PrepareForCall).
534 void RawCallStub(CodeStub* stub); 531 void RawCallStub(CodeStub* stub);
535 532
536 // Calls a code object which has already been prepared for calling 533 // Calls a code object which has already been prepared for calling
537 // (via PrepareForCall). 534 // (via PrepareForCall).
538 void RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode); 535 void RawCallCodeObject(Handle<Code> code, RelocInfo::Mode rmode);
539 536
540 inline bool Equals(VirtualFrame* other); 537 inline bool Equals(VirtualFrame* other);
541 538
542 // Classes that need raw access to the elements_ array. 539 // Classes that need raw access to the elements_ array.
543 friend class DeferredCode; 540 friend class DeferredCode;
544 friend class JumpTarget; 541 friend class JumpTarget;
545 }; 542 };
546 543
547 544
548 } } // namespace v8::internal 545 } } // namespace v8::internal
549 546
550 #endif // V8_MIPS_VIRTUAL_FRAME_MIPS_H_ 547 #endif // V8_MIPS_VIRTUAL_FRAME_MIPS_H_
551 548
OLDNEW
« no previous file with comments | « src/mips/stub-cache-mips.cc ('k') | src/mips/virtual-frame-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698