Home | History | Annotate | Download | only in src
      1 // Copyright 2012 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   v->VisitPointer(context_address());
     71   v->VisitPointer(code_address());
     72 }
     73 
     74 
     75 inline StackHandler* StackHandler::FromAddress(Address address) {
     76   return reinterpret_cast<StackHandler*>(address);
     77 }
     78 
     79 
     80 inline bool StackHandler::is_js_entry() const {
     81   return kind() == JS_ENTRY;
     82 }
     83 
     84 
     85 inline bool StackHandler::is_catch() const {
     86   return kind() == CATCH;
     87 }
     88 
     89 
     90 inline bool StackHandler::is_finally() const {
     91   return kind() == FINALLY;
     92 }
     93 
     94 
     95 inline StackHandler::Kind StackHandler::kind() const {
     96   const int offset = StackHandlerConstants::kStateOffset;
     97   return KindField::decode(Memory::unsigned_at(address() + offset));
     98 }
     99 
    100 
    101 inline Object** StackHandler::context_address() const {
    102   const int offset = StackHandlerConstants::kContextOffset;
    103   return reinterpret_cast<Object**>(address() + offset);
    104 }
    105 
    106 
    107 inline Object** StackHandler::code_address() const {
    108   const int offset = StackHandlerConstants::kCodeOffset;
    109   return reinterpret_cast<Object**>(address() + offset);
    110 }
    111 
    112 
    113 inline StackFrame::StackFrame(StackFrameIterator* iterator)
    114     : iterator_(iterator), isolate_(iterator_->isolate()) {
    115 }
    116 
    117 
    118 inline StackHandler* StackFrame::top_handler() const {
    119   return iterator_->handler();
    120 }
    121 
    122 
    123 inline Code* StackFrame::LookupCode() const {
    124   return GetContainingCode(isolate(), pc());
    125 }
    126 
    127 
    128 inline Code* StackFrame::GetContainingCode(Isolate* isolate, Address pc) {
    129   return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
    130 }
    131 
    132 
    133 inline EntryFrame::EntryFrame(StackFrameIterator* iterator)
    134     : StackFrame(iterator) {
    135 }
    136 
    137 
    138 inline EntryConstructFrame::EntryConstructFrame(StackFrameIterator* iterator)
    139     : EntryFrame(iterator) {
    140 }
    141 
    142 
    143 inline ExitFrame::ExitFrame(StackFrameIterator* iterator)
    144     : StackFrame(iterator) {
    145 }
    146 
    147 
    148 inline StandardFrame::StandardFrame(StackFrameIterator* iterator)
    149     : StackFrame(iterator) {
    150 }
    151 
    152 
    153 inline Object* StandardFrame::GetExpression(int index) const {
    154   return Memory::Object_at(GetExpressionAddress(index));
    155 }
    156 
    157 
    158 inline void StandardFrame::SetExpression(int index, Object* value) {
    159   Memory::Object_at(GetExpressionAddress(index)) = value;
    160 }
    161 
    162 
    163 inline Object* StandardFrame::context() const {
    164   const int offset = StandardFrameConstants::kContextOffset;
    165   return Memory::Object_at(fp() + offset);
    166 }
    167 
    168 
    169 inline Address StandardFrame::caller_fp() const {
    170   return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset);
    171 }
    172 
    173 
    174 inline Address StandardFrame::caller_pc() const {
    175   return Memory::Address_at(ComputePCAddress(fp()));
    176 }
    177 
    178 
    179 inline Address StandardFrame::ComputePCAddress(Address fp) {
    180   return fp + StandardFrameConstants::kCallerPCOffset;
    181 }
    182 
    183 
    184 inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
    185   Object* marker =
    186       Memory::Object_at(fp + StandardFrameConstants::kContextOffset);
    187   return marker == Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR);
    188 }
    189 
    190 
    191 inline bool StandardFrame::IsConstructFrame(Address fp) {
    192   Object* marker =
    193       Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset);
    194   return marker == Smi::FromInt(StackFrame::CONSTRUCT);
    195 }
    196 
    197 
    198 inline JavaScriptFrame::JavaScriptFrame(StackFrameIterator* iterator)
    199     : StandardFrame(iterator) {
    200 }
    201 
    202 
    203 Address JavaScriptFrame::GetParameterSlot(int index) const {
    204   int param_count = ComputeParametersCount();
    205   ASSERT(-1 <= index && index < param_count);
    206   int parameter_offset = (param_count - index - 1) * kPointerSize;
    207   return caller_sp() + parameter_offset;
    208 }
    209 
    210 
    211 Object* JavaScriptFrame::GetParameter(int index) const {
    212   return Memory::Object_at(GetParameterSlot(index));
    213 }
    214 
    215 
    216 inline Object* JavaScriptFrame::receiver() const {
    217   return GetParameter(-1);
    218 }
    219 
    220 
    221 inline void JavaScriptFrame::set_receiver(Object* value) {
    222   Memory::Object_at(GetParameterSlot(-1)) = value;
    223 }
    224 
    225 
    226 inline bool JavaScriptFrame::has_adapted_arguments() const {
    227   return IsArgumentsAdaptorFrame(caller_fp());
    228 }
    229 
    230 
    231 inline Object* JavaScriptFrame::function() const {
    232   Object* result = function_slot_object();
    233   ASSERT(result->IsJSFunction());
    234   return result;
    235 }
    236 
    237 
    238 inline OptimizedFrame::OptimizedFrame(StackFrameIterator* iterator)
    239     : JavaScriptFrame(iterator) {
    240 }
    241 
    242 
    243 inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
    244     StackFrameIterator* iterator) : JavaScriptFrame(iterator) {
    245 }
    246 
    247 
    248 inline InternalFrame::InternalFrame(StackFrameIterator* iterator)
    249     : StandardFrame(iterator) {
    250 }
    251 
    252 
    253 inline ConstructFrame::ConstructFrame(StackFrameIterator* iterator)
    254     : InternalFrame(iterator) {
    255 }
    256 
    257 
    258 template<typename Iterator>
    259 inline JavaScriptFrameIteratorTemp<Iterator>::JavaScriptFrameIteratorTemp(
    260     Isolate* isolate)
    261     : iterator_(isolate) {
    262   if (!done()) Advance();
    263 }
    264 
    265 
    266 template<typename Iterator>
    267 inline JavaScriptFrameIteratorTemp<Iterator>::JavaScriptFrameIteratorTemp(
    268     Isolate* isolate, ThreadLocalTop* top)
    269     : iterator_(isolate, top) {
    270   if (!done()) Advance();
    271 }
    272 
    273 
    274 template<typename Iterator>
    275 inline JavaScriptFrame* JavaScriptFrameIteratorTemp<Iterator>::frame() const {
    276   // TODO(1233797): The frame hierarchy needs to change. It's
    277   // problematic that we can't use the safe-cast operator to cast to
    278   // the JavaScript frame type, because we may encounter arguments
    279   // adaptor frames.
    280   StackFrame* frame = iterator_.frame();
    281   ASSERT(frame->is_java_script() || frame->is_arguments_adaptor());
    282   return static_cast<JavaScriptFrame*>(frame);
    283 }
    284 
    285 
    286 template<typename Iterator>
    287 JavaScriptFrameIteratorTemp<Iterator>::JavaScriptFrameIteratorTemp(
    288     Isolate* isolate, StackFrame::Id id)
    289     : iterator_(isolate) {
    290   AdvanceToId(id);
    291 }
    292 
    293 
    294 template<typename Iterator>
    295 void JavaScriptFrameIteratorTemp<Iterator>::Advance() {
    296   do {
    297     iterator_.Advance();
    298   } while (!iterator_.done() && !iterator_.frame()->is_java_script());
    299 }
    300 
    301 
    302 template<typename Iterator>
    303 void JavaScriptFrameIteratorTemp<Iterator>::AdvanceToArgumentsFrame() {
    304   if (!frame()->has_adapted_arguments()) return;
    305   iterator_.Advance();
    306   ASSERT(iterator_.frame()->is_arguments_adaptor());
    307 }
    308 
    309 
    310 template<typename Iterator>
    311 void JavaScriptFrameIteratorTemp<Iterator>::AdvanceToId(StackFrame::Id id) {
    312   while (!done()) {
    313     Advance();
    314     if (frame()->id() == id) return;
    315   }
    316 }
    317 
    318 
    319 template<typename Iterator>
    320 void JavaScriptFrameIteratorTemp<Iterator>::Reset() {
    321   iterator_.Reset();
    322   if (!done()) Advance();
    323 }
    324 
    325 
    326 } }  // namespace v8::internal
    327 
    328 #endif  // V8_FRAMES_INL_H_
    329