V8 Project
v8::internal::SafeStackFrameIterator Class Reference

#include <frames.h>

+ Inheritance diagram for v8::internal::SafeStackFrameIterator:
+ Collaboration diagram for v8::internal::SafeStackFrameIterator:

Public Member Functions

 SafeStackFrameIterator (Isolate *isolate, Address fp, Address sp, Address js_entry_sp)
 
StackFrameframe () const
 
void Advance ()
 
StackFrame::Type top_frame_type () const
 

Private Member Functions

void AdvanceOneFrame ()
 
bool IsValidStackAddress (Address addr) const
 
bool IsValidFrame (StackFrame *frame) const
 
bool IsValidCaller (StackFrame *frame)
 
bool IsValidExitFrame (Address fp) const
 
bool IsValidTop (ThreadLocalTop *top) const
 

Private Attributes

const Address low_bound_
 
const Address high_bound_
 
StackFrame::Type top_frame_type_
 
ExternalCallbackScope * external_callback_scope_
 

Detailed Description

Definition at line 893 of file frames.h.

Constructor & Destructor Documentation

◆ SafeStackFrameIterator()

v8::internal::SafeStackFrameIterator::SafeStackFrameIterator ( Isolate isolate,
Address  fp,
Address  sp,
Address  js_entry_sp 
)

Definition at line 194 of file frames.cc.

197  : StackFrameIteratorBase(isolate, false),
198  low_bound_(sp),
199  high_bound_(js_entry_sp),
201  external_callback_scope_(isolate->external_callback_scope()) {
202  StackFrame::State state;
203  StackFrame::Type type;
204  ThreadLocalTop* top = isolate->thread_local_top();
205  if (IsValidTop(top)) {
207  top_frame_type_ = type;
208  } else if (IsValidStackAddress(fp)) {
209  DCHECK(fp != NULL);
210  state.fp = fp;
211  state.sp = sp;
212  state.pc_address = StackFrame::ResolveReturnAddressLocation(
213  reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
214  // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset,
215  // we check only that kMarkerOffset is within the stack bounds and do
216  // compile time check that kContextOffset slot is pushed on the stack before
217  // kMarkerOffset.
221  if (IsValidStackAddress(frame_marker)) {
222  type = StackFrame::ComputeType(this, &state);
223  top_frame_type_ = type;
224  } else {
225  // Mark the frame as JAVA_SCRIPT if we cannot determine its type.
226  // The frame anyways will be skipped.
227  type = StackFrame::JAVA_SCRIPT;
228  // Top frame is incomplete so we cannot reliably determine its type.
230  }
231  } else {
232  return;
233  }
234  if (SingletonFor(type) == NULL) return;
235  frame_ = SingletonFor(type, &state);
236  if (frame_ == NULL) return;
237 
238  Advance();
239 
240  if (frame_ != NULL && !frame_->is_exit() &&
242  external_callback_scope_->scope_address() < frame_->fp()) {
243  // Skip top ExternalCallbackScope if we already advanced to a JS frame
244  // under it. Sampler will anyways take this top external callback.
246  }
247 }
static Type GetStateForFramePointer(Address fp, State *state)
Definition: frames.cc:539
static Address c_entry_fp(ThreadLocalTop *thread)
Definition: isolate.h:647
StackFrame::Type top_frame_type_
Definition: frames.h:917
ExternalCallbackScope * external_callback_scope_
Definition: frames.h:918
bool IsValidTop(ThreadLocalTop *top) const
Definition: frames.cc:250
bool IsValidStackAddress(Address addr) const
Definition: frames.h:907
static const int kContextOffset
Definition: frames.h:162
static const int kMarkerOffset
Definition: frames.h:161
static Address ComputePCAddress(Address fp)
Definition: frames-inl.h:180
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
TypeImpl< ZoneTypeConfig > Type
const Register fp
const Register sp
byte * Address
Definition: globals.h:101
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
@ NONE

References Advance(), v8::internal::Isolate::c_entry_fp(), v8::internal::StandardFrame::ComputePCAddress(), DCHECK, external_callback_scope_, v8::internal::fp, v8::internal::ExitFrame::GetStateForFramePointer(), IsValidStackAddress(), IsValidTop(), v8::internal::StandardFrameConstants::kContextOffset, v8::internal::StandardFrameConstants::kMarkerOffset, NONE, NULL, v8::internal::sp, v8::internal::STATIC_ASSERT(), v8::internal::Isolate::thread_local_top(), and top_frame_type_.

+ Here is the call graph for this function:

Member Function Documentation

◆ Advance()

void v8::internal::SafeStackFrameIterator::Advance ( )

Definition at line 327 of file frames.cc.

327  {
328  while (true) {
329  AdvanceOneFrame();
330  if (done()) return;
331  if (frame_->is_java_script()) return;
332  if (frame_->is_exit() && external_callback_scope_) {
333  // Some of the EXIT frames may have ExternalCallbackScope allocated on
334  // top of them. In that case the scope corresponds to the first EXIT
335  // frame beneath it. There may be other EXIT frames on top of the
336  // ExternalCallbackScope, just skip them as we cannot collect any useful
337  // information about them.
338  if (external_callback_scope_->scope_address() < frame_->fp()) {
339  Address* callback_address =
340  external_callback_scope_->callback_address();
341  if (*callback_address != NULL) {
342  frame_->state_.pc_address = callback_address;
343  }
346  external_callback_scope_->scope_address() > frame_->fp());
347  return;
348  }
349  }
350  }
351 }

