• 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_EXECUTION_FRAMES_INL_H_
6 #define V8_EXECUTION_FRAMES_INL_H_
7 
8 #include "src/base/memory.h"
9 #include "src/execution/frame-constants.h"
10 #include "src/execution/frames.h"
11 #include "src/execution/isolate.h"
12 #include "src/execution/pointer-authentication.h"
13 #include "src/objects/objects-inl.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 class InnerPointerToCodeCache {
19  public:
20   struct InnerPointerToCodeCacheEntry {
21     Address inner_pointer;
22     Code code;
23     SafepointEntry safepoint_entry;
24   };
25 
InnerPointerToCodeCache(Isolate * isolate)26   explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
27     Flush();
28   }
29 
30   InnerPointerToCodeCache(const InnerPointerToCodeCache&) = delete;
31   InnerPointerToCodeCache& operator=(const InnerPointerToCodeCache&) = delete;
32 
Flush()33   void Flush() { memset(static_cast<void*>(&cache_[0]), 0, sizeof(cache_)); }
34 
35   InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
36 
37  private:
cache(int index)38   InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
39 
40   Isolate* isolate_;
41 
42   static const int kInnerPointerToCodeCacheSize = 1024;
43   InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
44 };
45 
address()46 inline Address StackHandler::address() const {
47   return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
48 }
49 
next()50 inline StackHandler* StackHandler::next() const {
51   const int offset = StackHandlerConstants::kNextOffset;
52   return FromAddress(base::Memory<Address>(address() + offset));
53 }
54 
next_address()55 inline Address StackHandler::next_address() const {
56   return base::Memory<Address>(address() + StackHandlerConstants::kNextOffset);
57 }
58 
FromAddress(Address address)59 inline StackHandler* StackHandler::FromAddress(Address address) {
60   return reinterpret_cast<StackHandler*>(address);
61 }
62 
StackFrame(StackFrameIteratorBase * iterator)63 inline StackFrame::StackFrame(StackFrameIteratorBase* iterator)
64     : iterator_(iterator), isolate_(iterator_->isolate()) {}
65 
top_handler()66 inline StackHandler* StackFrame::top_handler() const {
67   return iterator_->handler();
68 }
69 
callee_pc()70 inline Address StackFrame::callee_pc() const {
71   return state_.callee_pc_address ? ReadPC(state_.callee_pc_address)
72                                   : kNullAddress;
73 }
74 
pc()75 inline Address StackFrame::pc() const { return ReadPC(pc_address()); }
76 
unauthenticated_pc()77 inline Address StackFrame::unauthenticated_pc() const {
78   return PointerAuthentication::StripPAC(*pc_address());
79 }
80 
ReadPC(Address * pc_address)81 inline Address StackFrame::ReadPC(Address* pc_address) {
82   return PointerAuthentication::AuthenticatePC(pc_address, kSystemPointerSize);
83 }
84 
ResolveReturnAddressLocation(Address * pc_address)85 inline Address* StackFrame::ResolveReturnAddressLocation(Address* pc_address) {
86   if (return_address_location_resolver_ == nullptr) {
87     return pc_address;
88   } else {
89     return reinterpret_cast<Address*>(return_address_location_resolver_(
90         reinterpret_cast<uintptr_t>(pc_address)));
91   }
92 }
93 
TypedFrame(StackFrameIteratorBase * iterator)94 inline TypedFrame::TypedFrame(StackFrameIteratorBase* iterator)
95     : CommonFrame(iterator) {}
96 
CommonFrameWithJSLinkage(StackFrameIteratorBase * iterator)97 inline CommonFrameWithJSLinkage::CommonFrameWithJSLinkage(
98     StackFrameIteratorBase* iterator)
99     : CommonFrame(iterator) {}
100 
TypedFrameWithJSLinkage(StackFrameIteratorBase * iterator)101 inline TypedFrameWithJSLinkage::TypedFrameWithJSLinkage(
102     StackFrameIteratorBase* iterator)
103     : CommonFrameWithJSLinkage(iterator) {}
104 
NativeFrame(StackFrameIteratorBase * iterator)105 inline NativeFrame::NativeFrame(StackFrameIteratorBase* iterator)
106     : TypedFrame(iterator) {}
107 
EntryFrame(StackFrameIteratorBase * iterator)108 inline EntryFrame::EntryFrame(StackFrameIteratorBase* iterator)
109     : TypedFrame(iterator) {}
110 
ConstructEntryFrame(StackFrameIteratorBase * iterator)111 inline ConstructEntryFrame::ConstructEntryFrame(
112     StackFrameIteratorBase* iterator)
113     : EntryFrame(iterator) {}
114 
ExitFrame(StackFrameIteratorBase * iterator)115 inline ExitFrame::ExitFrame(StackFrameIteratorBase* iterator)
116     : TypedFrame(iterator) {}
117 
BuiltinExitFrame(StackFrameIteratorBase * iterator)118 inline BuiltinExitFrame::BuiltinExitFrame(StackFrameIteratorBase* iterator)
119     : ExitFrame(iterator) {}
120 
receiver_slot_object()121 inline Object BuiltinExitFrame::receiver_slot_object() const {
122   // The receiver is the first argument on the frame.
123   // fp[1]: return address.
124   // ------- fixed extra builtin arguments -------
125   // fp[2]: new target.
126   // fp[3]: target.
127   // fp[4]: argc.
128   // fp[5]: hole.
129   // ------- JS stack arguments ------
130   // fp[6]: receiver
131   const int receiverOffset = BuiltinExitFrameConstants::kFirstArgumentOffset;
132   return Object(base::Memory<Address>(fp() + receiverOffset));
133 }
134 
argc_slot_object()135 inline Object BuiltinExitFrame::argc_slot_object() const {
136   return Object(
137       base::Memory<Address>(fp() + BuiltinExitFrameConstants::kArgcOffset));
138 }
139 
target_slot_object()140 inline Object BuiltinExitFrame::target_slot_object() const {
141   return Object(
142       base::Memory<Address>(fp() + BuiltinExitFrameConstants::kTargetOffset));
143 }
144 
new_target_slot_object()145 inline Object BuiltinExitFrame::new_target_slot_object() const {
146   return Object(base::Memory<Address>(
147       fp() + BuiltinExitFrameConstants::kNewTargetOffset));
148 }
149 
CommonFrame(StackFrameIteratorBase * iterator)150 inline CommonFrame::CommonFrame(StackFrameIteratorBase* iterator)
151     : StackFrame(iterator) {}
152 
GetExpression(int index)153 inline Object CommonFrame::GetExpression(int index) const {
154   return Object(base::Memory<Address>(GetExpressionAddress(index)));
155 }
156 
SetExpression(int index,Object value)157 inline void CommonFrame::SetExpression(int index, Object value) {
158   base::Memory<Address>(GetExpressionAddress(index)) = value.ptr();
159 }
160 
caller_fp()161 inline Address CommonFrame::caller_fp() const {
162   return base::Memory<Address>(fp() + StandardFrameConstants::kCallerFPOffset);
163 }
164 
caller_pc()165 inline Address CommonFrame::caller_pc() const {
166   return ReadPC(reinterpret_cast<Address*>(ComputePCAddress(fp())));
167 }
168 
ComputePCAddress(Address fp)169 inline Address CommonFrame::ComputePCAddress(Address fp) {
170   return fp + StandardFrameConstants::kCallerPCOffset;
171 }
172 
ComputeConstantPoolAddress(Address fp)173 inline Address CommonFrame::ComputeConstantPoolAddress(Address fp) {
174   return fp + StandardFrameConstants::kConstantPoolOffset;
175 }
176 
IsConstructFrame(Address fp)177 inline bool CommonFrameWithJSLinkage::IsConstructFrame(Address fp) {
178   intptr_t frame_type =
179       base::Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
180   return frame_type == StackFrame::TypeToMarker(StackFrame::CONSTRUCT);
181 }
182 
JavaScriptFrame(StackFrameIteratorBase * iterator)183 inline JavaScriptFrame::JavaScriptFrame(StackFrameIteratorBase* iterator)
184     : CommonFrameWithJSLinkage(iterator) {}
185 
GetParameterSlot(int index)186 Address CommonFrameWithJSLinkage::GetParameterSlot(int index) const {
187   DCHECK_LE(-1, index);
188   DCHECK_LT(index,
189             std::max(GetActualArgumentCount(), ComputeParametersCount()));
190   int parameter_offset = (index + 1) * kSystemPointerSize;
191   return caller_sp() + parameter_offset;
192 }
193 
GetActualArgumentCount()194 inline int CommonFrameWithJSLinkage::GetActualArgumentCount() const {
195   return 0;
196 }
197 
set_receiver(Object value)198 inline void JavaScriptFrame::set_receiver(Object value) {
199   base::Memory<Address>(GetParameterSlot(-1)) = value.ptr();
200 }
201 
function_slot_object()202 inline Object JavaScriptFrame::function_slot_object() const {
203   const int offset = StandardFrameConstants::kFunctionOffset;
204   return Object(base::Memory<Address>(fp() + offset));
205 }
206 
StubFrame(StackFrameIteratorBase * iterator)207 inline StubFrame::StubFrame(StackFrameIteratorBase* iterator)
208     : TypedFrame(iterator) {}
209 
OptimizedFrame(StackFrameIteratorBase * iterator)210 inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
211     : JavaScriptFrame(iterator) {}
212 
UnoptimizedFrame(StackFrameIteratorBase * iterator)213 inline UnoptimizedFrame::UnoptimizedFrame(StackFrameIteratorBase* iterator)
214     : JavaScriptFrame(iterator) {}
215 
InterpretedFrame(StackFrameIteratorBase * iterator)216 inline InterpretedFrame::InterpretedFrame(StackFrameIteratorBase* iterator)
217     : UnoptimizedFrame(iterator) {}
218 
BaselineFrame(StackFrameIteratorBase * iterator)219 inline BaselineFrame::BaselineFrame(StackFrameIteratorBase* iterator)
220     : UnoptimizedFrame(iterator) {}
221 
BuiltinFrame(StackFrameIteratorBase * iterator)222 inline BuiltinFrame::BuiltinFrame(StackFrameIteratorBase* iterator)
223     : TypedFrameWithJSLinkage(iterator) {}
224 
225 #if V8_ENABLE_WEBASSEMBLY
WasmFrame(StackFrameIteratorBase * iterator)226 inline WasmFrame::WasmFrame(StackFrameIteratorBase* iterator)
227     : TypedFrame(iterator) {}
228 
WasmExitFrame(StackFrameIteratorBase * iterator)229 inline WasmExitFrame::WasmExitFrame(StackFrameIteratorBase* iterator)
230     : WasmFrame(iterator) {}
231 
WasmDebugBreakFrame(StackFrameIteratorBase * iterator)232 inline WasmDebugBreakFrame::WasmDebugBreakFrame(
233     StackFrameIteratorBase* iterator)
234     : TypedFrame(iterator) {}
235 
WasmToJsFrame(StackFrameIteratorBase * iterator)236 inline WasmToJsFrame::WasmToJsFrame(StackFrameIteratorBase* iterator)
237     : StubFrame(iterator) {}
238 
JsToWasmFrame(StackFrameIteratorBase * iterator)239 inline JsToWasmFrame::JsToWasmFrame(StackFrameIteratorBase* iterator)
240     : StubFrame(iterator) {}
241 
StackSwitchFrame(StackFrameIteratorBase * iterator)242 inline StackSwitchFrame::StackSwitchFrame(StackFrameIteratorBase* iterator)
243     : ExitFrame(iterator) {}
244 
CWasmEntryFrame(StackFrameIteratorBase * iterator)245 inline CWasmEntryFrame::CWasmEntryFrame(StackFrameIteratorBase* iterator)
246     : StubFrame(iterator) {}
247 
WasmCompileLazyFrame(StackFrameIteratorBase * iterator)248 inline WasmCompileLazyFrame::WasmCompileLazyFrame(
249     StackFrameIteratorBase* iterator)
250     : TypedFrame(iterator) {}
251 #endif  // V8_ENABLE_WEBASSEMBLY
252 
InternalFrame(StackFrameIteratorBase * iterator)253 inline InternalFrame::InternalFrame(StackFrameIteratorBase* iterator)
254     : TypedFrame(iterator) {}
255 
ConstructFrame(StackFrameIteratorBase * iterator)256 inline ConstructFrame::ConstructFrame(StackFrameIteratorBase* iterator)
257     : InternalFrame(iterator) {}
258 
BuiltinContinuationFrame(StackFrameIteratorBase * iterator)259 inline BuiltinContinuationFrame::BuiltinContinuationFrame(
260     StackFrameIteratorBase* iterator)
261     : InternalFrame(iterator) {}
262 
JavaScriptBuiltinContinuationFrame(StackFrameIteratorBase * iterator)263 inline JavaScriptBuiltinContinuationFrame::JavaScriptBuiltinContinuationFrame(
264     StackFrameIteratorBase* iterator)
265     : TypedFrameWithJSLinkage(iterator) {}
266 
267 inline JavaScriptBuiltinContinuationWithCatchFrame::
JavaScriptBuiltinContinuationWithCatchFrame(StackFrameIteratorBase * iterator)268     JavaScriptBuiltinContinuationWithCatchFrame(
269         StackFrameIteratorBase* iterator)
270     : JavaScriptBuiltinContinuationFrame(iterator) {}
271 
JavaScriptFrameIterator(Isolate * isolate)272 inline JavaScriptFrameIterator::JavaScriptFrameIterator(Isolate* isolate)
273     : iterator_(isolate) {
274   if (!done()) Advance();
275 }
276 
JavaScriptFrameIterator(Isolate * isolate,ThreadLocalTop * top)277 inline JavaScriptFrameIterator::JavaScriptFrameIterator(Isolate* isolate,
278                                                         ThreadLocalTop* top)
279     : iterator_(isolate, top) {
280   if (!done()) Advance();
281 }
282 
frame()283 inline JavaScriptFrame* JavaScriptFrameIterator::frame() const {
284   StackFrame* frame = iterator_.frame();
285   return JavaScriptFrame::cast(frame);
286 }
287 
Reframe()288 inline JavaScriptFrame* JavaScriptFrameIterator::Reframe() {
289   StackFrame* frame = iterator_.Reframe();
290   return JavaScriptFrame::cast(frame);
291 }
292 
frame()293 inline CommonFrame* StackTraceFrameIterator::frame() const {
294   StackFrame* frame = iterator_.frame();
295 #if V8_ENABLE_WEBASSEMBLY
296   DCHECK(frame->is_java_script() || frame->is_wasm());
297 #else
298   DCHECK(frame->is_java_script());
299 #endif  // V8_ENABLE_WEBASSEMBLY
300   return static_cast<CommonFrame*>(frame);
301 }
302 
Reframe()303 inline CommonFrame* StackTraceFrameIterator::Reframe() {
304   iterator_.Reframe();
305   return frame();
306 }
307 
is_javascript()308 bool StackTraceFrameIterator::is_javascript() const {
309   return frame()->is_java_script();
310 }
311 
312 #if V8_ENABLE_WEBASSEMBLY
is_wasm()313 bool StackTraceFrameIterator::is_wasm() const { return frame()->is_wasm(); }
314 #endif  // V8_ENABLE_WEBASSEMBLY
315 
javascript_frame()316 JavaScriptFrame* StackTraceFrameIterator::javascript_frame() const {
317   return JavaScriptFrame::cast(frame());
318 }
319 
frame()320 inline StackFrame* SafeStackFrameIterator::frame() const {
321   DCHECK(!done());
322 #if V8_ENABLE_WEBASSEMBLY
323   DCHECK(frame_->is_java_script() || frame_->is_exit() ||
324          frame_->is_builtin_exit() || frame_->is_wasm() ||
325          frame_->is_wasm_to_js() || frame_->is_js_to_wasm());
326 #else
327   DCHECK(frame_->is_java_script() || frame_->is_exit() ||
328          frame_->is_builtin_exit());
329 #endif  // V8_ENABLE_WEBASSEMBLY
330   return frame_;
331 }
332 
333 }  // namespace internal
334 }  // namespace v8
335 
336 #endif  // V8_EXECUTION_FRAMES_INL_H_
337