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_FRAMES_INL_H_ 29 #define V8_FRAMES_INL_H_ 30 31 #include "frames.h" 32 #include "isolate.h" 33 #include "v8memory.h" 34 35 #if V8_TARGET_ARCH_IA32 36 #include "ia32/frames-ia32.h" 37 #elif V8_TARGET_ARCH_X64 38 #include "x64/frames-x64.h" 39 #elif V8_TARGET_ARCH_ARM 40 #include "arm/frames-arm.h" 41 #elif V8_TARGET_ARCH_MIPS 42 #include "mips/frames-mips.h" 43 #else 44 #error Unsupported target architecture. 45 #endif 46 47 namespace v8 { 48 namespace internal { 49 50 51 inline Address StackHandler::address() const { 52 return reinterpret_cast<Address>(const_cast<StackHandler*>(this)); 53 } 54 55 56 inline StackHandler* StackHandler::next() const { 57 const int offset = StackHandlerConstants::kNextOffset; 58 return FromAddress(Memory::Address_at(address() + offset)); 59 } 60 61 62 inline bool StackHandler::includes(Address address) const { 63 Address start = this->address(); 64 Address end = start + StackHandlerConstants::kSize; 65 return start <= address && address <= end; 66 } 67 68 69 inline void StackHandler::Iterate(ObjectVisitor* v, Code* holder) const { 70 StackFrame::IteratePc(v, pc_address(), holder); 71 } 72 73 74 inline StackHandler* StackHandler::FromAddress(Address address) { 75 return reinterpret_cast<StackHandler*>(address); 76 } 77 78 79 inline StackHandler::State StackHandler::state() const { 80 const int offset = StackHandlerConstants::kStateOffset; 81 return static_cast<State>(Memory::int_at(address() + offset)); 82 } 83 84 85 inline Address* StackHandler::pc_address() const { 86 const int offset = StackHandlerConstants::kPCOffset; 87 return reinterpret_cast<Address*>(address() + offset); 88 } 89 90 91 inline StackFrame::StackFrame(StackFrameIterator* iterator) 92 : iterator_(iterator), isolate_(iterator_->isolate()) { 93 } 94 95 96 inline StackHandler* StackFrame::top_handler() const { 97 return iterator_->handler(); 98 } 99 100 101 inline Code* StackFrame::GetContainingCode(Isolate* isolate, Address pc) { 102 return isolate->pc_to_code_cache()->GetCacheEntry(pc)->code; 103 } 104 105 106 inline Object* StandardFrame::GetExpression(int index) const { 107 return Memory::Object_at(GetExpressionAddress(index)); 108 } 109 110 111 inline void StandardFrame::SetExpression(int index, Object* value) { 112 Memory::Object_at(GetExpressionAddress(index)) = value; 113 } 114 115 116 inline Object* StandardFrame::context() const { 117 const int offset = StandardFrameConstants::kContextOffset; 118 return Memory::Object_at(fp() + offset); 119 } 120 121 122 inline Address StandardFrame::caller_fp() const { 123 return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset); 124 } 125 126 127 inline Address StandardFrame::caller_pc() const { 128 return Memory::Address_at(ComputePCAddress(fp())); 129 } 130 131 132 inline Address StandardFrame::ComputePCAddress(Address fp) { 133 return fp + StandardFrameConstants::kCallerPCOffset; 134 } 135 136 137 inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) { 138 Object* marker = 139 Memory::Object_at(fp + StandardFrameConstants::kContextOffset); 140 return marker == Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR); 141 } 142 143 144 inline bool StandardFrame::IsConstructFrame(Address fp) { 145 Object* marker = 146 Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset); 147 return marker == Smi::FromInt(CONSTRUCT); 148 } 149 150 151 Address JavaScriptFrame::GetParameterSlot(int index) const { 152 int param_count = ComputeParametersCount(); 153 ASSERT(-1 <= index && index < param_count); 154 int parameter_offset = (param_count - index - 1) * kPointerSize; 155 return caller_sp() + parameter_offset; 156 } 157 158 159 Object* JavaScriptFrame::GetParameter(int index) const { 160 return Memory::Object_at(GetParameterSlot(index)); 161 } 162 163 164 inline Object* JavaScriptFrame::receiver() const { 165 return GetParameter(-1); 166 } 167 168 169 inline void JavaScriptFrame::set_receiver(Object* value) { 170 Memory::Object_at(GetParameterSlot(-1)) = value; 171 } 172 173 174 inline bool JavaScriptFrame::has_adapted_arguments() const { 175 return IsArgumentsAdaptorFrame(caller_fp()); 176 } 177 178 179 inline Object* JavaScriptFrame::function() const { 180 Object* result = function_slot_object(); 181 ASSERT(result->IsJSFunction()); 182 return result; 183 } 184 185 186 template<typename Iterator> 187 inline JavaScriptFrameIteratorTemp<Iterator>::JavaScriptFrameIteratorTemp( 188 Isolate* isolate) 189 : iterator_(isolate) { 190 if (!done()) Advance(); 191 } 192 193 template<typename Iterator> 194 inline JavaScriptFrame* JavaScriptFrameIteratorTemp<Iterator>::frame() const { 195 // TODO(1233797): The frame hierarchy needs to change. It's 196 // problematic that we can't use the safe-cast operator to cast to 197 // the JavaScript frame type, because we may encounter arguments 198 // adaptor frames. 199 StackFrame* frame = iterator_.frame(); 200 ASSERT(frame->is_java_script() || frame->is_arguments_adaptor()); 201 return static_cast<JavaScriptFrame*>(frame); 202 } 203 204 205 template<typename Iterator> 206 JavaScriptFrameIteratorTemp<Iterator>::JavaScriptFrameIteratorTemp( 207 Isolate* isolate, StackFrame::Id id) 208 : iterator_(isolate) { 209 AdvanceToId(id); 210 } 211 212 213 template<typename Iterator> 214 void JavaScriptFrameIteratorTemp<Iterator>::Advance() { 215 do { 216 iterator_.Advance(); 217 } while (!iterator_.done() && !iterator_.frame()->is_java_script()); 218 } 219 220 221 template<typename Iterator> 222 void JavaScriptFrameIteratorTemp<Iterator>::AdvanceToArgumentsFrame() { 223 if (!frame()->has_adapted_arguments()) return; 224 iterator_.Advance(); 225 ASSERT(iterator_.frame()->is_arguments_adaptor()); 226 } 227 228 229 template<typename Iterator> 230 void JavaScriptFrameIteratorTemp<Iterator>::AdvanceToId(StackFrame::Id id) { 231 while (!done()) { 232 Advance(); 233 if (frame()->id() == id) return; 234 } 235 } 236 237 238 template<typename Iterator> 239 void JavaScriptFrameIteratorTemp<Iterator>::Reset() { 240 iterator_.Reset(); 241 if (!done()) Advance(); 242 } 243 244 245 } } // namespace v8::internal 246 247 #endif // V8_FRAMES_INL_H_ 248