References AdvanceOneFrame(), DCHECK, external_callback_scope_, and NULL.

Referenced by v8::internal::TickSample::Init(), and SafeStackFrameIterator().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ AdvanceOneFrame()

void v8::internal::SafeStackFrameIterator::AdvanceOneFrame ( )
private

Definition at line 261 of file frames.cc.

261  {
262  DCHECK(!done());
263  StackFrame* last_frame = frame_;
264  Address last_sp = last_frame->sp(), last_fp = last_frame->fp();
265  // Before advancing to the next stack frame, perform pointer validity tests.
266  if (!IsValidFrame(last_frame) || !IsValidCaller(last_frame)) {
267  frame_ = NULL;
268  return;
269  }
270 
271  // Advance to the previous frame.
272  StackFrame::State state;
273  StackFrame::Type type = frame_->GetCallerState(&state);
274  frame_ = SingletonFor(type, &state);
275  if (frame_ == NULL) return;
276 
277  // Check that we have actually moved to the previous frame in the stack.
278  if (frame_->sp() < last_sp || frame_->fp() < last_fp) {
279  frame_ = NULL;
280  }
281 }
bool IsValidFrame(StackFrame *frame) const
Definition: frames.cc:284
bool IsValidCaller(StackFrame *frame)
Definition: frames.cc:289
HANDLE HANDLE LPSTACKFRAME64 StackFrame

References DCHECK, IsValidCaller(), IsValidFrame(), and NULL.

Referenced by Advance().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ frame()

StackFrame * v8::internal::SafeStackFrameIterator::frame ( ) const
inline

Definition at line 325 of file frames-inl.h.

325  {
326  DCHECK(!done());
327  DCHECK(frame_->is_java_script() || frame_->is_exit());
328  return frame_;
329 }

References DCHECK.

Referenced by v8::internal::TickSample::Init(), IsValidCaller(), and IsValidFrame().

+ Here is the caller graph for this function:

◆ IsValidCaller()

bool v8::internal::SafeStackFrameIterator::IsValidCaller ( StackFrame frame)
private

Definition at line 289 of file frames.cc.

