frames-inl.h 8.44 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7

#ifndef V8_FRAMES_INL_H_
#define V8_FRAMES_INL_H_

8 9 10
#include "src/frames.h"
#include "src/isolate.h"
#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 23
#elif V8_TARGET_ARCH_MIPS64
#include "src/mips64/frames-mips64.h"  // NOLINT
danno@chromium.org's avatar
danno@chromium.org committed
24
#elif V8_TARGET_ARCH_X87
25
#include "src/x87/frames-x87.h"  // NOLINT
26 27
#else
#error Unsupported target architecture.
28 29
#endif

30 31
namespace v8 {
namespace internal {
32 33 34


inline Address StackHandler::address() const {
35
  return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
}


inline StackHandler* StackHandler::next() const {
  const int offset = StackHandlerConstants::kNextOffset;
  return FromAddress(Memory::Address_at(address() + offset));
}


inline bool StackHandler::includes(Address address) const {
  Address start = this->address();
  Address end = start + StackHandlerConstants::kSize;
  return start <= address && address <= end;
}


52
inline void StackHandler::Iterate(ObjectVisitor* v, Code* holder) const {
53
  v->VisitPointer(context_address());
54
  v->VisitPointer(code_address());
55 56 57 58 59 60 61 62
}


inline StackHandler* StackHandler::FromAddress(Address address) {
  return reinterpret_cast<StackHandler*>(address);
}


63 64
inline bool StackHandler::is_js_entry() const {
  return kind() == JS_ENTRY;
65 66 67
}


68 69
inline bool StackHandler::is_catch() const {
  return kind() == CATCH;
70 71 72
}


73 74
inline bool StackHandler::is_finally() const {
  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 85 86 87 88 89
inline unsigned StackHandler::index() const {
  const int offset = StackHandlerConstants::kStateOffset;
  return IndexField::decode(Memory::unsigned_at(address() + offset));
}


90 91 92 93 94 95
inline Object** StackHandler::context_address() const {
  const int offset = StackHandlerConstants::kContextOffset;
  return reinterpret_cast<Object**>(address() + offset);
}


96 97 98
inline Object** StackHandler::code_address() const {
  const int offset = StackHandlerConstants::kCodeOffset;
  return reinterpret_cast<Object**>(address() + offset);
99 100 101
}


102
inline StackFrame::StackFrame(StackFrameIteratorBase* iterator)
103 104 105 106
    : iterator_(iterator), isolate_(iterator_->isolate()) {
}


107 108 109 110 111
inline StackHandler* StackFrame::top_handler() const {
  return iterator_->handler();
}


112 113 114 115 116
inline Code* StackFrame::LookupCode() const {
  return GetContainingCode(isolate(), pc());
}


117
inline Code* StackFrame::GetContainingCode(Isolate* isolate, Address pc) {
118
  return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
119 120 121
}


122 123 124 125 126 127 128 129 130 131 132
inline Address* StackFrame::ResolveReturnAddressLocation(Address* pc_address) {
  if (return_address_location_resolver_ == NULL) {
    return pc_address;
  } else {
    return reinterpret_cast<Address*>(
        return_address_location_resolver_(
            reinterpret_cast<uintptr_t>(pc_address)));
  }
}


133
inline EntryFrame::EntryFrame(StackFrameIteratorBase* iterator)
134 135 136 137
    : StackFrame(iterator) {
}


138 139
inline EntryConstructFrame::EntryConstructFrame(
    StackFrameIteratorBase* iterator)
140 141 142 143
    : EntryFrame(iterator) {
}


144
inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
145 146 147 148
    : StackFrame(iterator) {
}


149
inline StandardFrame::StandardFrame(StackFrameIteratorBase* iterator)
150 151 152 153
    : StackFrame(iterator) {
}


154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
inline Object* StandardFrame::GetExpression(int index) const {
  return Memory::Object_at(GetExpressionAddress(index));
}


inline void StandardFrame::SetExpression(int index, Object* value) {
  Memory::Object_at(GetExpressionAddress(index)) = value;
}


inline Object* StandardFrame::context() const {
  const int offset = StandardFrameConstants::kContextOffset;
  return Memory::Object_at(fp() + offset);
}


inline Address StandardFrame::caller_fp() const {
  return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset);
}


inline Address StandardFrame::caller_pc() const {
  return Memory::Address_at(ComputePCAddress(fp()));
}


inline Address StandardFrame::ComputePCAddress(Address fp) {
  return fp + StandardFrameConstants::kCallerPCOffset;
}


185 186 187 188 189
inline Address StandardFrame::ComputeConstantPoolAddress(Address fp) {
  return fp + StandardFrameConstants::kConstantPoolOffset;
}


190
inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
191 192 193
  Object* marker =
      Memory::Object_at(fp + StandardFrameConstants::kContextOffset);
  return marker == Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR);
194 195 196
}


