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