blob: 4013601dace9c121bf722b131e6a71234dba2df5 [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"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/objects-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/v8memory.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000012
13#if V8_TARGET_ARCH_IA32
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014#include "src/ia32/frames-ia32.h" // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +000015#elif V8_TARGET_ARCH_X64
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "src/x64/frames-x64.h" // NOLINT
17#elif V8_TARGET_ARCH_ARM64
18#include "src/arm64/frames-arm64.h" // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +000019#elif V8_TARGET_ARCH_ARM
Ben Murdochb8a8cc12014-11-26 15:28:44 +000020#include "src/arm/frames-arm.h" // NOLINT
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021#elif V8_TARGET_ARCH_PPC
22#include "src/ppc/frames-ppc.h" // NOLINT
Andrei Popescu31002712010-02-23 13:46:05 +000023#elif V8_TARGET_ARCH_MIPS
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024#include "src/mips/frames-mips.h" // NOLINT
25#elif V8_TARGET_ARCH_MIPS64
26#include "src/mips64/frames-mips64.h" // NOLINT
27#elif V8_TARGET_ARCH_X87
28#include "src/x87/frames-x87.h" // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +000029#else
30#error Unsupported target architecture.
31#endif
32
33namespace v8 {
34namespace internal {
35
36
37inline Address StackHandler::address() const {
38 return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
39}
40
41
42inline StackHandler* StackHandler::next() const {
43 const int offset = StackHandlerConstants::kNextOffset;
44 return FromAddress(Memory::Address_at(address() + offset));
45}
46
47
Steve Blocka7e24c12009-10-30 11:49:00 +000048inline StackHandler* StackHandler::FromAddress(Address address) {
49 return reinterpret_cast<StackHandler*>(address);
50}
51
52
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053inline StackFrame::StackFrame(StackFrameIteratorBase* iterator)
Ben Murdoch8b112d22011-06-08 16:22:53 +010054 : iterator_(iterator), isolate_(iterator_->isolate()) {
55}
56
57
Steve Blocka7e24c12009-10-30 11:49:00 +000058inline StackHandler* StackFrame::top_handler() const {
59 return iterator_->handler();
60}
61
62
Ben Murdoch3ef787d2012-04-12 10:51:47 +010063inline Code* StackFrame::LookupCode() const {
64 return GetContainingCode(isolate(), pc());
65}
66
67
Steve Block44f0eee2011-05-26 01:26:41 +010068inline Code* StackFrame::GetContainingCode(Isolate* isolate, Address pc) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +010069 return isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code;
70}
71
72
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073inline Address* StackFrame::ResolveReturnAddressLocation(Address* pc_address) {
74 if (return_address_location_resolver_ == NULL) {
75 return pc_address;
76 } else {
77 return reinterpret_cast<Address*>(
78 return_address_location_resolver_(
79 reinterpret_cast<uintptr_t>(pc_address)));
80 }
81}
82
83
84inline EntryFrame::EntryFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010085 : StackFrame(iterator) {
86}
87
88
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089inline EntryConstructFrame::EntryConstructFrame(
90 StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010091 : EntryFrame(iterator) {
92}
93
94
Ben Murdochb8a8cc12014-11-26 15:28:44 +000095inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010096 : StackFrame(iterator) {
97}
98
99
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100inline StandardFrame::StandardFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100101 : StackFrame(iterator) {
Steve Block44f0eee2011-05-26 01:26:41 +0100102}
103
104
Steve Blocka7e24c12009-10-30 11:49:00 +0000105inline Object* StandardFrame::GetExpression(int index) const {
106 return Memory::Object_at(GetExpressionAddress(index));
107}
108
109
110inline void StandardFrame::SetExpression(int index, Object* value) {
111 Memory::Object_at(GetExpressionAddress(index)) = value;
112}
113
114
115inline Object* StandardFrame::context() const {
116 const int offset = StandardFrameConstants::kContextOffset;
117 return Memory::Object_at(fp() + offset);
118}
119
120
121inline Address StandardFrame::caller_fp() const {
122 return Memory::Address_at(fp() + StandardFrameConstants::kCallerFPOffset);
123}
124
125
126inline Address StandardFrame::caller_pc() const {
127 return Memory::Address_at(ComputePCAddress(fp()));
128}
129
130
131inline Address StandardFrame::ComputePCAddress(Address fp) {
132 return fp + StandardFrameConstants::kCallerPCOffset;
133}
134
135
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136inline Address StandardFrame::ComputeConstantPoolAddress(Address fp) {
137 return fp + StandardFrameConstants::kConstantPoolOffset;
138}
139
140
Steve Blocka7e24c12009-10-30 11:49:00 +0000141inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
142 Object* marker =
143 Memory::Object_at(fp + StandardFrameConstants::kContextOffset);
144 return marker == Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR);
145}
146
147
148inline bool StandardFrame::IsConstructFrame(Address fp) {
149 Object* marker =
150 Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100151 return marker == Smi::FromInt(StackFrame::CONSTRUCT);
152}
153
154
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000155inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100156 : StandardFrame(iterator) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000157}
158
159
Ben Murdoch8b112d22011-06-08 16:22:53 +0100160Address JavaScriptFrame::GetParameterSlot(int index) const {
161 int param_count = ComputeParametersCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000162 DCHECK(-1 <= index && index < param_count);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100163 int parameter_offset = (param_count - index - 1) * kPointerSize;
164 return caller_sp() + parameter_offset;
165}
166
167
168Object* JavaScriptFrame::GetParameter(int index) const {
169 return Memory::Object_at(GetParameterSlot(index));
170}
171
172
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000173inline Address JavaScriptFrame::GetOperandSlot(int index) const {
174 Address base = fp() + JavaScriptFrameConstants::kLocal0Offset;
175 DCHECK(IsAddressAligned(base, kPointerSize));
176 DCHECK_EQ(type(), JAVA_SCRIPT);
177 DCHECK_LT(index, ComputeOperandsCount());
178 DCHECK_LE(0, index);
179 // Operand stack grows down.
180 return base - index * kPointerSize;
181}
182
183
184inline Object* JavaScriptFrame::GetOperand(int index) const {
185 return Memory::Object_at(GetOperandSlot(index));
186}
187
188
189inline int JavaScriptFrame::ComputeOperandsCount() const {
190 Address base = fp() + JavaScriptFrameConstants::kLocal0Offset;
191 // Base points to low address of first operand and stack grows down, so add
192 // kPointerSize to get the actual stack size.
193 intptr_t stack_size_in_bytes = (base + kPointerSize) - sp();
194 DCHECK(IsAligned(stack_size_in_bytes, kPointerSize));
195 DCHECK(type() == JAVA_SCRIPT);
196 DCHECK(stack_size_in_bytes >= 0);
197 return static_cast<int>(stack_size_in_bytes >> kPointerSizeLog2);
198}
199
200
Steve Blocka7e24c12009-10-30 11:49:00 +0000201inline Object* JavaScriptFrame::receiver() const {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100202 return GetParameter(-1);
Steve Blocka7e24c12009-10-30 11:49:00 +0000203}
204
205
206inline void JavaScriptFrame::set_receiver(Object* value) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100207 Memory::Object_at(GetParameterSlot(-1)) = value;
Steve Blocka7e24c12009-10-30 11:49:00 +0000208}
209
210
211inline bool JavaScriptFrame::has_adapted_arguments() const {
212 return IsArgumentsAdaptorFrame(caller_fp());
213}
214
215
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216inline JSFunction* JavaScriptFrame::function() const {
217 return JSFunction::cast(function_slot_object());
Steve Blocka7e24c12009-10-30 11:49:00 +0000218}
219
220
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221inline Object* JavaScriptFrame::function_slot_object() const {
222 const int offset = JavaScriptFrameConstants::kFunctionOffset;
223 return Memory::Object_at(fp() + offset);
224}
225
226
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000227inline StubFrame::StubFrame(StackFrameIteratorBase* iterator)
228 : StandardFrame(iterator) {
229}
230
231
232inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100233 : JavaScriptFrame(iterator) {
234}
235
236
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000237inline InterpretedFrame::InterpretedFrame(StackFrameIteratorBase* iterator)
238 : JavaScriptFrame(iterator) {}
239
240
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100241inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100243}
244
245
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000246inline InternalFrame::InternalFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100247 : StandardFrame(iterator) {
248}
249
250
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000251inline StubFailureTrampolineFrame::StubFailureTrampolineFrame(
252 StackFrameIteratorBase* iterator) : StandardFrame(iterator) {
253}
254
255
256inline ConstructFrame::ConstructFrame(StackFrameIteratorBase* iterator)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100257 : InternalFrame(iterator) {
258}
259
260
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000261inline JavaScriptFrameIterator::JavaScriptFrameIterator(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100262 Isolate* isolate)
263 : iterator_(isolate) {
264 if (!done()) Advance();
265}
266
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100267
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000268inline JavaScriptFrameIterator::JavaScriptFrameIterator(
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100269 Isolate* isolate, ThreadLocalTop* top)
270 : iterator_(isolate, top) {
271 if (!done()) Advance();
272}
273
274
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000275inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000276 // 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();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000281 DCHECK(frame->is_java_script() || frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000282 return static_cast<JavaScriptFrame*>(frame);
283}
284
285
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286inline StackFrame* SafeStackFrameIterator::frame() const {
287 DCHECK(!done());
288 DCHECK(frame_->is_java_script() || frame_->is_exit());
289 return frame_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000290}
291
292
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293} // namespace internal
294} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000295
296#endif // V8_FRAMES_INL_H_