00001 // Copyright 2006-2008 the V8 project authors. All rights reserved. 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions are 00004 // met: 00005 // 00006 // * Redistributions of source code must retain the above copyright 00007 // notice, this list of conditions and the following disclaimer. 00008 // * Redistributions in binary form must reproduce the above 00009 // copyright notice, this list of conditions and the following 00010 // disclaimer in the documentation and/or other materials provided 00011 // with the distribution. 00012 // * Neither the name of Google Inc. nor the names of its 00013 // contributors may be used to endorse or promote products derived 00014 // from this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00020 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00021 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00026 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 #ifndef V8_FRAMES_IA32_H_ 00029 #define V8_FRAMES_IA32_H_ 00030 00031 namespace v8 { namespace internal { 00032 00033 00034 // Register lists 00035 // Note that the bit values must match those used in actual instruction encoding 00036 static const int kNumRegs = 8; 00037 00038 00039 // Caller-saved registers 00040 static const RegList kJSCallerSaved = 00041 1 << 0 | // eax 00042 1 << 1 | // ecx 00043 1 << 2 | // edx 00044 1 << 3 | // ebx - used as a caller-saved register in JavaScript code 00045 1 << 7; // edi - callee function 00046 00047 static const int kNumJSCallerSaved = 5; 00048 00049 typedef Object* JSCallerSavedBuffer[kNumJSCallerSaved]; 00050 00051 // ---------------------------------------------------- 00052 00053 00054 class StackHandlerConstants : public AllStatic { 00055 public: 00056 static const int kNextOffset = 0 * kPointerSize; 00057 static const int kPPOffset = 1 * kPointerSize; 00058 static const int kFPOffset = 2 * kPointerSize; 00059 00060 // TODO(1233780): Get rid of the code slot in stack handlers. 00061 static const int kCodeOffset = 3 * kPointerSize; 00062 00063 static const int kStateOffset = 4 * kPointerSize; 00064 static const int kPCOffset = 5 * kPointerSize; 00065 00066 static const int kAddressDisplacement = -1 * kPointerSize; 00067 static const int kSize = kPCOffset + kPointerSize; 00068 }; 00069 00070 00071 class EntryFrameConstants : public AllStatic { 00072 public: 00073 static const int kCallerFPOffset = -6 * kPointerSize; 00074 00075 static const int kFunctionArgOffset = +3 * kPointerSize; 00076 static const int kReceiverArgOffset = +4 * kPointerSize; 00077 static const int kArgcOffset = +5 * kPointerSize; 00078 static const int kArgvOffset = +6 * kPointerSize; 00079 }; 00080 00081 00082 class ExitFrameConstants : public AllStatic { 00083 public: 00084 static const int kDebugMarkOffset = -2 * kPointerSize; 00085 static const int kSPOffset = -1 * kPointerSize; 00086 00087 // Let the parameters pointer for exit frames point just below the 00088 // frame structure on the stack (frame pointer and return address). 00089 static const int kPPDisplacement = +2 * kPointerSize; 00090 00091 static const int kCallerFPOffset = 0 * kPointerSize; 00092 static const int kCallerPCOffset = +1 * kPointerSize; 00093 }; 00094 00095 00096 class StandardFrameConstants : public AllStatic { 00097 public: 00098 static const int kExpressionsOffset = -3 * kPointerSize; 00099 static const int kMarkerOffset = -2 * kPointerSize; 00100 static const int kContextOffset = -1 * kPointerSize; 00101 static const int kCallerFPOffset = 0 * kPointerSize; 00102 static const int kCallerPCOffset = +1 * kPointerSize; 00103 static const int kCallerSPOffset = +2 * kPointerSize; 00104 }; 00105 00106 00107 class JavaScriptFrameConstants : public AllStatic { 00108 public: 00109 // FP-relative. 00110 static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset; 00111 static const int kSavedRegistersOffset = +2 * kPointerSize; 00112 static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset; 00113 00114 // CallerSP-relative (aka PP-relative) 00115 static const int kParam0Offset = -2 * kPointerSize; 00116 static const int kReceiverOffset = -1 * kPointerSize; 00117 }; 00118 00119 00120 class ArgumentsAdaptorFrameConstants : public AllStatic { 00121 public: 00122 static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset; 00123 }; 00124 00125 00126 class InternalFrameConstants : public AllStatic { 00127 public: 00128 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset; 00129 }; 00130 00131 00132 inline Object* JavaScriptFrame::function() const { 00133 const int offset = JavaScriptFrameConstants::kFunctionOffset; 00134 Object* result = Memory::Object_at(fp() + offset); 00135 ASSERT(result->IsJSFunction()); 00136 return result; 00137 } 00138 00139 00140 // ---------------------------------------------------- 00141 00142 00143 00144 00145 // C Entry frames: 00146 00147 // lower | Stack | 00148 // addresses | ^ | 00149 // | | | 00150 // | | 00151 // +-------------+ 00152 // | entry_pc | 00153 // +-------------+ <--+ entry_sp 00154 // . | 00155 // . | 00156 // . | 00157 // +-------------+ | 00158 // -3 | entry_sp --+----+ 00159 // e +-------------+ 00160 // n -2 | C function | 00161 // t +-------------+ 00162 // r -1 | caller_pp | 00163 // y +-------------+ <--- fp (frame pointer, ebp) 00164 // 0 | caller_fp | 00165 // f +-------------+ 00166 // r 1 | caller_pc | 00167 // a +-------------+ <--- caller_sp (stack pointer, esp) 00168 // m 2 | | 00169 // e | arguments | 00170 // | | 00171 // +- - - - - - -+ 00172 // | argument0 | 00173 // +=============+ 00174 // | | 00175 // | caller | 00176 // higher | expressions | 00177 // addresses | | 00178 00179 00180 // Proper JS frames: 00181 00182 // lower | Stack | 00183 // addresses | ^ | 00184 // | | | 00185 // | | 00186 // ----------- +=============+ <--- sp (stack pointer, esp) 00187 // | function | 00188 // +-------------+ 00189 // | | 00190 // | expressions | 00191 // | | 00192 // +-------------+ 00193 // a | | 00194 // c | locals | 00195 // t | | 00196 // i +- - - - - - -+ <--- 00197 // v -4 | local0 | ^ 00198 // a +-------------+ | 00199 // t -3 | code | | 00200 // i +-------------+ | 00201 // o -2 | context | | kLocal0Offset 00202 // n +-------------+ | 00203 // -1 | caller_pp | v 00204 // f +-------------+ <--- fp (frame pointer, ebp) 00205 // r 0 | caller_fp | 00206 // a +-------------+ 00207 // m 1 | caller_pc | 00208 // e +-------------+ <--- caller_sp (incl. parameters) 00209 // 2 | | 00210 // | parameters | 00211 // | | 00212 // +- - - - - - -+ <--- 00213 // -2 | parameter0 | ^ 00214 // +-------------+ | kParam0Offset 00215 // -1 | receiver | v 00216 // ----------- +=============+ <--- pp (parameter pointer, edi) 00217 // 0 | function | 00218 // +-------------+ 00219 // | | 00220 // | caller | 00221 // higher | expressions | 00222 // addresses | | 00223 00224 00225 // JS entry frames: When calling from C to JS, we construct two extra 00226 // frames: An entry frame (C) and a trampoline frame (JS). The 00227 // following pictures shows the two frames: 00228 00229 // lower | Stack | 00230 // addresses | ^ | 00231 // | | | 00232 // | | 00233 // ----------- +=============+ <--- sp (stack pointer, esp) 00234 // | | 00235 // | parameters | 00236 // t | | 00237 // r +- - - - - - -+ 00238 // a | parameter0 | 00239 // m +-------------+ 00240 // p | receiver | 00241 // o +-------------+ <--- 00242 // l | function | ^ 00243 // i +-------------+ | 00244 // n -3 | code | | kLocal0Offset 00245 // e +-------------+ 00246 // -2 | NULL | context is always NULL 00247 // +-------------+ 00248 // f -1 | NULL | caller pp is always NULL for entry frames 00249 // r +-------------+ <--- fp (frame pointer, ebp) 00250 // a 0 | caller fp | 00251 // m +-------------+ 00252 // e 1 | caller pc | 00253 // +-------------+ <--- caller_sp (incl. parameters) 00254 // | 0 | 00255 // ----------- +=============+ <--- pp (parameter pointer, edi) 00256 // | 0 | 00257 // +-------------+ <--- 00258 // . ^ 00259 // . | try-handler (HandlerOffsets::kSize) 00260 // . v 00261 // +-------------+ <--- 00262 // -5 | next top pp | 00263 // +-------------+ 00264 // e -4 | next top fp | 00265 // n +-------------+ <--- 00266 // t -3 | ebx | ^ 00267 // r +-------------+ | 00268 // y -2 | esi | | callee-saved registers 00269 // +-------------+ | 00270 // -1 | edi | v 00271 // f +-------------+ <--- fp 00272 // r 0 | caller fp | 00273 // a +-------------+ pp == NULL (parameter pointer) 00274 // m 1 | caller pc | 00275 // e +-------------+ <--- caller sp 00276 // 2 | code entry | ^ 00277 // +-------------+ | 00278 // 3 | function | | 00279 // +-------------+ | arguments passed from C code 00280 // 4 | receiver | | 00281 // +-------------+ | 00282 // 5 | argc | | 00283 // +-------------+ | 00284 // 6 | argv | v 00285 // +-------------+ <--- 00286 // | | 00287 // higher | | 00288 // addresses | | 00289 00290 00291 } } // namespace v8::internal 00292 00293 #endif // V8_FRAMES_IA32_H_