Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_FRAMES_INL_H_
      6 #define V8_FRAMES_INL_H_
      7 
      8 #include "src/frames.h"
      9 #include "src/isolate.h"
     10 #include "src/v8memory.h"
     11 
     12 #if V8_TARGET_ARCH_IA32
     13 #include "src/ia32/frames-ia32.h"  // NOLINT
     14 #elif V8_TARGET_ARCH_X64
     15 #include "src/x64/frames-x64.h"  // NOLINT
     16 #elif V8_TARGET_ARCH_ARM64
     17 #include "src/arm64/frames-arm64.h"  // NOLINT
     18 #elif V8_TARGET_ARCH_ARM
     19 #include "src/arm/frames-arm.h"  // NOLINT
     20 #elif V8_TARGET_ARCH_MIPS
     21 #include "src/mips/frames-mips.h"  // NOLINT
     22 #elif V8_TARGET_ARCH_MIPS64
     23 #include "src/mips64/frames-mips64.h"  // NOLINT
     24 #elif V8_TARGET_ARCH_X87
     25 #include "src/x87/frames-x87.h"  // NOLINT
     26 #else
     27 #error Unsupported target architecture.
     28 #endif
     29 
     30 namespace v8 {
     31 namespace internal {
     32 
     33 
     34 inline Address StackHandler::address() const {
     35   return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
     36 }
     37 
     38 
     39 inline StackHandler* StackHandler::next() const {
     40   const int offset = StackHandlerConstants::kNextOffset;
     41   return FromAddress(Memory::Address_at(address() + offset));
     42 }
     43 
     44 
     45 inline bool StackHandler::includes(Address address) const {
     46   Address start = this->address();
     47   Address end = start + StackHandlerConstants::kSize;
     48   return start <= address && address <= end;
     49 }
     50 
     51 
     52 inline void StackHandler::Iterate(ObjectVisitor* v, Code* holder) const {
     53   v->VisitPointer(context_address());
     54   v->VisitPointer(code_address());
     55 }
     56 
     57 
     58 inline StackHandler* StackHandler::FromAddress(Address address) {
     59   return reinterpret_cast<StackHandler*>(address);
     60 }
     61 
     62 
     63 inline bool StackHandler::is_js_entry() const {
     64   return kind() == JS_ENTRY;
     65 }
     66 
     67 
     68 inline bool StackHandler::is_catch() const {
     69   return kind() == CATCH;
     70 }
     71 
     72 
     73 inline bool StackHandler::is_finally() const {
     74   return kind() == FINALLY;
     75 }
     76 
     77 
     78 inline StackHandler::Kind StackHandler::kind() const {
     79   const int offset = StackHandlerConstants::kStateOffset;
     80   return KindField::decode(Memory::unsigned_at(address() + offset));
     81 }
     82 
     83 
     84 inline unsigned StackHandler::index() const {
     85   const int offset = StackHandlerConstants::kStateOffset;
     86   return IndexField::decode(Memory::unsigned_at(address() + offset));
     87 }
     88 
     89 
     90 inline Object** StackHandler::context_address() const {
     91   const int offset = StackHandlerConstants::kContextOffset;
     92   return reinterpret_cast<Object**>(address() + offset);
     93 }
     94 
     95 
     96 inline Object** StackHandler::code_address() const {
     97   const int offset = StackHandlerConstants::kCodeOffset;
     98   return reinterpret_cast<Object**>(address() + offset);
     99 }
    100 
    101 
    102 inline StackFrame::StackFrame(StackFrameIteratorBase* iterator)
    103     : iterator_(iterator), isolate_(iterator_->isolate()) {
    104 }
    105 
    106 
    107 inline StackHandler* StackFrame::top_handler() const {
    108   return iterator_->handler();
    109 }
    110 
    111 
    112 inline Code* StackFrame::LookupCode() const {
    113   return GetContainingCode(isolate(), pc());
    114 }
    115 
    116 
    117 inline Code* StackFrame::GetContainingCode(Isolate* isolate, Address pc) {
    118   return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
    119 }
    120 
    121 
    122 inline Address* StackFrame::ResolveReturnAddressLocation(Address* pc_address) {
    123   if (return_address_location_resolver_ == NULL) {
    124     return pc_address;
    125   } else {
    126     return reinterpret_cast<Address*>(
    127         return_address_location_resolver_(
    128             reinterpret_cast<uintptr_t>(pc_address)));
    129   }
    130 }
    131 
    132 
    133 inline EntryFrame::EntryFrame(StackFrameIteratorBase* iterator)
    134     : StackFrame(iterator) {
    135 }
    136 
    137 
    138 inline EntryConstructFrame::EntryConstructFrame(
    139     StackFrameIteratorBase* iterator)
    140     : EntryFrame(iterator) {
    141 }
    142 
    143 
    144 inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
    145     : StackFrame(iterator) {
    146 }
    147 
    148 
    149 inline StandardFrame::StandardFrame(StackFrameIteratorBase* iterator)
    150     : StackFrame(iterator) {
    151 }
    152 
    153 
    154 inline Object* StandardFrame::GetExpression(int index) const {
    155   return Memory::Object_at(GetExpressionAddress(index));
    156 }
    157 
    158 
    159 inline void StandardFrame::SetExpression(int index, Object* value) {
    160   Memory::Object_at(GetExpressionAddress(index)) = value;
    161 }
    162 
    163 
    164 inline Object* StandardFrame::context() const {
    165   const int offset = StandardFrameConstants::kContextOffset;
    166   return Memory::Object_at(fp() + offset);
    167 }
    168 
    169 
    170 inline Address StandardFrame::caller_fp() const {
    171   return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset);
    172 }
    173 
    174 
    175 inline Address StandardFrame::caller_pc() const {
    176   return Memory::Address_at(ComputePCAddress(fp()));
    177 }
    178 
    179 
    180 inline Address StandardFrame::ComputePCAddress(Address fp) {
    181   return fp + StandardFrameConstants::kCallerPCOffset;
    182 }
    183 
    184 
    185 inline Address StandardFrame::ComputeConstantPoolAddress(Address fp) {
    186   return fp + StandardFrameConstants::kConstantPoolOffset;
    187 }
    188 
    189 
    190 inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
    191   Object* marker =
    192       Memory::Object_at(fp + StandardFrameConstants::kContextOffset);
    193   return marker == Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR);
    194 }
    195 
    196 
    197 inline bool StandardFrame::IsConstructFrame(Address fp) {
    198   Object* marker =
    199       Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset);
    200   return marker == Smi::FromInt(StackFrame::CONSTRUCT);
    201 }
    202 
    203 
    204 inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
    205     : StandardFrame(iterator) {
    206 }
    207 
    208 
    209 Address JavaScriptFrame::GetParameterSlot(int index) const {
    210   int param_count = ComputeParametersCount();
    211   DCHECK(-1 <= index && index < param_count);
    212   int parameter_offset = (param_count - index - 1) * kPointerSize;
    213   return caller_sp() + parameter_offset;
    214 }
    215 
    216 
    217 Object* JavaScriptFrame::GetParameter(int index) const {
    218   return Memory::Object_at(GetParameterSlot(index));
    219 }
    220 
    221 
    222 inline Address JavaScriptFrame::GetOperandSlot(int index) const {
    223   Address base = fp() + JavaScriptFrameConstants::kLocal0Offset;
    224   DCHECK(IsAddressAligned(base, kPointerSize));
    225   DCHECK_EQ(type(), JAVA_SCRIPT);
    226   DCHECK_LT(index, ComputeOperandsCount());
    227   DCHECK_LE(0, index);
    228   // Operand stack grows down.
    229   return base - index * kPointerSize;
    230 }
    231 
    232 
    233 inline Object* JavaScriptFrame::GetOperand(int index) const {
    234   return Memory::Object_at(GetOperandSlot(index));
    235 }
    236 
    237 
    238 inline int JavaScriptFrame::ComputeOperandsCount() const {
    239   Address base = fp() + JavaScriptFrameConstants::kLocal0Offset;
    240   // Base points to low address of first operand and stack grows down, so add
    241   // kPointerSize to get the actual stack size.
    242   intptr_t stack_size_in_bytes = (base + kPointerSize) - sp();
    243   DCHECK(IsAligned(stack_size_in_bytes, kPointerSize));
    244   DCHECK(type() == JAVA_SCRIPT);
    245   DCHECK(stack_size_in_bytes >= 0);
    246   return static_cast<int>(stack_size_in_bytes >> kPointerSizeLog2);
    247 }
    248 
    249 
    250 inline Object* JavaScriptFrame::receiver() const {
    251   return GetParameter(-1);
    252 }
    253 
    254 
    255 inline void JavaScriptFrame::set_receiver(Object* value) {
    256   Memory::Object_at(GetParameterSlot(-1)) = value;
    257 }
    258 
    259 
    260 inline bool JavaScriptFrame::has_adapted_arguments() const {
    261   return IsArgumentsAdaptorFrame(caller_fp());
    262 }
    263 
    264 
    265 inline JSFunction* JavaScriptFrame::function() const {
    266   return JSFunction::cast(function_slot_object());
    267 }
    268 
    269 
    270 inline StubFrame::StubFrame(StackFrameIteratorBase* iterator)
    271     : StandardFrame(iterator) {
    272 }
    273 
    274 
    275 inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
    276     : JavaScriptFrame(iterator) {
    277 }
    278 
    279 
    280 inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
    281     StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) {
    282 }
    283 
    284 
    285 inline InternalFrame::InternalFrame(StackFrameIteratorBase* iterator)
    286     : StandardFrame(iterator) {
    287 }
    288 
    289 
    290 inline StubFailureTrampolineFrame::StubFailureTrampolineFrame(
    291     StackFrameIteratorBase* iterator) : StandardFrame(iterator) {
    292 }
    293 
    294 
    295 inline ConstructFrame::ConstructFrame(StackFrameIteratorBase* iterator)
    296     : InternalFrame(iterator) {
    297 }
    298 
    299 
    300 inline JavaScriptFrameIterator::JavaScriptFrameIterator(
    301     Isolate* isolate)
    302     : iterator_(isolate) {
    303   if (!done()) Advance();
    304 }
    305 
    306 
    307 inline JavaScriptFrameIterator::JavaScriptFrameIterator(
    308     Isolate* isolate, ThreadLocalTop* top)
    309     : iterator_(isolate, top) {
    310   if (!done()) Advance();
    311 }
    312 
    313 
    314 inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
    315   // TODO(1233797): The frame hierarchy needs to change. It's
    316   // problematic that we can't use the safe-cast operator to cast to
    317   // the JavaScript frame type, because we may encounter arguments
    318   // adaptor frames.
    319   StackFrame* frame = iterator_.frame();
    320   DCHECK(frame->is_java_script() || frame->is_arguments_adaptor());
    321   return static_cast<JavaScriptFrame*>(frame);
    322 }
    323 
    324 
    325 inline StackFrame* SafeStackFrameIterator::frame() const {
    326   DCHECK(!done());
    327   DCHECK(frame_->is_java_script() || frame_->is_exit());
    328   return frame_;
    329 }
    330 
    331 
    332 } }  // namespace v8::internal
    333 
    334 #endif  // V8_FRAMES_INL_H_
    335