5#ifndef V8_HEAP_BASE_STACK_H_
6#define V8_HEAP_BASE_STACK_H_
40#ifdef V8_USE_ADDRESS_SANITIZER
41 current_segment_.asan_fake_stack = __asan_get_current_fake_stack();
43#ifdef V8_USE_SAFE_STACK
44 current_segment_.unsafe_stack_start = __builtin___get_unsafe_stack_top();
51 static bool IsOnStack(
const void* slot);
54 IteratePointersUntilMarker(visitor);
55 IterateBackgroundStacks(visitor);
60 void IteratePointersUntilMarker(
StackVisitor* visitor)
const;
63 void IterateBackgroundStacks(
StackVisitor* visitor)
const;
67 template <
typename Callback>
69 TrampolineCallbackHelper(
static_cast<void*
>(&
callback),
70 &SetMarkerAndCallbackImpl<Callback>);
73 template <
typename Callback>
76 TrampolineCallbackHelper(
static_cast<void*
>(&
callback),
77 &SetMarkerAndCallbackImpl<Callback>);
79 DCHECK(IsOnCurrentStack(current_segment_.top));
86 template <
typename Callback>
89 std::pair<ThreadId, Callback*> info{thread, &
callback};
90 TrampolineCallbackHelper(
91 static_cast<void*
>(&info),
92 &SetMarkerForBackgroundThreadAndCallbackImpl<Callback>);
103 bool IsMarkerSet()
const {
return current_segment_.top !=
nullptr; }
106 auto it = background_stacks_.find(thread);
107 if (it == background_stacks_.end())
return false;
117 scan_simulator_callback_ =
callback;
126 const void* top =
nullptr;
128#ifdef V8_USE_ADDRESS_SANITIZER
130 const void* asan_fake_stack =
nullptr;
133#ifdef V8_USE_SAFE_STACK
139 const void* unsafe_stack_start =
nullptr;
140 const void* unsafe_stack_top =
nullptr;
144 Segment(
const void* stack_start,
const void* stack_top)
145 :
start(stack_start), top(stack_top) {
146#ifdef V8_USE_ADDRESS_SANITIZER
147 asan_fake_stack = __asan_get_current_fake_stack();
149#ifdef V8_USE_SAFE_STACK
150 unsafe_stack_start = __builtin___get_unsafe_stack_top();
151 unsafe_stack_top = __builtin___get_unsafe_stack_ptr();
158 static bool IsOnCurrentStack(
const void* ptr);
161 V8_NOINLINE void TrampolineCallbackHelper(
void* argument,
164 template <
typename Callback>
166 const void* stack_end) {
167 Segment previous_segment = stack->current_segment_;
168 stack->current_segment_.
top = stack_end;
169#ifdef V8_USE_SAFE_STACK
170 stack->current_segment_.unsafe_stack_top =
171 __builtin___get_unsafe_stack_ptr();
173 Callback*
callback =
static_cast<Callback*
>(argument);
175 stack->current_segment_ = previous_segment;
178 template <
typename Callback>
180 Stack* stack,
void* argument,
const void* stack_end) {
181 DCHECK(IsOnCurrentStack(stack_end));
183 *
static_cast<std::pair<ThreadId, Callback*>*
>(argument);
184 auto& background_stacks = stack->background_stacks_;
188 if (
auto it = background_stacks.find(thread);
189 it != background_stacks.end()) {
190 previous_segment = it->second;
199 background_stacks[thread] =
205 if (previous_segment.
top)
206 background_stacks[thread] = previous_segment;
208 background_stacks.erase(thread);
virtual void VisitPointer(const void *address)=0
virtual ~StackVisitor()=default
void(*)(Stack *, void *, const void *) IterateStackCallback
void IteratePointers(StackVisitor *visitor) const
V8_INLINE void SetMarkerIfNeededAndCallback(Callback callback)
static void SetMarkerForBackgroundThreadAndCallbackImpl(Stack *stack, void *argument, const void *stack_end)
static void SetMarkerAndCallbackImpl(Stack *stack, void *argument, const void *stack_end)
V8_INLINE void SetMarkerForBackgroundThreadAndCallback(ThreadId thread, Callback callback)
void SetScanSimulatorCallback(StackVisitorCallback callback)
bool HasBackgroundStacks() const
V8_INLINE void SetMarkerAndCallback(Callback callback)
std::map< ThreadId, Segment > background_stacks_
bool IsMarkerSetForBackgroundThread(ThreadId thread) const
static StackSlot GetStackStart()
void(*)(const Stack *, StackVisitor *, intptr_t *) IterateStackCallback
void(*)(StackVisitor *) StackVisitorCallback
#define DCHECK_NOT_NULL(val)
#define DCHECK(condition)
#define V8_EXPORT_PRIVATE
Segment(const void *stack_start, const void *stack_top)