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