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_DEBUG_DEBUG_H_
6 : #define V8_DEBUG_DEBUG_H_
7 :
8 : #include <vector>
9 :
10 : #include "src/allocation.h"
11 : #include "src/base/atomicops.h"
12 : #include "src/base/hashmap.h"
13 : #include "src/base/platform/platform.h"
14 : #include "src/debug/debug-interface.h"
15 : #include "src/debug/interface-types.h"
16 : #include "src/execution.h"
17 : #include "src/flags.h"
18 : #include "src/frames.h"
19 : #include "src/globals.h"
20 : #include "src/heap/factory.h"
21 : #include "src/objects/debug-objects.h"
22 : #include "src/runtime/runtime.h"
23 : #include "src/source-position-table.h"
24 : #include "src/string-stream.h"
25 : #include "src/v8threads.h"
26 :
27 : namespace v8 {
28 : namespace internal {
29 :
30 : // Forward declarations.
31 : class DebugScope;
32 : class JSGeneratorObject;
33 :
34 : // Step actions. NOTE: These values are in macros.py as well.
35 : enum StepAction : int8_t {
36 : StepNone = -1, // Stepping not prepared.
37 : StepOut = 0, // Step out of the current function.
38 : StepNext = 1, // Step to the next statement in the current function.
39 : StepIn = 2, // Step into new functions invoked or the next statement
40 : // in the current function.
41 : LastStepAction = StepIn
42 : };
43 :
44 : // Type of exception break. NOTE: These values are in macros.py as well.
45 : enum ExceptionBreakType {
46 : BreakException = 0,
47 : BreakUncaughtException = 1
48 : };
49 :
50 : enum DebugBreakType {
51 : NOT_DEBUG_BREAK,
52 : DEBUGGER_STATEMENT,
53 : DEBUG_BREAK_SLOT,
54 : DEBUG_BREAK_SLOT_AT_CALL,
55 : DEBUG_BREAK_SLOT_AT_RETURN,
56 : DEBUG_BREAK_SLOT_AT_SUSPEND,
57 : DEBUG_BREAK_AT_ENTRY,
58 : };
59 :
60 : enum IgnoreBreakMode {
61 : kIgnoreIfAllFramesBlackboxed,
62 : kIgnoreIfTopFrameBlackboxed
63 : };
64 :
65 : class BreakLocation {
66 : public:
67 : static BreakLocation FromFrame(Handle<DebugInfo> debug_info,
68 : JavaScriptFrame* frame);
69 :
70 : static void AllAtCurrentStatement(Handle<DebugInfo> debug_info,
71 : JavaScriptFrame* frame,
72 : std::vector<BreakLocation>* result_out);
73 :
74 : inline bool IsSuspend() const { return type_ == DEBUG_BREAK_SLOT_AT_SUSPEND; }
75 180763 : inline bool IsReturn() const { return type_ == DEBUG_BREAK_SLOT_AT_RETURN; }
76 : inline bool IsReturnOrSuspend() const {
77 7969 : return type_ >= DEBUG_BREAK_SLOT_AT_RETURN;
78 : }
79 : inline bool IsCall() const { return type_ == DEBUG_BREAK_SLOT_AT_CALL; }
80 5 : inline bool IsDebugBreakSlot() const { return type_ >= DEBUG_BREAK_SLOT; }
81 : inline bool IsDebuggerStatement() const {
82 : return type_ == DEBUGGER_STATEMENT;
83 : }
84 : inline bool IsDebugBreakAtEntry() const {
85 : bool result = type_ == DEBUG_BREAK_AT_ENTRY;
86 : return result;
87 : }
88 :
89 : bool HasBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info) const;
90 :
91 : inline int position() const { return position_; }
92 :
93 : debug::BreakLocationType type() const;
94 :
95 : JSGeneratorObject GetGeneratorObjectForSuspendedFrame(
96 : JavaScriptFrame* frame) const;
97 :
98 : private:
99 : BreakLocation(Handle<AbstractCode> abstract_code, DebugBreakType type,
100 : int code_offset, int position, int generator_obj_reg_index)
101 : : abstract_code_(abstract_code),
102 : code_offset_(code_offset),
103 : type_(type),
104 : position_(position),
105 436045 : generator_obj_reg_index_(generator_obj_reg_index) {
106 : DCHECK_NE(NOT_DEBUG_BREAK, type_);
107 : }
108 :
109 : BreakLocation(int position, DebugBreakType type)
110 : : code_offset_(0),
111 : type_(type),
112 : position_(position),
113 470 : generator_obj_reg_index_(0) {}
114 :
115 : static int BreakIndexFromCodeOffset(Handle<DebugInfo> debug_info,
116 : Handle<AbstractCode> abstract_code,
117 : int offset);
118 :
119 : void SetDebugBreak();
120 : void ClearDebugBreak();
121 :
122 : Handle<AbstractCode> abstract_code_;
123 : int code_offset_;
124 : DebugBreakType type_;
125 : int position_;
126 : int generator_obj_reg_index_;
127 :
128 : friend class BreakIterator;
129 : };
130 :
131 : class BreakIterator {
132 : public:
133 : explicit BreakIterator(Handle<DebugInfo> debug_info);
134 :
135 : BreakLocation GetBreakLocation();
136 148735461 : bool Done() const { return source_position_iterator_.done(); }
137 : void Next();
138 :
139 : void SkipToPosition(int position);
140 : void SkipTo(int count) {
141 11874710 : while (count-- > 0) Next();
142 : }
143 :
144 100924350 : int code_offset() { return source_position_iterator_.code_offset(); }
145 : int break_index() const { return break_index_; }
146 : inline int position() const { return position_; }
147 : inline int statement_position() const { return statement_position_; }
148 :
149 : void ClearDebugBreak();
150 : void SetDebugBreak();
151 :
152 : private:
153 : int BreakIndexFromPosition(int position);
154 :
155 : Isolate* isolate();
156 :
157 : DebugBreakType GetDebugBreakType();
158 :
159 : Handle<DebugInfo> debug_info_;
160 : int break_index_;
161 : int position_;
162 : int statement_position_;
163 : SourcePositionTableIterator source_position_iterator_;
164 : DisallowHeapAllocation no_gc_;
165 :
166 : DISALLOW_COPY_AND_ASSIGN(BreakIterator);
167 : };
168 :
169 : // Linked list holding debug info objects. The debug info objects are kept as
170 : // weak handles to avoid a debug info object to keep a function alive.
171 : class DebugInfoListNode {
172 : public:
173 : DebugInfoListNode(Isolate* isolate, DebugInfo debug_info);
174 : ~DebugInfoListNode();
175 :
176 : DebugInfoListNode* next() { return next_; }
177 30939 : void set_next(DebugInfoListNode* next) { next_ = next; }
178 : Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); }
179 :
180 : private:
181 : // Global (weak) handle to the debug info object.
182 : Address* debug_info_;
183 :
184 : // Next pointer for linked list.
185 : DebugInfoListNode* next_;
186 : };
187 :
188 : class DebugFeatureTracker {
189 : public:
190 : enum Feature {
191 : kActive = 1,
192 : kBreakPoint = 2,
193 : kStepping = 3,
194 : kHeapSnapshot = 4,
195 : kAllocationTracking = 5,
196 : kProfiler = 6,
197 : kLiveEdit = 7,
198 : };
199 :
200 : explicit DebugFeatureTracker(Isolate* isolate)
201 62883 : : isolate_(isolate), bitfield_(0) {}
202 : void Track(Feature feature);
203 :
204 : private:
205 : Isolate* isolate_;
206 : uint32_t bitfield_;
207 : };
208 :
209 :
210 : // This class contains the debugger support. The main purpose is to handle
211 : // setting break points in the code.
212 : //
213 : // This class controls the debug info for all functions which currently have
214 : // active breakpoints in them. This debug info is held in the heap root object
215 : // debug_info which is a FixedArray. Each entry in this list is of class
216 : // DebugInfo.
217 : class Debug {
218 : public:
219 : // Debug event triggers.
220 : void OnDebugBreak(Handle<FixedArray> break_points_hit);
221 :
222 : void OnThrow(Handle<Object> exception);
223 : void OnPromiseReject(Handle<Object> promise, Handle<Object> value);
224 : void OnCompileError(Handle<Script> script);
225 : void OnAfterCompile(Handle<Script> script);
226 :
227 : void HandleDebugBreak(IgnoreBreakMode ignore_break_mode);
228 :
229 : // The break target may not be the top-most frame, since we may be
230 : // breaking before entering a function that cannot contain break points.
231 : void Break(JavaScriptFrame* frame, Handle<JSFunction> break_target);
232 :
233 : // Scripts handling.
234 : Handle<FixedArray> GetLoadedScripts();
235 :
236 : // Break point handling.
237 : bool SetBreakPoint(Handle<JSFunction> function,
238 : Handle<BreakPoint> break_point, int* source_position);
239 : void ClearBreakPoint(Handle<BreakPoint> break_point);
240 : void ChangeBreakOnException(ExceptionBreakType type, bool enable);
241 : bool IsBreakOnException(ExceptionBreakType type);
242 :
243 : bool SetBreakPointForScript(Handle<Script> script, Handle<String> condition,
244 : int* source_position, int* id);
245 : bool SetBreakpointForFunction(Handle<JSFunction> function,
246 : Handle<String> condition, int* id);
247 : void RemoveBreakpoint(int id);
248 :
249 : // Find breakpoints from the debug info and the break location and check
250 : // whether they are hit. Return an empty handle if not, or a FixedArray with
251 : // hit BreakPoint objects.
252 : MaybeHandle<FixedArray> GetHitBreakPoints(Handle<DebugInfo> debug_info,
253 : int position);
254 :
255 : // Stepping handling.
256 : void PrepareStep(StepAction step_action);
257 : void PrepareStepIn(Handle<JSFunction> function);
258 : void PrepareStepInSuspendedGenerator();
259 : void PrepareStepOnThrow();
260 : void ClearStepping();
261 :
262 : void SetBreakOnNextFunctionCall();
263 : void ClearBreakOnNextFunctionCall();
264 :
265 : void DeoptimizeFunction(Handle<SharedFunctionInfo> shared);
266 : void PrepareFunctionForDebugExecution(Handle<SharedFunctionInfo> shared);
267 : void InstallDebugBreakTrampoline();
268 : bool GetPossibleBreakpoints(Handle<Script> script, int start_position,
269 : int end_position, bool restrict_to_function,
270 : std::vector<BreakLocation>* locations);
271 :
272 : bool IsBlackboxed(Handle<SharedFunctionInfo> shared);
273 :
274 : bool CanBreakAtEntry(Handle<SharedFunctionInfo> shared);
275 :
276 : void SetDebugDelegate(debug::DebugDelegate* delegate);
277 :
278 : // Returns whether the operation succeeded.
279 : bool EnsureBreakInfo(Handle<SharedFunctionInfo> shared);
280 : void CreateBreakInfo(Handle<SharedFunctionInfo> shared);
281 : Handle<DebugInfo> GetOrCreateDebugInfo(Handle<SharedFunctionInfo> shared);
282 :
283 : void InstallCoverageInfo(Handle<SharedFunctionInfo> shared,
284 : Handle<CoverageInfo> coverage_info);
285 : void RemoveAllCoverageInfos();
286 :
287 : // This function is used in FunctionNameUsing* tests.
288 : Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script,
289 : int position);
290 :
291 : static Handle<Object> GetSourceBreakLocations(
292 : Isolate* isolate, Handle<SharedFunctionInfo> shared);
293 :
294 : // Check whether this frame is just about to return.
295 : bool IsBreakAtReturn(JavaScriptFrame* frame);
296 :
297 : // Support for LiveEdit
298 : void ScheduleFrameRestart(StackFrame* frame);
299 :
300 : bool AllFramesOnStackAreBlackboxed();
301 :
302 : // Set new script source, throw an exception if error occurred. When preview
303 : // is true: try to set source, throw exception if any without actual script
304 : // change. stack_changed is true if after editing script on pause stack is
305 : // changed and client should request stack trace again.
306 : bool SetScriptSource(Handle<Script> script, Handle<String> source,
307 : bool preview, debug::LiveEditResult* result);
308 :
309 : int GetFunctionDebuggingId(Handle<JSFunction> function);
310 :
311 : // Threading support.
312 : char* ArchiveDebug(char* to);
313 : char* RestoreDebug(char* from);
314 : static int ArchiveSpacePerThread();
315 : void FreeThreadResources() { }
316 : void Iterate(RootVisitor* v);
317 11836 : void InitThread(const ExecutionAccess& lock) { ThreadInit(); }
318 :
319 44519 : bool CheckExecutionState() { return is_active(); }
320 :
321 : void StartSideEffectCheckMode();
322 : void StopSideEffectCheckMode();
323 :
324 : void ApplySideEffectChecks(Handle<DebugInfo> debug_info);
325 : void ClearSideEffectChecks(Handle<DebugInfo> debug_info);
326 :
327 : bool PerformSideEffectCheck(Handle<JSFunction> function,
328 : Handle<Object> receiver);
329 :
330 : enum AccessorKind { kNotAccessor, kGetter, kSetter };
331 : bool PerformSideEffectCheckForCallback(Handle<Object> callback_info,
332 : Handle<Object> receiver,
333 : AccessorKind accessor_kind);
334 : bool PerformSideEffectCheckAtBytecode(InterpretedFrame* frame);
335 : bool PerformSideEffectCheckForObject(Handle<Object> object);
336 :
337 : // Flags and states.
338 29069 : inline bool is_active() const { return is_active_; }
339 : inline bool in_debug_scope() const {
340 1937287 : return !!base::Relaxed_Load(&thread_local_.current_debug_scope_);
341 : }
342 537714 : inline bool needs_check_on_function_call() const {
343 537714 : return hook_on_function_call_;
344 : }
345 :
346 7039 : void set_break_points_active(bool v) { break_points_active_ = v; }
347 8481 : bool break_points_active() const { return break_points_active_; }
348 :
349 : StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
350 :
351 : Handle<Object> return_value_handle();
352 66515 : Object return_value() { return thread_local_.return_value_; }
353 133432 : void set_return_value(Object value) { thread_local_.return_value_ = value; }
354 :
355 : // Support for embedding into generated code.
356 : Address is_active_address() {
357 63285 : return reinterpret_cast<Address>(&is_active_);
358 : }
359 :
360 : Address hook_on_function_call_address() {
361 63275 : return reinterpret_cast<Address>(&hook_on_function_call_);
362 : }
363 :
364 : Address suspended_generator_address() {
365 62938 : return reinterpret_cast<Address>(&thread_local_.suspended_generator_);
366 : }
367 :
368 : Address restart_fp_address() {
369 64114 : return reinterpret_cast<Address>(&thread_local_.restart_fp_);
370 : }
371 66711 : bool will_restart() const {
372 66711 : return thread_local_.restart_fp_ != kNullAddress;
373 : }
374 :
375 537714 : StepAction last_step_action() { return thread_local_.last_step_action_; }
376 16456 : bool break_on_next_function_call() const {
377 16456 : return thread_local_.break_on_next_function_call_;
378 : }
379 :
380 : DebugFeatureTracker* feature_tracker() { return &feature_tracker_; }
381 :
382 : // For functions in which we cannot set a break point, use a canonical
383 : // source position for break points.
384 : static const int kBreakAtEntryPosition = 0;
385 :
386 : void RemoveBreakInfoAndMaybeFree(Handle<DebugInfo> debug_info);
387 :
388 : private:
389 : explicit Debug(Isolate* isolate);
390 : ~Debug();
391 :
392 : void UpdateDebugInfosForExecutionMode();
393 : void UpdateState();
394 : void UpdateHookOnFunctionCall();
395 : void Unload();
396 :
397 : // Return the number of virtual frames below debugger entry.
398 : int CurrentFrameCount();
399 :
400 : inline bool ignore_events() const {
401 7016593 : return is_suppressed_ || !is_active_ ||
402 685939 : isolate_->debug_execution_mode() == DebugInfo::kSideEffects;
403 : }
404 : inline bool break_disabled() const { return break_disabled_; }
405 :
406 : void clear_suspended_generator() {
407 136342 : thread_local_.suspended_generator_ = Smi::kZero;
408 : }
409 :
410 : bool has_suspended_generator() const {
411 : return thread_local_.suspended_generator_ != Smi::kZero;
412 : }
413 :
414 : bool IsExceptionBlackboxed(bool uncaught);
415 :
416 : void OnException(Handle<Object> exception, Handle<Object> promise,
417 : v8::debug::ExceptionType exception_type);
418 :
419 : void ProcessCompileEvent(bool has_compile_error, Handle<Script> script);
420 :
421 : // Find the closest source position for a break point for a given position.
422 : int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position);
423 : // Instrument code to break at break points.
424 : void ApplyBreakPoints(Handle<DebugInfo> debug_info);
425 : // Clear code from instrumentation.
426 : void ClearBreakPoints(Handle<DebugInfo> debug_info);
427 : // Clear all code from instrumentation.
428 : void ClearAllBreakPoints();
429 : // Instrument a function with one-shots.
430 : void FloodWithOneShot(Handle<SharedFunctionInfo> function,
431 : bool returns_only = false);
432 : // Clear all one-shot instrumentations, but restore break points.
433 : void ClearOneShot();
434 :
435 : bool IsFrameBlackboxed(JavaScriptFrame* frame);
436 :
437 : void ActivateStepOut(StackFrame* frame);
438 : MaybeHandle<FixedArray> CheckBreakPoints(Handle<DebugInfo> debug_info,
439 : BreakLocation* location,
440 : bool* has_break_points = nullptr);
441 : bool IsMutedAtCurrentLocation(JavaScriptFrame* frame);
442 : // Check whether a BreakPoint object is hit. Evaluate condition depending
443 : // on whether this is a regular break location or a break at function entry.
444 : bool CheckBreakPoint(Handle<BreakPoint> break_point, bool is_break_at_entry);
445 :
446 : inline void AssertDebugContext() {
447 : DCHECK(in_debug_scope());
448 : }
449 :
450 : void ThreadInit();
451 :
452 : void PrintBreakLocation();
453 :
454 : void ClearAllDebuggerHints();
455 :
456 : // Wraps logic for clearing and maybe freeing all debug infos.
457 : typedef std::function<void(Handle<DebugInfo>)> DebugInfoClearFunction;
458 : void ClearAllDebugInfos(const DebugInfoClearFunction& clear_function);
459 :
460 : void FindDebugInfo(Handle<DebugInfo> debug_info, DebugInfoListNode** prev,
461 : DebugInfoListNode** curr);
462 : void FreeDebugInfoListNode(DebugInfoListNode* prev, DebugInfoListNode* node);
463 :
464 : debug::DebugDelegate* debug_delegate_ = nullptr;
465 :
466 : // Debugger is active, i.e. there is a debug event listener attached.
467 : bool is_active_;
468 : // Debugger needs to be notified on every new function call.
469 : // Used for stepping and read-only checks
470 : bool hook_on_function_call_;
471 : // Suppress debug events.
472 : bool is_suppressed_;
473 : // Running liveedit.
474 : bool running_live_edit_ = false;
475 : // Do not trigger debug break events.
476 : bool break_disabled_;
477 : // Do not break on break points.
478 : bool break_points_active_;
479 : // Trigger debug break events for all exceptions.
480 : bool break_on_exception_;
481 : // Trigger debug break events for uncaught exceptions.
482 : bool break_on_uncaught_exception_;
483 : // Termination exception because side effect check has failed.
484 : bool side_effect_check_failed_;
485 :
486 : // List of active debug info objects.
487 : DebugInfoListNode* debug_info_list_;
488 :
489 : // Used for side effect check to mark temporary objects.
490 : class TemporaryObjectsTracker;
491 : std::unique_ptr<TemporaryObjectsTracker> temporary_objects_;
492 :
493 : Handle<RegExpMatchInfo> regexp_match_info_;
494 :
495 : // Used to collect histogram data on debugger feature usage.
496 : DebugFeatureTracker feature_tracker_;
497 :
498 : // Per-thread data.
499 62883 : class ThreadLocal {
500 : public:
501 : // Top debugger entry.
502 : base::AtomicWord current_debug_scope_;
503 :
504 : // Frame id for the frame of the current break.
505 : StackFrame::Id break_frame_id_;
506 :
507 : // Step action for last step performed.
508 : StepAction last_step_action_;
509 :
510 : // If set, next PrepareStepIn will ignore this function until stepped into
511 : // another function, at which point this will be cleared.
512 : Object ignore_step_into_function_;
513 :
514 : // If set then we need to repeat StepOut action at return.
515 : bool fast_forward_to_return_;
516 :
517 : // Source statement position from last step next action.
518 : int last_statement_position_;
519 :
520 : // Frame pointer from last step next or step frame action.
521 : int last_frame_count_;
522 :
523 : // Frame pointer of the target frame we want to arrive at.
524 : int target_frame_count_;
525 :
526 : // Value of the accumulator at the point of entering the debugger.
527 : Object return_value_;
528 :
529 : // The suspended generator object to track when stepping.
530 : Object suspended_generator_;
531 :
532 : // The new frame pointer to drop to when restarting a frame.
533 : Address restart_fp_;
534 :
535 : // Last used inspector breakpoint id.
536 : int last_breakpoint_id_;
537 :
538 : // This flag is true when SetBreakOnNextFunctionCall is called and it forces
539 : // debugger to break on next function call.
540 : bool break_on_next_function_call_;
541 : };
542 :
543 : // Storage location for registers when handling debug break calls
544 : ThreadLocal thread_local_;
545 :
546 : Isolate* isolate_;
547 :
548 : friend class Isolate;
549 : friend class DebugScope;
550 : friend class DisableBreak;
551 : friend class LiveEdit;
552 : friend class SuppressDebug;
553 :
554 : friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc
555 : friend void CheckDebuggerUnloaded(); // In test-debug.cc
556 :
557 : DISALLOW_COPY_AND_ASSIGN(Debug);
558 : };
559 :
560 : // This scope is used to load and enter the debug context and create a new
561 : // break state. Leaving the scope will restore the previous state.
562 : class DebugScope {
563 : public:
564 : explicit DebugScope(Debug* debug);
565 : ~DebugScope();
566 :
567 : private:
568 252806 : Isolate* isolate() { return debug_->isolate_; }
569 :
570 : Debug* debug_;
571 : DebugScope* prev_; // Previous scope if entered recursively.
572 : StackFrame::Id break_frame_id_; // Previous break frame id.
573 : PostponeInterruptsScope no_interrupts_;
574 : };
575 :
576 : // This scope is used to handle return values in nested debug break points.
577 : // When there are nested debug breaks, we use this to restore the return
578 : // value to the previous state. This is not merged with DebugScope because
579 : // return_value_ will not be cleared when we use DebugScope.
580 : class ReturnValueScope {
581 : public:
582 : explicit ReturnValueScope(Debug* debug);
583 : ~ReturnValueScope();
584 :
585 : private:
586 : Debug* debug_;
587 : Handle<Object> return_value_; // Previous result.
588 : };
589 :
590 : // Stack allocated class for disabling break.
591 : class DisableBreak {
592 : public:
593 : explicit DisableBreak(Debug* debug, bool disable = true)
594 258374 : : debug_(debug), previous_break_disabled_(debug->break_disabled_) {
595 258374 : debug_->break_disabled_ = disable;
596 : }
597 : ~DisableBreak() {
598 258374 : debug_->break_disabled_ = previous_break_disabled_;
599 : }
600 :
601 : private:
602 : Debug* debug_;
603 : bool previous_break_disabled_;
604 : DISALLOW_COPY_AND_ASSIGN(DisableBreak);
605 : };
606 :
607 : class SuppressDebug {
608 : public:
609 : explicit SuppressDebug(Debug* debug)
610 42768 : : debug_(debug), old_state_(debug->is_suppressed_) {
611 42768 : debug_->is_suppressed_ = true;
612 : }
613 42768 : ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
614 :
615 : private:
616 : Debug* debug_;
617 : bool old_state_;
618 : DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
619 : };
620 :
621 : // Code generator routines.
622 : class DebugCodegen : public AllStatic {
623 : public:
624 : enum DebugBreakCallHelperMode {
625 : SAVE_RESULT_REGISTER,
626 : IGNORE_RESULT_REGISTER
627 : };
628 :
629 : // Builtin to drop frames to restart function.
630 : static void GenerateFrameDropperTrampoline(MacroAssembler* masm);
631 :
632 : // Builtin to atomically (wrt deopts) handle debugger statement and
633 : // drop frames to restart function if necessary.
634 : static void GenerateHandleDebuggerStatement(MacroAssembler* masm);
635 :
636 : // Builtin to trigger a debug break before entering the function.
637 : static void GenerateDebugBreakTrampoline(MacroAssembler* masm);
638 : };
639 :
640 :
641 : } // namespace internal
642 : } // namespace v8
643 :
644 : #endif // V8_DEBUG_DEBUG_H_
|