289  {
290  StackFrame::State state;
291  if (frame->is_entry() || frame->is_entry_construct()) {
292  // See EntryFrame::GetCallerState. It computes the caller FP address
293  // and calls ExitFrame::GetStateForFramePointer on it. We need to be
294  // sure that caller FP address is valid.
295  Address caller_fp = Memory::Address_at(
297  if (!IsValidExitFrame(caller_fp)) return false;
298  } else if (frame->is_arguments_adaptor()) {
299  // See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that
300  // the number of arguments is stored on stack as Smi. We need to check
301  // that it really an Smi.
302  Object* number_of_args = reinterpret_cast<ArgumentsAdaptorFrame*>(frame)->
303  GetExpression(0);
304  if (!number_of_args->IsSmi()) {
305  return false;
306  }
307  }
308  frame->ComputeCallerState(&state);
309  return IsValidStackAddress(state.sp) && IsValidStackAddress(state.fp) &&
310  SingletonFor(frame->GetCallerState(&state)) != NULL;
311 }
static const int kCallerFPOffset
Definition: frames-arm.h:80
static Address & Address_at(Address addr)
Definition: v8memory.h:56
bool IsValidExitFrame(Address fp) const
Definition: frames.cc:314
kSerializedDataOffset Object
Definition: objects-inl.h:5322

References v8::internal::Memory::Address_at(), frame(), IsValidExitFrame(), IsValidStackAddress(), v8::internal::EntryFrameConstants::kCallerFPOffset, and NULL.

Referenced by AdvanceOneFrame().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsValidExitFrame()

bool v8::internal::SafeStackFrameIterator::IsValidExitFrame ( Address  fp) const
private

Definition at line 314 of file frames.cc.

314  {
315  if (!IsValidStackAddress(fp)) return false;
317  if (!IsValidStackAddress(sp)) return false;
318  StackFrame::State state;
319  ExitFrame::FillState(fp, sp, &state);
320  if (!IsValidStackAddress(reinterpret_cast<Address>(state.pc_address))) {
321  return false;
322  }
323  return *state.pc_address != NULL;
324 }
static void FillState(Address fp, Address sp, State *state)
Definition: frames.cc:553
static Address ComputeStackPointer(Address fp)
Definition: frames.cc:548

References v8::internal::ExitFrame::ComputeStackPointer(), v8::internal::ExitFrame::FillState(), v8::internal::fp, IsValidStackAddress(), NULL, and v8::internal::sp.

Referenced by IsValidCaller(), and IsValidTop().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsValidFrame()

bool v8::internal::SafeStackFrameIterator::IsValidFrame ( StackFrame frame) const
private

Definition at line 284 of file frames.cc.

284  {
285  return IsValidStackAddress(frame->sp()) && IsValidStackAddress(frame->fp());
286 }

References frame(), and IsValidStackAddress().

Referenced by AdvanceOneFrame().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsValidStackAddress()

bool v8::internal::SafeStackFrameIterator::IsValidStackAddress ( Address  addr) const
inlineprivate

Definition at line 907 of file frames.h.

907  {
908  return low_bound_ <= addr && addr <= high_bound_;
909  }

Referenced by IsValidCaller(), IsValidExitFrame(), IsValidFrame(), and SafeStackFrameIterator().

+ Here is the caller graph for this function:

◆ IsValidTop()

bool v8::internal::SafeStackFrameIterator::IsValidTop ( ThreadLocalTop *  top) const
private

Definition at line 250 of file frames.cc.

250  {
251  Address c_entry_fp = Isolate::c_entry_fp(top);
252  if (!IsValidExitFrame(c_entry_fp)) return false;
253  // There should be at least one JS_ENTRY stack handler.
254  Address handler = Isolate::handler(top);
255  if (handler == NULL) return false;
256  // Check that there are no js frames on top of the native frames.
257  return c_entry_fp < handler;
258 }
static Address handler(ThreadLocalTop *thread)
Definition: isolate.h:650

References v8::internal::Isolate::c_entry_fp(), v8::internal::Isolate::handler(), IsValidExitFrame(), and NULL.

Referenced by SafeStackFrameIterator().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ top_frame_type()

StackFrame::Type v8::internal::SafeStackFrameIterator::top_frame_type ( ) const
inline

Definition at line 902 of file frames.h.

902 { return top_frame_type_; }

Referenced by v8::internal::TickSample::Init().

+ Here is the caller graph for this function:

Member Data Documentation

◆ external_callback_scope_

ExternalCallbackScope* v8::internal::SafeStackFrameIterator::external_callback_scope_
private

Definition at line 918 of file frames.h.

Referenced by Advance(), and SafeStackFrameIterator().

◆ high_bound_

const Address v8::internal::SafeStackFrameIterator::high_bound_
private

Definition at line 916 of file frames.h.

◆ low_bound_

const Address v8::internal::SafeStackFrameIterator::low_bound_
private

Definition at line 915 of file frames.h.

◆ top_frame_type_

StackFrame::Type v8::internal::SafeStackFrameIterator::top_frame_type_
private

Definition at line 917 of file frames.h.

Referenced by SafeStackFrameIterator().


The documentation for this class was generated from the following files: