Line data Source code
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/frame-constants.h"
9 : #include "src/frames.h"
10 : #include "src/isolate.h"
11 : #include "src/objects-inl.h"
12 : #include "src/v8memory.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : class InnerPointerToCodeCache {
18 : public:
19 64211968 : struct InnerPointerToCodeCacheEntry {
20 : Address inner_pointer;
21 : Code code;
22 : SafepointEntry safepoint_entry;
23 : };
24 :
25 64274851 : explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
26 : Flush();
27 62883 : }
28 :
29 83492 : void Flush() { memset(static_cast<void*>(&cache_[0]), 0, sizeof(cache_)); }
30 :
31 : InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
32 :
33 : private:
34 : InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
35 :
36 : Isolate* isolate_;
37 :
38 : static const int kInnerPointerToCodeCacheSize = 1024;
39 : InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
40 :
41 : DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
42 : };
43 :
44 : inline Address StackHandler::address() const {
45 50958226 : return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
46 : }
47 :
48 :
49 : inline StackHandler* StackHandler::next() const {
50 : const int offset = StackHandlerConstants::kNextOffset;
51 1667527 : return FromAddress(Memory<Address>(address() + offset));
52 : }
53 :
54 : inline Address StackHandler::next_address() const {
55 109881 : return Memory<Address>(address() + StackHandlerConstants::kNextOffset);
56 : }
57 :
58 : inline StackHandler* StackHandler::FromAddress(Address address) {
59 10158103 : return reinterpret_cast<StackHandler*>(address);
60 : }
61 :
62 :
63 : inline StackFrame::StackFrame(StackFrameIteratorBase* iterator)
64 178832283 : : iterator_(iterator), isolate_(iterator_->isolate()) {
65 : }
66 :
67 :
68 : inline StackHandler* StackFrame::top_handler() const {
69 109848 : return iterator_->handler();
70 : }
71 :
72 :
73 : inline Address* StackFrame::ResolveReturnAddressLocation(Address* pc_address) {
74 64217914 : if (return_address_location_resolver_ == nullptr) {
75 : return pc_address;
76 : } else {
77 : return reinterpret_cast<Address*>(
78 : return_address_location_resolver_(
79 0 : reinterpret_cast<uintptr_t>(pc_address)));
80 : }
81 : }
82 :
83 : inline NativeFrame::NativeFrame(StackFrameIteratorBase* iterator)
84 8515823 : : StackFrame(iterator) {}
85 :
86 0 : inline Address NativeFrame::GetCallerStackPointer() const {
87 0 : return fp() + CommonFrameConstants::kCallerSPOffset;
88 : }
89 :
90 : inline EntryFrame::EntryFrame(StackFrameIteratorBase* iterator)
91 17031646 : : StackFrame(iterator) {}
92 :
93 : inline ConstructEntryFrame::ConstructEntryFrame(
94 : StackFrameIteratorBase* iterator)
95 8515823 : : EntryFrame(iterator) {}
96 :
97 : inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
98 17031646 : : StackFrame(iterator) {}
99 :
100 : inline BuiltinExitFrame::BuiltinExitFrame(StackFrameIteratorBase* iterator)
101 8515823 : : ExitFrame(iterator) {}
102 :
103 36491 : inline Object BuiltinExitFrame::receiver_slot_object() const {
104 : // The receiver is the first argument on the frame.
105 : // fp[1]: return address.
106 : // fp[2]: the last argument (new target).
107 : // fp[4]: argc.
108 : // fp[2 + argc - 1]: receiver.
109 36491 : Object argc_slot = argc_slot_object();
110 : DCHECK(argc_slot->IsSmi());
111 36491 : int argc = Smi::ToInt(argc_slot);
112 :
113 36491 : const int receiverOffset = BuiltinExitFrameConstants::kNewTargetOffset +
114 36491 : (argc - 1) * kSystemPointerSize;
115 72982 : return Object(Memory<Address>(fp() + receiverOffset));
116 : }
117 :
118 : inline Object BuiltinExitFrame::argc_slot_object() const {
119 73000 : return Object(Memory<Address>(fp() + BuiltinExitFrameConstants::kArgcOffset));
120 : }
121 :
122 : inline Object BuiltinExitFrame::target_slot_object() const {
123 : return Object(
124 133564 : Memory<Address>(fp() + BuiltinExitFrameConstants::kTargetOffset));
125 : }
126 :
127 : inline Object BuiltinExitFrame::new_target_slot_object() const {
128 : return Object(
129 72982 : Memory<Address>(fp() + BuiltinExitFrameConstants::kNewTargetOffset));
130 : }
131 :
132 : inline StandardFrame::StandardFrame(StackFrameIteratorBase* iterator)
133 136253168 : : StackFrame(iterator) {
134 : }
135 :
136 : inline Object StandardFrame::GetExpression(int index) const {
137 111801490 : return Object(Memory<Address>(GetExpressionAddress(index)));
138 : }
139 :
140 : inline void StandardFrame::SetExpression(int index, Object value) {
141 1726026 : Memory<Address>(GetExpressionAddress(index)) = value->ptr();
142 : }
143 :
144 : inline Address StandardFrame::caller_fp() const {
145 97404758 : return Memory<Address>(fp() + StandardFrameConstants::kCallerFPOffset);
146 : }
147 :
148 :
149 : inline Address StandardFrame::caller_pc() const {
150 : return Memory<Address>(ComputePCAddress(fp()));
151 : }
152 :
153 :
154 : inline Address StandardFrame::ComputePCAddress(Address fp) {
155 41090478 : return fp + StandardFrameConstants::kCallerPCOffset;
156 : }
157 :
158 :
159 : inline Address StandardFrame::ComputeConstantPoolAddress(Address fp) {
160 : return fp + StandardFrameConstants::kConstantPoolOffset;
161 : }
162 :
163 :
164 : inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
165 : intptr_t frame_type =
166 15248368 : Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
167 9 : return frame_type == StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR);
168 : }
169 :
170 :
171 : inline bool StandardFrame::IsConstructFrame(Address fp) {
172 : intptr_t frame_type =
173 14605106 : Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
174 7302553 : return frame_type == StackFrame::TypeToMarker(StackFrame::CONSTRUCT);
175 : }
176 :
177 : inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
178 51094938 : : StandardFrame(iterator) {}
179 :
180 7514098 : Address JavaScriptFrame::GetParameterSlot(int index) const {
181 7514098 : int param_count = ComputeParametersCount();
182 : DCHECK(-1 <= index &&
183 : (index < param_count ||
184 : param_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel));
185 7514098 : int parameter_offset = (param_count - index - 1) * kSystemPointerSize;
186 15028196 : return caller_sp() + parameter_offset;
187 : }
188 :
189 : inline void JavaScriptFrame::set_receiver(Object value) {
190 : Memory<Address>(GetParameterSlot(-1)) = value->ptr();
191 : }
192 :
193 9 : inline bool JavaScriptFrame::has_adapted_arguments() const {
194 9 : return IsArgumentsAdaptorFrame(caller_fp());
195 : }
196 :
197 : inline Object JavaScriptFrame::function_slot_object() const {
198 : const int offset = JavaScriptFrameConstants::kFunctionOffset;
199 55454044 : return Object(Memory<Address>(fp() + offset));
200 : }
201 :
202 : inline StubFrame::StubFrame(StackFrameIteratorBase* iterator)
203 34063292 : : StandardFrame(iterator) {
204 : }
205 :
206 :
207 : inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
208 8515823 : : JavaScriptFrame(iterator) {
209 : }
210 :
211 :
212 : inline InterpretedFrame::InterpretedFrame(StackFrameIteratorBase* iterator)
213 8515823 : : JavaScriptFrame(iterator) {}
214 :
215 :
216 : inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
217 8515823 : StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) {
218 : }
219 :
220 : inline BuiltinFrame::BuiltinFrame(StackFrameIteratorBase* iterator)
221 8515823 : : JavaScriptFrame(iterator) {}
222 :
223 : inline WasmCompiledFrame::WasmCompiledFrame(StackFrameIteratorBase* iterator)
224 8515823 : : StandardFrame(iterator) {}
225 :
226 : inline WasmInterpreterEntryFrame::WasmInterpreterEntryFrame(
227 : StackFrameIteratorBase* iterator)
228 8515823 : : StandardFrame(iterator) {}
229 :
230 : inline WasmToJsFrame::WasmToJsFrame(StackFrameIteratorBase* iterator)
231 8515823 : : StubFrame(iterator) {}
232 :
233 : inline JsToWasmFrame::JsToWasmFrame(StackFrameIteratorBase* iterator)
234 8515823 : : StubFrame(iterator) {}
235 :
236 : inline CWasmEntryFrame::CWasmEntryFrame(StackFrameIteratorBase* iterator)
237 8515823 : : StubFrame(iterator) {}
238 :
239 : inline WasmCompileLazyFrame::WasmCompileLazyFrame(
240 : StackFrameIteratorBase* iterator)
241 8515823 : : StandardFrame(iterator) {}
242 :
243 : inline InternalFrame::InternalFrame(StackFrameIteratorBase* iterator)
244 25547469 : : StandardFrame(iterator) {
245 : }
246 :
247 : inline ConstructFrame::ConstructFrame(StackFrameIteratorBase* iterator)
248 8515823 : : InternalFrame(iterator) {
249 : }
250 :
251 : inline BuiltinContinuationFrame::BuiltinContinuationFrame(
252 : StackFrameIteratorBase* iterator)
253 8515823 : : InternalFrame(iterator) {}
254 :
255 : inline JavaScriptBuiltinContinuationFrame::JavaScriptBuiltinContinuationFrame(
256 : StackFrameIteratorBase* iterator)
257 17031646 : : JavaScriptFrame(iterator) {}
258 :
259 : inline JavaScriptBuiltinContinuationWithCatchFrame::
260 : JavaScriptBuiltinContinuationWithCatchFrame(
261 : StackFrameIteratorBase* iterator)
262 8515823 : : JavaScriptBuiltinContinuationFrame(iterator) {}
263 :
264 825773 : inline JavaScriptFrameIterator::JavaScriptFrameIterator(
265 : Isolate* isolate)
266 825773 : : iterator_(isolate) {
267 825773 : if (!done()) Advance();
268 825773 : }
269 :
270 10598 : inline JavaScriptFrameIterator::JavaScriptFrameIterator(
271 : Isolate* isolate, ThreadLocalTop* top)
272 10598 : : iterator_(isolate, top) {
273 10598 : if (!done()) Advance();
274 10598 : }
275 :
276 432623 : inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
277 : // TODO(1233797): The frame hierarchy needs to change. It's
278 : // problematic that we can't use the safe-cast operator to cast to
279 : // the JavaScript frame type, because we may encounter arguments
280 : // adaptor frames.
281 857211 : StackFrame* frame = iterator_.frame();
282 : DCHECK(frame->is_java_script() || frame->is_arguments_adaptor());
283 432623 : return static_cast<JavaScriptFrame*>(frame);
284 : }
285 :
286 90 : inline StandardFrame* StackTraceFrameIterator::frame() const {
287 1463923 : StackFrame* frame = iterator_.frame();
288 : DCHECK(frame->is_java_script() || frame->is_arguments_adaptor() ||
289 : frame->is_wasm());
290 90 : return static_cast<StandardFrame*>(frame);
291 : }
292 :
293 : bool StackTraceFrameIterator::is_javascript() const {
294 427451 : return frame()->is_java_script();
295 : }
296 :
297 2036 : bool StackTraceFrameIterator::is_wasm() const { return frame()->is_wasm(); }
298 :
299 : JavaScriptFrame* StackTraceFrameIterator::javascript_frame() const {
300 : return JavaScriptFrame::cast(frame());
301 : }
302 :
303 : inline StackFrame* SafeStackFrameIterator::frame() const {
304 : DCHECK(!done());
305 : DCHECK(frame_->is_java_script() || frame_->is_exit() ||
306 : frame_->is_builtin_exit() || frame_->is_wasm());
307 : return frame_;
308 : }
309 :
310 :
311 : } // namespace internal
312 : } // namespace v8
313 :
314 : #endif // V8_FRAMES_INL_H_
|