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