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 : struct InnerPointerToCodeCacheEntry {
20 : Address inner_pointer;
21 : Code code;
22 : SafepointEntry safepoint_entry;
23 : };
24 :
25 63814634 : explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
26 : Flush();
27 62442 : }
28 :
29 68846 : void Flush() { memset(static_cast<void*>(&cache_[0]), 0, sizeof(cache_)); }
30 :
31 : InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
32 :
33 : private:
34 59324774 : 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 52537020 : return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
46 : }
47 :
48 :
49 : inline StackHandler* StackHandler::next() const {
50 : const int offset = StackHandlerConstants::kNextOffset;
51 1624778 : return FromAddress(Memory<Address>(address() + offset));
52 : }
53 :
54 : inline Address StackHandler::next_address() const {
55 121016 : return Memory<Address>(address() + StackHandlerConstants::kNextOffset);
56 : }
57 :
58 : inline StackHandler* StackHandler::FromAddress(Address address) {
59 10795788 : return reinterpret_cast<StackHandler*>(address);
60 : }
61 :
62 :
63 : inline StackFrame::StackFrame(StackFrameIteratorBase* iterator)
64 193855809 : : iterator_(iterator), isolate_(iterator_->isolate()) {
65 : }
66 :
67 :
68 : inline StackHandler* StackFrame::top_handler() const {
69 : return iterator_->handler();
70 : }
71 :
72 :
73 : inline Address* StackFrame::ResolveReturnAddressLocation(Address* pc_address) {
74 67956116 : if (return_address_location_resolver_ == nullptr) {
75 : return pc_address;
76 : } else {
77 : return reinterpret_cast<Address*>(
78 0 : return_address_location_resolver_(
79 0 : reinterpret_cast<uintptr_t>(pc_address)));
80 : }
81 : }
82 :
83 : inline NativeFrame::NativeFrame(StackFrameIteratorBase* iterator)
84 9231229 : : 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 18462458 : : StackFrame(iterator) {}
92 :
93 : inline ConstructEntryFrame::ConstructEntryFrame(
94 : StackFrameIteratorBase* iterator)
95 9231229 : : EntryFrame(iterator) {}
96 :
97 : inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
98 18462458 : : StackFrame(iterator) {}
99 :
100 : inline BuiltinExitFrame::BuiltinExitFrame(StackFrameIteratorBase* iterator)
101 9231229 : : ExitFrame(iterator) {}
102 :
103 : 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 : Object argc_slot = argc_slot_object();
110 : DCHECK(argc_slot->IsSmi());
111 : int argc = Smi::ToInt(argc_slot);
112 :
113 31537 : const int receiverOffset = BuiltinExitFrameConstants::kNewTargetOffset +
114 31537 : (argc - 1) * kSystemPointerSize;
115 63074 : return Object(Memory<Address>(fp() + receiverOffset));
116 : }
117 :
118 : inline Object BuiltinExitFrame::argc_slot_object() const {
119 63102 : return Object(Memory<Address>(fp() + BuiltinExitFrameConstants::kArgcOffset));
120 : }
121 :
122 : inline Object BuiltinExitFrame::target_slot_object() const {
123 : return Object(
124 123868 : Memory<Address>(fp() + BuiltinExitFrameConstants::kTargetOffset));
125 : }
126 :
127 : inline Object BuiltinExitFrame::new_target_slot_object() const {
128 : return Object(
129 63074 : Memory<Address>(fp() + BuiltinExitFrameConstants::kNewTargetOffset));
130 : }
131 :
132 : inline StandardFrame::StandardFrame(StackFrameIteratorBase* iterator)
133 147699664 : : StackFrame(iterator) {
134 : }
135 :
136 : inline Object StandardFrame::GetExpression(int index) const {
137 117620346 : return Object(Memory<Address>(GetExpressionAddress(index)));
138 : }
139 :
140 : inline void StandardFrame::SetExpression(int index, Object value) {
141 1741288 : Memory<Address>(GetExpressionAddress(index)) = value->ptr();
142 : }
143 :
144 : inline Address StandardFrame::caller_fp() const {
145 50263829 : 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 42529040 : 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 15549416 : Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
167 24 : return frame_type == StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR);
168 : }
169 :
170 :
171 : inline bool StandardFrame::IsConstructFrame(Address fp) {
172 : intptr_t frame_type =
173 14903196 : Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
174 7451598 : return frame_type == StackFrame::TypeToMarker(StackFrame::CONSTRUCT);
175 : }
176 :
177 : inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
178 55387374 : : StandardFrame(iterator) {}
179 :
180 : Address JavaScriptFrame::GetParameterSlot(int index) const {
181 7647620 : int param_count = ComputeParametersCount();
182 : DCHECK(-1 <= index &&
183 : (index < param_count ||
184 : param_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel));
185 7647620 : int parameter_offset = (param_count - index - 1) * kSystemPointerSize;
186 15295240 : 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 24 : inline bool JavaScriptFrame::has_adapted_arguments() const {
194 24 : return IsArgumentsAdaptorFrame(caller_fp());
195 : }
196 :
197 : inline Object JavaScriptFrame::function_slot_object() const {
198 : const int offset = JavaScriptFrameConstants::kFunctionOffset;
199 57422608 : return Object(Memory<Address>(fp() + offset));
200 : }
201 :
202 : inline StubFrame::StubFrame(StackFrameIteratorBase* iterator)
203 36924916 : : StandardFrame(iterator) {
204 : }
205 :
206 :
207 : inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
208 9231229 : : JavaScriptFrame(iterator) {
209 : }
210 :
211 :
212 : inline InterpretedFrame::InterpretedFrame(StackFrameIteratorBase* iterator)
213 9231229 : : JavaScriptFrame(iterator) {}
214 :
215 :
216 : inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
217 9231229 : StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) {
218 : }
219 :
220 : inline BuiltinFrame::BuiltinFrame(StackFrameIteratorBase* iterator)
221 9231229 : : JavaScriptFrame(iterator) {}
222 :
223 : inline WasmCompiledFrame::WasmCompiledFrame(StackFrameIteratorBase* iterator)
224 9231229 : : StandardFrame(iterator) {}
225 :
226 : inline WasmInterpreterEntryFrame::WasmInterpreterEntryFrame(
227 : StackFrameIteratorBase* iterator)
228 9231229 : : StandardFrame(iterator) {}
229 :
230 : inline WasmToJsFrame::WasmToJsFrame(StackFrameIteratorBase* iterator)
231 9231229 : : StubFrame(iterator) {}
232 :
233 : inline JsToWasmFrame::JsToWasmFrame(StackFrameIteratorBase* iterator)
234 9231229 : : StubFrame(iterator) {}
235 :
236 : inline CWasmEntryFrame::CWasmEntryFrame(StackFrameIteratorBase* iterator)
237 9231229 : : StubFrame(iterator) {}
238 :
239 : inline WasmCompileLazyFrame::WasmCompileLazyFrame(
240 : StackFrameIteratorBase* iterator)
241 9231229 : : StandardFrame(iterator) {}
242 :
243 : inline InternalFrame::InternalFrame(StackFrameIteratorBase* iterator)
244 27693687 : : StandardFrame(iterator) {
245 : }
246 :
247 : inline ConstructFrame::ConstructFrame(StackFrameIteratorBase* iterator)
248 9231229 : : InternalFrame(iterator) {
249 : }
250 :
251 : inline BuiltinContinuationFrame::BuiltinContinuationFrame(
252 : StackFrameIteratorBase* iterator)
253 9231229 : : InternalFrame(iterator) {}
254 :
255 : inline JavaScriptBuiltinContinuationFrame::JavaScriptBuiltinContinuationFrame(
256 : StackFrameIteratorBase* iterator)
257 18462458 : : JavaScriptFrame(iterator) {}
258 :
259 : inline JavaScriptBuiltinContinuationWithCatchFrame::
260 : JavaScriptBuiltinContinuationWithCatchFrame(
261 : StackFrameIteratorBase* iterator)
262 9231229 : : JavaScriptBuiltinContinuationFrame(iterator) {}
263 :
264 752895 : inline JavaScriptFrameIterator::JavaScriptFrameIterator(
265 : Isolate* isolate)
266 752895 : : iterator_(isolate) {
267 752895 : if (!done()) Advance();
268 752895 : }
269 :
270 21286 : inline JavaScriptFrameIterator::JavaScriptFrameIterator(
271 : Isolate* isolate, ThreadLocalTop* top)
272 21286 : : iterator_(isolate, top) {
273 21286 : if (!done()) Advance();
274 21286 : }
275 :
276 : 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 : StackFrame* frame = iterator_.frame();
282 : DCHECK(frame->is_java_script() || frame->is_arguments_adaptor());
283 : return static_cast<JavaScriptFrame*>(frame);
284 : }
285 :
286 : inline StandardFrame* StackTraceFrameIterator::frame() const {
287 : StackFrame* frame = iterator_.frame();
288 : DCHECK(frame->is_java_script() || frame->is_arguments_adaptor() ||
289 : frame->is_wasm());
290 : return static_cast<StandardFrame*>(frame);
291 : }
292 :
293 : bool StackTraceFrameIterator::is_javascript() const {
294 427475 : return frame()->is_java_script();
295 : }
296 :
297 2033 : 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_
|