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