Cleanup include guards:
[platform/upstream/v8.git] / src / arm / frames-arm.h
1 // Copyright 2006-2008 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_FRAMES_ARM_H_
29 #define V8_ARM_FRAMES_ARM_H_
30
31 namespace v8 { namespace internal {
32
33
34 // The ARM ABI does not specify the usage of register r9, which may be reserved
35 // as the static base or thread register on some platforms, in which case we
36 // leave it alone. Adjust the value of kR9Available accordingly:
37 static const int kR9Available = 1;  // 1 if available to us, 0 if reserved
38
39
40 // Register list in load/store instructions
41 // Note that the bit values must match those used in actual instruction encoding
42 static const int kNumRegs = 16;
43
44
45 // Caller-saved/arguments registers
46 static const RegList kJSCallerSaved =
47   1 << 0 |  // r0 a1
48   1 << 1 |  // r1 a2
49   1 << 2 |  // r2 a3
50   1 << 3;   // r3 a4
51
52 static const int kNumJSCallerSaved = 4;
53
54 typedef Object* JSCallerSavedBuffer[kNumJSCallerSaved];
55
56 // Return the code of the n-th caller-saved register available to JavaScript
57 // e.g. JSCallerSavedReg(0) returns r0.code() == 0
58 int JSCallerSavedCode(int n);
59
60
61 // Callee-saved registers preserved when switching from C to JavaScript
62 static const RegList kCalleeSaved =
63   1 <<  4 |  //  r4 v1
64   1 <<  5 |  //  r5 v2
65   1 <<  6 |  //  r6 v3
66   1 <<  7 |  //  r7 v4
67   1 <<  8 |  //  r8 v5 (cp in JavaScript code)
68   kR9Available
69     <<  9 |  //  r9 v6
70   1 << 10 |  // r10 v7 (pp in JavaScript code)
71   1 << 11;   // r11 v8 (fp in JavaScript code)
72
73 static const int kNumCalleeSaved = 7 + kR9Available;
74
75
76 // ----------------------------------------------------
77
78
79 class StackHandlerConstants : public AllStatic {
80  public:
81   // TODO(1233780): Get rid of the code slot in stack handlers.
82   static const int kCodeOffset  = 0 * kPointerSize;
83   static const int kNextOffset  = 1 * kPointerSize;
84   static const int kStateOffset = 2 * kPointerSize;
85   static const int kPPOffset    = 3 * kPointerSize;
86   static const int kFPOffset    = 4 * kPointerSize;
87   static const int kPCOffset    = 5 * kPointerSize;
88
89   static const int kAddressDisplacement = -1 * kPointerSize;
90   static const int kSize = kPCOffset + kPointerSize;
91 };
92
93
94 class EntryFrameConstants : public AllStatic {
95  public:
96   static const int kCallerFPOffset      = -3 * kPointerSize;
97 };
98
99
100 class ExitFrameConstants : public AllStatic {
101  public:
102   // Exit frames have a debug marker on the stack.
103   static const int kSPDisplacement = -1 * kPointerSize;
104
105   // The debug marker is just above the frame pointer.
106   static const int kDebugMarkOffset = -1 * kPointerSize;
107
108   static const int kSavedRegistersOffset = 0 * kPointerSize;
109
110   // Let the parameters pointer for exit frames point just below the
111   // frame structure on the stack.
112   static const int kPPDisplacement = 3 * kPointerSize;
113
114   // The caller fields are below the frame pointer on the stack.
115   static const int kCallerFPOffset = +0 * kPointerSize;
116   static const int kCallerPPOffset = +1 * kPointerSize;
117   static const int kCallerPCOffset = +2 * kPointerSize;
118 };
119
120
121 class StandardFrameConstants : public AllStatic {
122  public:
123   static const int kExpressionsOffset = -3 * kPointerSize;
124   static const int kMarkerOffset      = -2 * kPointerSize;
125   static const int kContextOffset     = -1 * kPointerSize;
126   static const int kCallerFPOffset    =  0 * kPointerSize;
127   static const int kCallerPCOffset    = +1 * kPointerSize;
128   static const int kCallerSPOffset    = +2 * kPointerSize;
129 };
130
131
132 class JavaScriptFrameConstants : public AllStatic {
133  public:
134   // FP-relative.
135   static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
136   static const int kSavedRegistersOffset = +2 * kPointerSize;
137   static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
138
139   // PP-relative.
140   static const int kParam0Offset   = -2 * kPointerSize;
141   static const int kReceiverOffset = -1 * kPointerSize;
142 };
143
144
145 class ArgumentsAdaptorFrameConstants : public AllStatic {
146  public:
147   static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
148 };
149
150
151 class InternalFrameConstants : public AllStatic {
152  public:
153   static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
154 };
155
156
157 inline Object* JavaScriptFrame::function_slot_object() const {
158   const int offset = JavaScriptFrameConstants::kFunctionOffset;
159   return Memory::Object_at(fp() + offset);
160 }
161
162
163 // ----------------------------------------------------
164
165
166
167
168   //    lower    |    Stack    |
169   //  addresses  |      ^      |
170   //             |      |      |
171   //             |             |
172   //             |  JS frame   |
173   //             |             |
174   //             |             |
175   // ----------- +=============+ <--- sp (stack pointer)
176   //             |  function   |
177   //             +-------------+
178   //             +-------------+
179   //             |             |
180   //             | expressions |
181   //             |             |
182   //             +-------------+
183   //             |             |
184   //      a      |   locals    |
185   //      c      |             |
186   //      t      +- - - - - - -+ <---
187   //      i   -4 |   local0    |   ^
188   //      v      +-------------+   |
189   //      a   -3 |    code     |   |
190   //      t      +-------------+   | kLocal0Offset
191   //      i   -2 |   context   |   |
192   //      o      +-------------+   |
193   //      n   -1 | args_length |   v
194   //             +-------------+ <--- fp (frame pointer)
195   //           0 |  caller_pp  |
196   //      f      +-------------+
197   //      r    1 |  caller_fp  |
198   //      a      +-------------+
199   //      m    2 |  sp_on_exit |  (pp if return, caller_sp if no return)
200   //      e      +-------------+
201   //           3 |  caller_pc  |
202   //             +-------------+ <--- caller_sp (incl. parameters)
203   //             |             |
204   //             | parameters  |
205   //             |             |
206   //             +- - - - - - -+ <---
207   //          -2 | parameter0  |   ^
208   //             +-------------+   | kParam0Offset
209   //          -1 |  receiver   |   v
210   // ----------- +=============+ <--- pp (parameter pointer, r10)
211   //           0 |  function   |
212   //             +-------------+
213   //             |             |
214   //             |caller-saved |  (must be valid JS values, traversed during GC)
215   //             |    regs     |
216   //             |             |
217   //             +-------------+
218   //             |             |
219   //             |   caller    |
220   //   higher    | expressions |
221   //  addresses  |             |
222   //             |             |
223   //             |  JS frame   |
224
225
226
227   // Handler frames (part of expressions of JS frames):
228
229   //    lower    |    Stack    |
230   //  addresses  |      ^      |
231   //             |      |      |
232   //             |             |
233   //      h      | expressions |
234   //      a      |             |
235   //      n      +-------------+
236   //      d   -1 |    code     |
237   //      l      +-------------+ <--- handler sp
238   //      e    0 |   next_sp   |  link to next handler (next handler's sp)
239   //      r      +-------------+
240   //           1 |    state    |
241   //      f      +-------------+
242   //      r    2 |     pp      |
243   //      a      +-------------+
244   //      m    3 |     fp      |
245   //      e      +-------------+
246   //           4 |     pc      |
247   //             +-------------+
248   //             |             |
249   //   higher    | expressions |
250   //  addresses  |             |
251
252
253
254   // JS entry frames: When calling from C to JS, we construct two extra
255   // frames: An entry frame (C) and a trampoline frame (JS). The
256   // following pictures shows the two frames:
257
258   //    lower    |    Stack    |
259   //  addresses  |      ^      |
260   //             |      |      |
261   //             |             |
262   //             |  JS frame   |
263   //             |             |
264   //             |             |
265   // ----------- +=============+ <--- sp (stack pointer)
266   //             |             |
267   //             | parameters  |
268   //      t      |             |
269   //      r      +- - - - - - -+
270   //      a      | parameter0  |
271   //      m      +-------------+
272   //      p      |  receiver   |
273   //      o      +-------------+
274   //      l      |  function   |
275   //      i      +-------------+
276   //      n   -3 |    code     |
277   //      e      +-------------+
278   //          -2 |    NULL     |  context is always NULL
279   //             +-------------+
280   //      f   -1 |      0      |  args_length is always zero
281   //      r      +-------------+ <--- fp (frame pointer)
282   //      a    0 |    NULL     |  caller pp is always NULL for entries
283   //      m      +-------------+
284   //      e    1 |  caller_fp  |
285   //             +-------------+
286   //           2 |  sp_on_exit |  (caller_sp)
287   //             +-------------+
288   //           3 |  caller_pc  |
289   // ----------- +=============+ <--- caller_sp == pp
290   //                    .          ^
291   //                    .          |  try-handler, fake, not GC'ed
292   //                    .          v
293   //             +-------------+ <---
294   //          -2 | next top pp |
295   //             +-------------+
296   //          -1 | next top fp |
297   //             +-------------+ <--- fp
298   //             |     r4      |  r4-r9 holding non-JS values must be preserved
299   //             +-------------+
300   //      J      |     r5      |  before being initialized not to confuse GC
301   //      S      +-------------+
302   //             |     r6      |
303   //             +-------------+
304   //      e      |     r7      |
305   //      n      +-------------+
306   //      t      |     r8      |
307   //      r      +-------------+
308   //      y    [ |     r9      | ]  only if r9 available
309   //             +-------------+
310   //             |     r10     |
311   //      f      +-------------+
312   //      r      |     r11     |
313   //      a      +-------------+
314   //      m      |  caller_sp  |
315   //      e      +-------------+
316   //             |  caller_pc  |
317   //             +-------------+ <--- caller_sp
318   //             |    argv     |    passed on stack from C code
319   //             +-------------+
320   //             |             |
321   //   higher    |             |
322   //  addresses  |   C frame   |
323
324
325   // The first 4 args are passed from C in r0-r3 and are not spilled on entry:
326   // r0: code entry
327   // r1: function
328   // r2: receiver
329   // r3: argc
330   // [sp+0]: argv
331
332
333   // C entry frames: When calling from JS to C, we construct one extra
334   // frame:
335
336   //    lower    |    Stack    |
337   //  addresses  |      ^      |
338   //             |      |      |
339   //             |             |
340   //             |   C frame   |
341   //             |             |
342   //             |             |
343   // ----------- +=============+ <--- sp (stack pointer)
344   //             |             |
345   //             | parameters  |  (first 4 args are passed in r0-r3)
346   //             |             |
347   //             +-------------+ <--- fp (frame pointer)
348   //      f  4/5 |  caller_fp  |
349   //      r      +-------------+
350   //      a  5/6 |  sp_on_exit |  (pp)
351   //      m      +-------------+
352   //      e  6/7 |  caller_pc  |
353   //             +-------------+ <--- caller_sp (incl. parameters)
354   //         7/8 |             |
355   //             | parameters  |
356   //             |             |
357   //             +- - - - - - -+ <---
358   //          -2 | parameter0  |   ^
359   //             +-------------+   | kParam0Offset
360   //          -1 |  receiver   |   v
361   // ----------- +=============+ <--- pp (parameter pointer, r10)
362   //           0 |  function   |
363   //             +-------------+
364   //             |             |
365   //             |caller-saved |
366   //             |    regs     |
367   //             |             |
368   //             +-------------+
369   //             |             |
370   //             |   caller    |
371   //             | expressions |
372   //             |             |
373   //   higher    |             |
374   //  addresses  |  JS frame   |
375
376
377 } }  // namespace v8::internal
378
379 #endif  // V8_ARM_FRAMES_ARM_H_