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 #include "v8.h" 00029 00030 #include "frames-inl.h" 00031 00032 namespace v8 { namespace internal { 00033 00034 00035 StackFrame::Type StackFrame::ComputeType(State* state) { 00036 ASSERT(state->fp != NULL); 00037 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { 00038 return ARGUMENTS_ADAPTOR; 00039 } 00040 // The marker and function offsets overlap. If the marker isn't a 00041 // smi then the frame is a JavaScript frame -- and the marker is 00042 // really the function. 00043 const int offset = StandardFrameConstants::kMarkerOffset; 00044 Object* marker = Memory::Object_at(state->fp + offset); 00045 if (!marker->IsSmi()) return JAVA_SCRIPT; 00046 return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); 00047 } 00048 00049 00050 StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { 00051 if (fp == 0) return NONE; 00052 // Compute the stack pointer. 00053 Address sp = Memory::Address_at(fp + ExitFrameConstants::kSPOffset); 00054 // Fill in the state. 00055 state->fp = fp; 00056 state->sp = sp; 00057 state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize); 00058 // Determine frame type. 00059 if (Memory::Address_at(fp + ExitFrameConstants::kDebugMarkOffset) != 0) { 00060 return EXIT_DEBUG; 00061 } else { 00062 return EXIT; 00063 } 00064 } 00065 00066 00067 void ExitFrame::Iterate(ObjectVisitor* v) const { 00068 // Exit frames on IA-32 do not contain any pointers. The arguments 00069 // are traversed as part of the expression stack of the calling 00070 // frame. 00071 } 00072 00073 00074 int JavaScriptFrame::GetProvidedParametersCount() const { 00075 return ComputeParametersCount(); 00076 } 00077 00078 00079 Address JavaScriptFrame::GetCallerStackPointer() const { 00080 int arguments; 00081 if (Heap::gc_state() != Heap::NOT_IN_GC) { 00082 // The arguments for cooked frames are traversed as if they were 00083 // expression stack elements of the calling frame. The reason for 00084 // this rather strange decision is that we cannot access the 00085 // function during mark-compact GCs when the stack is cooked. 00086 // In fact accessing heap objects (like function->shared() below) 00087 // at all during GC is problematic. 00088 arguments = 0; 00089 } else { 00090 // Compute the number of arguments by getting the number of formal 00091 // parameters of the function. We must remember to take the 00092 // receiver into account (+1). 00093 JSFunction* function = JSFunction::cast(this->function()); 00094 arguments = function->shared()->formal_parameter_count() + 1; 00095 } 00096 const int offset = StandardFrameConstants::kCallerSPOffset; 00097 return fp() + offset + (arguments * kPointerSize); 00098 } 00099 00100 00101 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const { 00102 const int arguments = Smi::cast(GetExpression(0))->value(); 00103 const int offset = StandardFrameConstants::kCallerSPOffset; 00104 return fp() + offset + (arguments + 1) * kPointerSize; 00105 } 00106 00107 00108 Address InternalFrame::GetCallerStackPointer() const { 00109 // Internal frames have no arguments. The stack pointer of the 00110 // caller is at a fixed offset from the frame pointer. 00111 return fp() + StandardFrameConstants::kCallerSPOffset; 00112 } 00113 00114 00115 Code* JavaScriptFrame::FindCode() const { 00116 JSFunction* function = JSFunction::cast(this->function()); 00117 return function->shared()->code(); 00118 } 00119 00120 00121 } } // namespace v8::internal