197 198 199
inline bool StandardFrame::IsConstructFrame(Address fp) {
  Object* marker =
      Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset);
200
  return marker == Smi::FromInt(StackFrame::CONSTRUCT);
201 202 203
}


204
inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
205 206 207 208
    : StandardFrame(iterator) {
}


209 210
Address JavaScriptFrame::GetParameterSlot(int index) const {
  int param_count = ComputeParametersCount();
211
  DCHECK(-1 <= index && index < param_count);
212 213 214 215 216 217 218 219 220 221
  int parameter_offset = (param_count - index - 1) * kPointerSize;
  return caller_sp() + parameter_offset;
}


Object* JavaScriptFrame::GetParameter(int index) const {
  return Memory::Object_at(GetParameterSlot(index));
}


222 223
inline Address JavaScriptFrame::GetOperandSlot(int index) const {
  Address base = fp() + JavaScriptFrameConstants::kLocal0Offset;
224 225 226 227
  DCHECK(IsAddressAligned(base, kPointerSize));
  DCHECK_EQ(type(), JAVA_SCRIPT);
  DCHECK_LT(index, ComputeOperandsCount());
  DCHECK_LE(0, index);
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
  // Operand stack grows down.
  return base - index * kPointerSize;
}


inline Object* JavaScriptFrame::GetOperand(int index) const {
  return Memory::Object_at(GetOperandSlot(index));
}


inline int JavaScriptFrame::ComputeOperandsCount() const {
  Address base = fp() + JavaScriptFrameConstants::kLocal0Offset;
  // Base points to low address of first operand and stack grows down, so add
  // kPointerSize to get the actual stack size.
  intptr_t stack_size_in_bytes = (base + kPointerSize) - sp();
243 244 245
  DCHECK(IsAligned(stack_size_in_bytes, kPointerSize));
  DCHECK(type() == JAVA_SCRIPT);
  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 261 262 263 264
}


inline bool JavaScriptFrame::has_adapted_arguments() const {
  return IsArgumentsAdaptorFrame(caller_fp());
}


265 266
inline JSFunction* JavaScriptFrame::function() const {
  return JSFunction::cast(function_slot_object());
267 268 269
}


270
inline StubFrame::StubFrame(StackFrameIteratorBase* iterator)
271 272 273 274
    : StandardFrame(iterator) {
}


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 287 288 289
    : StandardFrame(iterator) {
}


290
inline StubFailureTrampolineFrame::StubFailureTrampolineFrame(
291
    StackFrameIteratorBase* iterator) : StandardFrame(iterator) {
292 293 294
}


295
inline ConstructFrame::ConstructFrame(StackFrameIteratorBase* iterator)
296 297 298 299
    : InternalFrame(iterator) {
}


300
inline JavaScriptFrameIterator::JavaScriptFrameIterator(
301 302 303 304 305
    Isolate* isolate)
    : iterator_(isolate) {
  if (!done()) Advance();
}

306

307
inline JavaScriptFrameIterator::JavaScriptFrameIterator(
308 309 310 311 312 313
    Isolate* isolate, ThreadLocalTop* top)
    : iterator_(isolate, top) {
  if (!done()) Advance();
}


314
inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
315 316 317 318 319
  // TODO(1233797): The frame hierarchy needs to change. It's
  // problematic that we can't use the safe-cast operator to cast to
  // the JavaScript frame type, because we may encounter arguments
  // adaptor frames.
  StackFrame* frame = iterator_.frame();
320
  DCHECK(frame->is_java_script() || frame->is_arguments_adaptor());
321 322 323 324
  return static_cast<JavaScriptFrame*>(frame);
}


325
inline StackFrame* SafeStackFrameIterator::frame() const {
326 327
  DCHECK(!done());
  DCHECK(frame_->is_java_script() || frame_->is_exit());
328
  return frame_;
329 330 331
}


332 333 334
} }  // namespace v8::internal

#endif  // V8_FRAMES_INL_H_