blob: 9241a449f4c0802fb42492697e88e349facd9ccb [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_FRAMES_INL_H_
6#define V8_FRAMES_INL_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/frames.h"
9#include "src/isolate.h"
10#include "src/v8memory.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000011
12#if V8_TARGET_ARCH_IA32
Ben Murdochb8a8cc12014-11-26 15:28:44 +000013#include "src/ia32/frames-ia32.h" // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +000014#elif V8_TARGET_ARCH_X64
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015#include "src/x64/frames-x64.h" // NOLINT
16#elif V8_TARGET_ARCH_ARM64
17#include "src/arm64/frames-arm64.h" // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +000018#elif V8_TARGET_ARCH_ARM
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019#include "src/arm/frames-arm.h" // NOLINT
Andrei Popescu31002712010-02-23 13:46:05 +000020#elif V8_TARGET_ARCH_MIPS
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021#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
Steve Blocka7e24c12009-10-30 11:49:00 +000026#else
27#error Unsupported target architecture.
28#endif
29
30namespace v8 {
31namespace internal {
32
33
34inline Address StackHandler::address() const {
35 return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
36}
37
38
39inline StackHandler* StackHandler::next() const {
40 const int offset = StackHandlerConstants::kNextOffset;
41 return FromAddress(Memory::Address_at(address() + offset));
42}
43
44
45inline 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
Kristian Monsen80d68ea2010-09-08 11:05:35 +010052inline void StackHandler::Iterate(ObjectVisitor* v, Code* holder) const {
Ben Murdoch69a99ed2011-11-30 16:03:39 +000053 v->VisitPointer(context_address());
Ben Murdoch3ef787d2012-04-12 10:51:47 +010054 v->VisitPointer(code_address());
Steve Blocka7e24c12009-10-30 11:49:00 +000055}
56
57
58inline StackHandler* StackHandler::FromAddress(Address address) {
59 return reinterpret_cast<StackHandler*>(address);
60}
61
62
Ben Murdoch3ef787d2012-04-12 10:51:47 +010063inline bool StackHandler::is_js_entry() const {
64 return kind() == JS_ENTRY;
65}
66
67
68inline bool StackHandler::is_catch() const {
69 return kind() == CATCH;
70}
71
72
73inline bool StackHandler::is_finally() const {
74 return kind() == FINALLY;
75}
76
77
78inline StackHandler::Kind StackHandler::kind() const {
Steve Blocka7e24c12009-10-30 11:49:00 +000079 const int offset = StackHandlerConstants::kStateOffset;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010080 return KindField::decode(Memory::unsigned_at(address() + offset));
Steve Blocka7e24c12009-10-30 11:49:00 +000081}
82
83
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084inline unsigned StackHandler::index() const {
85 const int offset = StackHandlerConstants::kStateOffset;
86 return IndexField::decode(Memory::unsigned_at(address() + offset));
87}
88
89
Ben Murdoch69a99ed2011-11-30 16:03:39 +000090inline Object** StackHandler::context_address() const {
91 const int offset = StackHandlerConstants::kContextOffset;
92 return reinterpret_cast<Object**>(address() + offset);
93}
94
95
Ben Murdoch3ef787d2012-04-12 10:51:47 +010096inline Object** StackHandler::code_address() const {
97 const int offset = StackHandlerConstants::kCodeOffset;
98 return reinterpret_cast<Object**>(address() + offset);
Steve Blocka7e24c12009-10-30 11:49:00 +000099}
100
101
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102inline StackFrame::StackFrame(StackFrameIteratorBase* iterator)
Ben Murdoch8b112d22011-06-08 16:22:53 +0100103 : iterator_(iterator), isolate_(iterator_->isolate()) {
104}
105
106
Steve Blocka7e24c12009-10-30 11:49:00 +0000107inline StackHandler* StackFrame::top_handler() const {
108 return iterator_->handler();
109}
110
111
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100112inline Code* StackFrame::LookupCode() const {
113 return GetContainingCode(isolate(), pc());
114}
115
116
Steve Block44f0eee2011-05-26 01:26:41 +0100117inline Code* StackFrame::GetContainingCode(Isolate* isolate, Address pc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100118 return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
119}
120
121
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000122inline 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
133inline EntryFrame::EntryFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100134 : StackFrame(iterator) {
135}
136
137
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138inline EntryConstructFrame::EntryConstructFrame(
139 StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100140 : EntryFrame(iterator) {
141}
142
143
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000144inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100145 : StackFrame(iterator) {
146}
147
148
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149inline StandardFrame::StandardFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100150 : StackFrame(iterator) {
Steve Block44f0eee2011-05-26 01:26:41 +0100151}
152
153
Steve Blocka7e24c12009-10-30 11:49:00 +0000154inline Object* StandardFrame::GetExpression(int index) const {
155 return Memory::Object_at(GetExpressionAddress(index));
156}
157
158
159inline void StandardFrame::SetExpression(int index, Object* value) {
160 Memory::Object_at(GetExpressionAddress(index)) = value;
161}
162
163
164inline Object* StandardFrame::context() const {
165 const int offset = StandardFrameConstants::kContextOffset;
166 return Memory::Object_at(fp() + offset);
167}
168
169
170inline Address StandardFrame::caller_fp() const {
171 return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset);
172}
173
174
175inline Address StandardFrame::caller_pc() const {
176 return Memory::Address_at(ComputePCAddress(fp()));
177}
178
179
180inline Address StandardFrame::ComputePCAddress(Address fp) {
181 return fp + StandardFrameConstants::kCallerPCOffset;
182}
183
184
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185inline Address StandardFrame::ComputeConstantPoolAddress(Address fp) {
186 return fp + StandardFrameConstants::kConstantPoolOffset;
187}
188
189
Steve Blocka7e24c12009-10-30 11:49:00 +0000190inline 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
197inline bool StandardFrame::IsConstructFrame(Address fp) {
198 Object* marker =
199 Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100200 return marker == Smi::FromInt(StackFrame::CONSTRUCT);
201}
202
203
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000204inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100205 : StandardFrame(iterator) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000206}
207
208
Ben Murdoch8b112d22011-06-08 16:22:53 +0100209Address JavaScriptFrame::GetParameterSlot(int index) const {
210 int param_count = ComputeParametersCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211 DCHECK(-1 <= index && index < param_count);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100212 int parameter_offset = (param_count - index - 1) * kPointerSize;
213 return caller_sp() + parameter_offset;
214}
215
216
217Object* JavaScriptFrame::GetParameter(int index) const {
218 return Memory::Object_at(GetParameterSlot(index));
219}
220
221
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000222inline 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
233inline Object* JavaScriptFrame::GetOperand(int index) const {
234 return Memory::Object_at(GetOperandSlot(index));
235}
236
237
238inline 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
Steve Blocka7e24c12009-10-30 11:49:00 +0000250inline Object* JavaScriptFrame::receiver() const {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100251 return GetParameter(-1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000252}
253
254
255inline void JavaScriptFrame::set_receiver(Object* value) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100256 Memory::Object_at(GetParameterSlot(-1)) = value;
Steve Blocka7e24c12009-10-30 11:49:00 +0000257}
258
259
260inline bool JavaScriptFrame::has_adapted_arguments() const {
261 return IsArgumentsAdaptorFrame(caller_fp());
262}
263
264
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265inline JSFunction* JavaScriptFrame::function() const {
266 return JSFunction::cast(function_slot_object());
Steve Blocka7e24c12009-10-30 11:49:00 +0000267}
268
269
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000270inline StubFrame::StubFrame(StackFrameIteratorBase* iterator)
271 : StandardFrame(iterator) {
272}
273
274
275inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100276 : JavaScriptFrame(iterator) {
277}
278
279
280inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000281 StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100282}
283
284
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000285inline InternalFrame::InternalFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100286 : StandardFrame(iterator) {
287}
288
289
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000290inline StubFailureTrampolineFrame::StubFailureTrampolineFrame(
291 StackFrameIteratorBase* iterator) : StandardFrame(iterator) {
292}
293
294
295inline ConstructFrame::ConstructFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100296 : InternalFrame(iterator) {
297}
298
299
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300inline JavaScriptFrameIterator::JavaScriptFrameIterator(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100301 Isolate* isolate)
302 : iterator_(isolate) {
303 if (!done()) Advance();
304}
305
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100306
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000307inline JavaScriptFrameIterator::JavaScriptFrameIterator(
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100308 Isolate* isolate, ThreadLocalTop* top)
309 : iterator_(isolate, top) {
310 if (!done()) Advance();
311}
312
313
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000314inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000315 // 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();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000320 DCHECK(frame->is_java_script() || frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000321 return static_cast<JavaScriptFrame*>(frame);
322}
323
324
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000325inline StackFrame* SafeStackFrameIterator::frame() const {
326 DCHECK(!done());
327 DCHECK(frame_->is_java_script() || frame_->is_exit());
328 return frame_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000329}
330
331
332} } // namespace v8::internal
333
334#endif // V8_FRAMES_INL_H_