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