~james-page/ubuntu/precise/nodejs/0.6.x-merge

« back to all changes in this revision

Viewing changes to deps/v8/src/arm/virtual-frame-arm.h

  • Committer: James Page
  • Date: 2012-03-30 12:09:16 UTC
  • mfrom: (7.1.23 sid)
  • Revision ID: james.page@canonical.com-20120330120916-40hfu9o00qr5t87b
* Merge from Debian unstable:
  - New upstream release (LP: #892034).
  - This package is x86/arm only. Update control to match
  - d/patches/2009_increase_test_timeout.patch: Increased default test
    timeout from 60 to 120 seconds to support reliable execution of all
    tests on armhf/armel architectures.
  - d/patches/2005_expected_failing_tests.patch: 
    - Allow racey tests to fail: test-cluster-kill-workers,
      test-child-process-fork2 
    - Allow test-fs-watch to fail as LP buildd's don't support
      inotify.
    - Revert all other Ubuntu changes as no longer required.
* Update Standards-Version to 3.9.3.
* Patch wscript to enable build on mipsel arch, libv8 being available.
  Upstream does not support that arch, failure expected.
* test-cluster-kill-workers is expected to fail on armhf,
  Bug#660802 will be closed when test pass.
* test-buffer is expected to fail on armel,
  Bug#660800 will be closed when test pass.
* Add epoch to dependency on libev >= 1:4.11. Closes: bug#658441.
* Remove tools/doc because node-doc-generator has no license for now.
* Add copyright for doc/sh* files (shjs).
* source.lintian-overrides : source-contains-waf-binary tools/node-waf
  it is simply not the case here.
* test-stream-pipe-multi expected to timeout sometimes on busy builds. 
* New upstream release.
* Remove upstream patches.
* test-dgram-pingpong expected to timeout, the test itself is buggy.
* test-buffer expected to fail on armel, allow building package to make
  it easier to find the cause of the failure.
  Closes: bug#639636.
* Expect tests dgram-multicast and broadcast to fail.
  debian/patches/2005_expected_failing_tests.patch
* Drop dpkg-source local-options: Defaults since dpkg-source 1.16.1.
* New upstream release.
* Depend on libev-dev 4.11, see bug#657080.
* Bump dependency on openssl to 1.0.0g.
* Remove useless uv_loop_refcount from libuv,
  refreshed 2009_fix_shared_ev.patch.
* Apply to upstream patches landed after 0.6.10 release,
  to fix debugger repl and http client.
* New upstream release. Closes:bug#650661
* Repackage to remove non-dfsg font files ./deps/npm/html/*/*.ttf
* Remove unneeded bundled dependencies: lighter tarball,
  debian/copyright is easier to maintain.
* Drop unneeded build-dependency on scons.
* Depend on zlib1g, libc-ares, libev.
  Patches done to support building with those shared libs.
* Fix DEB_UPSTREAM_URL in debian/rules, and debian/watch.
* nodejs.pc file for pkgconfig is no more available.
* Build-depend on procps package, a test is using /bin/ps.
* Refreshed debian/patches/2005_expected_failing_tests.patch,
  only for tests that need networking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2009 the V8 project authors. All rights reserved.
2
 
// Redistribution and use in source and binary forms, with or without
3
 
// modification, are permitted provided that the following conditions are
4
 
// met:
5
 
//
6
 
//     * Redistributions of source code must retain the above copyright
7
 
//       notice, this list of conditions and the following disclaimer.
8
 
//     * Redistributions in binary form must reproduce the above
9
 
//       copyright notice, this list of conditions and the following
10
 
//       disclaimer in the documentation and/or other materials provided
11
 
//       with the distribution.
12
 
//     * Neither the name of Google Inc. nor the names of its
13
 
//       contributors may be used to endorse or promote products derived
14
 
//       from this software without specific prior written permission.
15
 
//
16
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
27
 
 
28
 
#ifndef V8_ARM_VIRTUAL_FRAME_ARM_H_
29
 
#define V8_ARM_VIRTUAL_FRAME_ARM_H_
30
 
 
31
 
#include "register-allocator.h"
32
 
 
33
 
namespace v8 {
34
 
namespace internal {
35
 
 
36
 
// This dummy class is only used to create invalid virtual frames.
37
 
extern class InvalidVirtualFrameInitializer {}* kInvalidVirtualFrameInitializer;
38
 
 
39
 
 
40
 
// -------------------------------------------------------------------------
41
 
// Virtual frames
42
 
//
43
 
// The virtual frame is an abstraction of the physical stack frame.  It
44
 
// encapsulates the parameters, frame-allocated locals, and the expression
45
 
// stack.  It supports push/pop operations on the expression stack, as well
46
 
// as random access to the expression stack elements, locals, and
47
 
// parameters.
48
 
 
49
 
class VirtualFrame : public ZoneObject {
50
 
 public:
51
 
  class RegisterAllocationScope;
52
 
  // A utility class to introduce a scope where the virtual frame is
53
 
  // expected to remain spilled.  The constructor spills the code
54
 
  // generator's current frame, and keeps it spilled.
55
 
  class SpilledScope BASE_EMBEDDED {
56
 
   public:
57
 
    explicit SpilledScope(VirtualFrame* frame)
58
 
      : old_is_spilled_(is_spilled_) {
59
 
      if (frame != NULL) {
60
 
        if (!is_spilled_) {
61
 
          frame->SpillAll();
62
 
        } else {
63
 
          frame->AssertIsSpilled();
64
 
        }
65
 
      }
66
 
      is_spilled_ = true;
67
 
    }
68
 
    ~SpilledScope() {
69
 
      is_spilled_ = old_is_spilled_;
70
 
    }
71
 
    static bool is_spilled() { return is_spilled_; }
72
 
 
73
 
   private:
74
 
    static bool is_spilled_;
75
 
    int old_is_spilled_;
76
 
 
77
 
    SpilledScope() { }
78
 
 
79
 
    friend class RegisterAllocationScope;
80
 
  };
81
 
 
82
 
  class RegisterAllocationScope BASE_EMBEDDED {
83
 
   public:
84
 
    // A utility class to introduce a scope where the virtual frame
85
 
    // is not spilled, ie. where register allocation occurs.  Eventually
86
 
    // when RegisterAllocationScope is ubiquitous it can be removed
87
 
    // along with the (by then unused) SpilledScope class.
88
 
    inline explicit RegisterAllocationScope(CodeGenerator* cgen);
89
 
    inline ~RegisterAllocationScope();
90
 
 
91
 
   private:
92
 
    CodeGenerator* cgen_;
93
 
    bool old_is_spilled_;
94
 
 
95
 
    RegisterAllocationScope() { }
96
 
  };
97
 
 
98
 
  // An illegal index into the virtual frame.
99
 
  static const int kIllegalIndex = -1;
100
 
 
101
 
  // Construct an initial virtual frame on entry to a JS function.
102
 
  inline VirtualFrame();
103
 
 
104
 
  // Construct an invalid virtual frame, used by JumpTargets.
105
 
  inline VirtualFrame(InvalidVirtualFrameInitializer* dummy);
106
 
 
107
 
  // Construct a virtual frame as a clone of an existing one.
108
 
  explicit inline VirtualFrame(VirtualFrame* original);
109
 
 
110
 
  inline CodeGenerator* cgen() const;
111
 
  inline MacroAssembler* masm();
112
 
 
113
 
  // The number of elements on the virtual frame.
114
 
  int element_count() const { return element_count_; }
115
 
 
116
 
  // The height of the virtual expression stack.
117
 
  inline int height() const;
118
 
 
119
 
  bool is_used(int num) {
120
 
    switch (num) {
121
 
      case 0: {  // r0.
122
 
        return kR0InUse[top_of_stack_state_];
123
 
      }
124
 
      case 1: {  // r1.
125
 
        return kR1InUse[top_of_stack_state_];
126
 
      }
127
 
      case 2:
128
 
      case 3:
129
 
      case 4:
130
 
      case 5:
131
 
      case 6: {  // r2 to r6.
132
 
        ASSERT(num - kFirstAllocatedRegister < kNumberOfAllocatedRegisters);
133
 
        ASSERT(num >= kFirstAllocatedRegister);
134
 
        if ((register_allocation_map_ &
135
 
             (1 << (num - kFirstAllocatedRegister))) == 0) {
136
 
          return false;
137
 
        } else {
138
 
          return true;
139
 
        }
140
 
      }
141
 
      default: {
142
 
        ASSERT(num < kFirstAllocatedRegister ||
143
 
               num >= kFirstAllocatedRegister + kNumberOfAllocatedRegisters);
144
 
        return false;
145
 
      }
146
 
    }
147
 
  }
148
 
 
149
 
  // Add extra in-memory elements to the top of the frame to match an actual
150
 
  // frame (eg, the frame after an exception handler is pushed).  No code is
151
 
  // emitted.
152
 
  void Adjust(int count);
153
 
 
154
 
  // Forget elements from the top of the frame to match an actual frame (eg,
155
 
  // the frame after a runtime call).  No code is emitted except to bring the
156
 
  // frame to a spilled state.
157
 
  void Forget(int count);
158
 
 
159
 
  // Spill all values from the frame to memory.
160
 
  void SpillAll();
161
 
 
162
 
  void AssertIsSpilled() const {
163
 
    ASSERT(top_of_stack_state_ == NO_TOS_REGISTERS);
164
 
    ASSERT(register_allocation_map_ == 0);
165
 
  }
166
 
 
167
 
  void AssertIsNotSpilled() {
168
 
    ASSERT(!SpilledScope::is_spilled());
169
 
  }
170
 
 
171
 
  // Spill all occurrences of a specific register from the frame.
172
 
  void Spill(Register reg) {
173
 
    UNIMPLEMENTED();
174
 
  }
175
 
 
176
 
  // Spill all occurrences of an arbitrary register if possible.  Return the
177
 
  // register spilled or no_reg if it was not possible to free any register
178
 
  // (ie, they all have frame-external references).  Unimplemented.
179
 
  Register SpillAnyRegister();
180
 
 
181
 
  // Make this virtual frame have a state identical to an expected virtual
182
 
  // frame.  As a side effect, code may be emitted to make this frame match
183
 
  // the expected one.
184
 
  void MergeTo(VirtualFrame* expected, Condition cond = al);
185
 
  void MergeTo(const VirtualFrame* expected, Condition cond = al);
186
 
 
187
 
  // Checks whether this frame can be branched to by the other frame.
188
 
  bool IsCompatibleWith(const VirtualFrame* other) const {
189
 
    return (tos_known_smi_map_ & (~other->tos_known_smi_map_)) == 0;
190
 
  }
191
 
 
192
 
  inline void ForgetTypeInfo() {
193
 
    tos_known_smi_map_ = 0;
194
 
  }
195
 
 
196
 
  // Detach a frame from its code generator, perhaps temporarily.  This
197
 
  // tells the register allocator that it is free to use frame-internal
198
 
  // registers.  Used when the code generator's frame is switched from this
199
 
  // one to NULL by an unconditional jump.
200
 
  void DetachFromCodeGenerator() {
201
 
  }
202
 
 
203
 
  // (Re)attach a frame to its code generator.  This informs the register
204
 
  // allocator that the frame-internal register references are active again.
205
 
  // Used when a code generator's frame is switched from NULL to this one by
206
 
  // binding a label.
207
 
  void AttachToCodeGenerator() {
208
 
  }
209
 
 
210
 
  // Emit code for the physical JS entry and exit frame sequences.  After
211
 
  // calling Enter, the virtual frame is ready for use; and after calling
212
 
  // Exit it should not be used.  Note that Enter does not allocate space in
213
 
  // the physical frame for storing frame-allocated locals.
214
 
  void Enter();
215
 
  void Exit();
216
 
 
217
 
  // Prepare for returning from the frame by elements in the virtual frame. This
218
 
  // avoids generating unnecessary merge code when jumping to the
219
 
  // shared return site. No spill code emitted. Value to return should be in r0.
220
 
  inline void PrepareForReturn();
221
 
 
222
 
  // Number of local variables after when we use a loop for allocating.
223
 
  static const int kLocalVarBound = 5;
224
 
 
225
 
  // Allocate and initialize the frame-allocated locals.
226
 
  void AllocateStackSlots();
227
 
 
228
 
  // The current top of the expression stack as an assembly operand.
229
 
  MemOperand Top() {
230
 
    AssertIsSpilled();
231
 
    return MemOperand(sp, 0);
232
 
  }
233
 
 
234
 
  // An element of the expression stack as an assembly operand.
235
 
  MemOperand ElementAt(int index) {
236
 
    int adjusted_index = index - kVirtualElements[top_of_stack_state_];
237
 
    ASSERT(adjusted_index >= 0);
238
 
    return MemOperand(sp, adjusted_index * kPointerSize);
239
 
  }
240
 
 
241
 
  bool KnownSmiAt(int index) {
242
 
    if (index >= kTOSKnownSmiMapSize) return false;
243
 
    return (tos_known_smi_map_ & (1 << index)) != 0;
244
 
  }
245
 
 
246
 
  // A frame-allocated local as an assembly operand.
247
 
  inline MemOperand LocalAt(int index);
248
 
 
249
 
  // Push the address of the receiver slot on the frame.
250
 
  void PushReceiverSlotAddress();
251
 
 
252
 
  // The function frame slot.
253
 
  MemOperand Function() { return MemOperand(fp, kFunctionOffset); }
254
 
 
255
 
  // The context frame slot.
256
 
  MemOperand Context() { return MemOperand(fp, kContextOffset); }
257
 
 
258
 
  // A parameter as an assembly operand.
259
 
  inline MemOperand ParameterAt(int index);
260
 
 
261
 
  // The receiver frame slot.
262
 
  inline MemOperand Receiver();
263
 
 
264
 
  // Push a try-catch or try-finally handler on top of the virtual frame.
265
 
  void PushTryHandler(HandlerType type);
266
 
 
267
 
  // Call stub given the number of arguments it expects on (and
268
 
  // removes from) the stack.
269
 
  inline void CallStub(CodeStub* stub, int arg_count);
270
 
 
271
 
  // Call JS function from top of the stack with arguments
272
 
  // taken from the stack.
273
 
  void CallJSFunction(int arg_count);
274
 
 
275
 
  // Call runtime given the number of arguments expected on (and
276
 
  // removed from) the stack.
277
 
  void CallRuntime(Runtime::Function* f, int arg_count);
278
 
  void CallRuntime(Runtime::FunctionId id, int arg_count);
279
 
 
280
 
#ifdef ENABLE_DEBUGGER_SUPPORT
281
 
  void DebugBreak();
282
 
#endif
283
 
 
284
 
  // Invoke builtin given the number of arguments it expects on (and
285
 
  // removes from) the stack.
286
 
  void InvokeBuiltin(Builtins::JavaScript id,
287
 
                     InvokeJSFlags flag,
288
 
                     int arg_count);
289
 
 
290
 
  // Call load IC. Receiver is on the stack and is consumed. Result is returned
291
 
  // in r0.
292
 
  void CallLoadIC(Handle<String> name, RelocInfo::Mode mode);
293
 
 
294
 
  // Call store IC. If the load is contextual, value is found on top of the
295
 
  // frame. If not, value and receiver are on the frame. Both are consumed.
296
 
  // Result is returned in r0.
297
 
  void CallStoreIC(Handle<String> name, bool is_contextual,
298
 
                   StrictModeFlag strict_mode);
299
 
 
300
 
  // Call keyed load IC. Key and receiver are on the stack. Both are consumed.
301
 
  // Result is returned in r0.
302
 
  void CallKeyedLoadIC();
303
 
 
304
 
  // Call keyed store IC. Value, key and receiver are on the stack. All three
305
 
  // are consumed. Result is returned in r0.
306
 
  void CallKeyedStoreIC(StrictModeFlag strict_mode);
307
 
 
308
 
  // Call into an IC stub given the number of arguments it removes
309
 
  // from the stack.  Register arguments to the IC stub are implicit,
310
 
  // and depend on the type of IC stub.
311
 
  void CallCodeObject(Handle<Code> ic,
312
 
                      RelocInfo::Mode rmode,
313
 
                      int dropped_args);
314
 
 
315
 
  // Drop a number of elements from the top of the expression stack.  May
316
 
  // emit code to affect the physical frame.  Does not clobber any registers
317
 
  // excepting possibly the stack pointer.
318
 
  void Drop(int count);
319
 
 
320
 
  // Drop one element.
321
 
  void Drop() { Drop(1); }
322
 
 
323
 
  // Pop an element from the top of the expression stack.  Discards
324
 
  // the result.
325
 
  void Pop();
326
 
 
327
 
  // Pop an element from the top of the expression stack.  The register
328
 
  // will be one normally used for the top of stack register allocation
329
 
  // so you can't hold on to it if you push on the stack.
330
 
  Register PopToRegister(Register but_not_to_this_one = no_reg);
331
 
 
332
 
  // Look at the top of the stack.  The register returned is aliased and
333
 
  // must be copied to a scratch register before modification.
334
 
  Register Peek();
335
 
 
336
 
  // Look at the value beneath the top of the stack.  The register returned is
337
 
  // aliased and must be copied to a scratch register before modification.
338
 
  Register Peek2();
339
 
 
340
 
  // Duplicate the top of stack.
341
 
  void Dup();
342
 
 
343
 
  // Duplicate the two elements on top of stack.
344
 
  void Dup2();
345
 
 
346
 
  // Flushes all registers, but it puts a copy of the top-of-stack in r0.
347
 
  void SpillAllButCopyTOSToR0();
348
 
 
349
 
  // Flushes all registers, but it puts a copy of the top-of-stack in r1.
350
 
  void SpillAllButCopyTOSToR1();
351
 
 
352
 
  // Flushes all registers, but it puts a copy of the top-of-stack in r1
353
 
  // and the next value on the stack in r0.
354
 
  void SpillAllButCopyTOSToR1R0();
355
 
 
356
 
  // Pop and save an element from the top of the expression stack and
357
 
  // emit a corresponding pop instruction.
358
 
  void EmitPop(Register reg);
359
 
 
360
 
  // Takes the top two elements and puts them in r0 (top element) and r1
361
 
  // (second element).
362
 
  void PopToR1R0();
363
 
 
364
 
  // Takes the top element and puts it in r1.
365
 
  void PopToR1();
366
 
 
367
 
  // Takes the top element and puts it in r0.
368
 
  void PopToR0();
369
 
 
370
 
  // Push an element on top of the expression stack and emit a
371
 
  // corresponding push instruction.
372
 
  void EmitPush(Register reg, TypeInfo type_info = TypeInfo::Unknown());
373
 
  void EmitPush(Operand operand, TypeInfo type_info = TypeInfo::Unknown());
374
 
  void EmitPush(MemOperand operand, TypeInfo type_info = TypeInfo::Unknown());
375
 
  void EmitPushRoot(Heap::RootListIndex index);
376
 
 
377
 
  // Overwrite the nth thing on the stack.  If the nth position is in a
378
 
  // register then this turns into a mov, otherwise an str.  Afterwards
379
 
  // you can still use the register even if it is a register that can be
380
 
  // used for TOS (r0 or r1).
381
 
  void SetElementAt(Register reg, int this_far_down);
382
 
 
383
 
  // Get a register which is free and which must be immediately used to
384
 
  // push on the top of the stack.
385
 
  Register GetTOSRegister();
386
 
 
387
 
  // Push multiple registers on the stack and the virtual frame
388
 
  // Register are selected by setting bit in src_regs and
389
 
  // are pushed in decreasing order: r15 .. r0.
390
 
  void EmitPushMultiple(int count, int src_regs);
391
 
 
392
 
  static Register scratch0() { return r7; }
393
 
  static Register scratch1() { return r9; }
394
 
 
395
 
 private:
396
 
  static const int kLocal0Offset = JavaScriptFrameConstants::kLocal0Offset;
397
 
  static const int kFunctionOffset = JavaScriptFrameConstants::kFunctionOffset;
398
 
  static const int kContextOffset = StandardFrameConstants::kContextOffset;
399
 
 
400
 
  static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
401
 
  static const int kPreallocatedElements = 5 + 8;  // 8 expression stack slots.
402
 
 
403
 
  // 5 states for the top of stack, which can be in memory or in r0 and r1.
404
 
  enum TopOfStack {
405
 
    NO_TOS_REGISTERS,
406
 
    R0_TOS,
407
 
    R1_TOS,
408
 
    R1_R0_TOS,
409
 
    R0_R1_TOS,
410
 
    TOS_STATES
411
 
  };
412
 
 
413
 
  static const int kMaxTOSRegisters = 2;
414
 
 
415
 
  static const bool kR0InUse[TOS_STATES];
416
 
  static const bool kR1InUse[TOS_STATES];
417
 
  static const int kVirtualElements[TOS_STATES];
418
 
  static const TopOfStack kStateAfterPop[TOS_STATES];
419
 
  static const TopOfStack kStateAfterPush[TOS_STATES];
420
 
  static const Register kTopRegister[TOS_STATES];
421
 
  static const Register kBottomRegister[TOS_STATES];
422
 
 
423
 
  // We allocate up to 5 locals in registers.
424
 
  static const int kNumberOfAllocatedRegisters = 5;
425
 
  // r2 to r6 are allocated to locals.
426
 
  static const int kFirstAllocatedRegister = 2;
427
 
 
428
 
  static const Register kAllocatedRegisters[kNumberOfAllocatedRegisters];
429
 
 
430
 
  static Register AllocatedRegister(int r) {
431
 
    ASSERT(r >= 0 && r < kNumberOfAllocatedRegisters);
432
 
    return kAllocatedRegisters[r];
433
 
  }
434
 
 
435
 
  // The number of elements on the stack frame.
436
 
  int element_count_;
437
 
  TopOfStack top_of_stack_state_:3;
438
 
  int register_allocation_map_:kNumberOfAllocatedRegisters;
439
 
  static const int kTOSKnownSmiMapSize = 4;
440
 
  unsigned tos_known_smi_map_:kTOSKnownSmiMapSize;
441
 
 
442
 
  // The index of the element that is at the processor's stack pointer
443
 
  // (the sp register).  For now since everything is in memory it is given
444
 
  // by the number of elements on the not-very-virtual stack frame.
445
 
  int stack_pointer() { return element_count_ - 1; }
446
 
 
447
 
  // The number of frame-allocated locals and parameters respectively.
448
 
  inline int parameter_count() const;
449
 
  inline int local_count() const;
450
 
 
451
 
  // The index of the element that is at the processor's frame pointer
452
 
  // (the fp register).  The parameters, receiver, function, and context
453
 
  // are below the frame pointer.
454
 
  inline int frame_pointer() const;
455
 
 
456
 
  // The index of the first parameter.  The receiver lies below the first
457
 
  // parameter.
458
 
  int param0_index() { return 1; }
459
 
 
460
 
  // The index of the context slot in the frame.  It is immediately
461
 
  // below the frame pointer.
462
 
  inline int context_index();
463
 
 
464
 
  // The index of the function slot in the frame.  It is below the frame
465
 
  // pointer and context slot.
466
 
  inline int function_index();
467
 
 
468
 
  // The index of the first local.  Between the frame pointer and the
469
 
  // locals lies the return address.
470
 
  inline int local0_index() const;
471
 
 
472
 
  // The index of the base of the expression stack.
473
 
  inline int expression_base_index() const;
474
 
 
475
 
  // Convert a frame index into a frame pointer relative offset into the
476
 
  // actual stack.
477
 
  inline int fp_relative(int index);
478
 
 
479
 
  // Spill all elements in registers. Spill the top spilled_args elements
480
 
  // on the frame.  Sync all other frame elements.
481
 
  // Then drop dropped_args elements from the virtual frame, to match
482
 
  // the effect of an upcoming call that will drop them from the stack.
483
 
  void PrepareForCall(int spilled_args, int dropped_args);
484
 
 
485
 
  // If all top-of-stack registers are in use then the lowest one is pushed
486
 
  // onto the physical stack and made free.
487
 
  void EnsureOneFreeTOSRegister();
488
 
 
489
 
  // Emit instructions to get the top of stack state from where we are to where
490
 
  // we want to be.
491
 
  void MergeTOSTo(TopOfStack expected_state, Condition cond = al);
492
 
 
493
 
  inline bool Equals(const VirtualFrame* other);
494
 
 
495
 
  inline void LowerHeight(int count) {
496
 
    element_count_ -= count;
497
 
    if (count >= kTOSKnownSmiMapSize) {
498
 
      tos_known_smi_map_ = 0;
499
 
    } else {
500
 
      tos_known_smi_map_ >>= count;
501
 
    }
502
 
  }
503
 
 
504
 
  inline void RaiseHeight(int count, unsigned known_smi_map = 0) {
505
 
    ASSERT(count >= 32 || known_smi_map < (1u << count));
506
 
    element_count_ += count;
507
 
    if (count >= kTOSKnownSmiMapSize) {
508
 
      tos_known_smi_map_ = known_smi_map;
509
 
    } else {
510
 
      tos_known_smi_map_ = ((tos_known_smi_map_ << count) | known_smi_map);
511
 
    }
512
 
  }
513
 
 
514
 
  friend class JumpTarget;
515
 
};
516
 
 
517
 
 
518
 
} }  // namespace v8::internal
519
 
 
520
 
#endif  // V8_ARM_VIRTUAL_FRAME_ARM_H_