Merge remote-tracking branch 'upstream/main' into tachyon-opcodes

This commit is contained in:
Pablo Galindo Salgado 2025-12-07 04:38:30 +00:00
commit 8129e3d7f4
154 changed files with 10330 additions and 4926 deletions

View file

@ -201,6 +201,11 @@ def _add_sampling_options(parser):
help="Gather bytecode opcode information for instruction-level profiling "
"(shows which bytecode instructions are executing, including specializations).",
)
sampling_group.add_argument(
"--async-aware",
action="store_true",
help="Enable async-aware profiling (uses task-based stack reconstruction)",
)
def _add_mode_options(parser):
@ -211,7 +216,14 @@ def _add_mode_options(parser):
choices=["wall", "cpu", "gil"],
default="wall",
help="Sampling mode: wall (all samples), cpu (only samples when thread is on CPU), "
"gil (only samples when thread holds the GIL)",
"gil (only samples when thread holds the GIL). Incompatible with --async-aware",
)
mode_group.add_argument(
"--async-mode",
choices=["running", "all"],
default="running",
help='Async profiling mode: "running" (only running task) '
'or "all" (all tasks including waiting). Requires --async-aware',
)
@ -392,6 +404,27 @@ def _validate_args(args, parser):
"Live mode requires the curses module, which is not available."
)
# Async-aware mode is incompatible with --native, --no-gc, --mode, and --all-threads
if args.async_aware:
issues = []
if args.native:
issues.append("--native")
if not args.gc:
issues.append("--no-gc")
if hasattr(args, 'mode') and args.mode != "wall":
issues.append(f"--mode={args.mode}")
if hasattr(args, 'all_threads') and args.all_threads:
issues.append("--all-threads")
if issues:
parser.error(
f"Options {', '.join(issues)} are incompatible with --async-aware. "
"Async-aware profiling uses task-based stack reconstruction."
)
# --async-mode requires --async-aware
if hasattr(args, 'async_mode') and args.async_mode != "running" and not args.async_aware:
parser.error("--async-mode requires --async-aware to be enabled.")
# Live mode is incompatible with format options
if hasattr(args, 'live') and args.live:
if args.format != "pstats":
@ -587,6 +620,7 @@ def _handle_attach(args):
all_threads=args.all_threads,
realtime_stats=args.realtime_stats,
mode=mode,
async_aware=args.async_mode if args.async_aware else None,
native=args.native,
gc=args.gc,
opcodes=args.opcodes,
@ -636,6 +670,7 @@ def _handle_run(args):
all_threads=args.all_threads,
realtime_stats=args.realtime_stats,
mode=mode,
async_aware=args.async_mode if args.async_aware else None,
native=args.native,
gc=args.gc,
opcodes=args.opcodes,
@ -670,6 +705,7 @@ def _handle_live_attach(args, pid):
pid=pid,
mode=mode,
opcodes=args.opcodes,
async_aware=args.async_mode if args.async_aware else None,
)
# Sample in live mode
@ -680,6 +716,7 @@ def _handle_live_attach(args, pid):
all_threads=args.all_threads,
realtime_stats=args.realtime_stats,
mode=mode,
async_aware=args.async_mode if args.async_aware else None,
native=args.native,
gc=args.gc,
opcodes=args.opcodes,
@ -711,6 +748,7 @@ def _handle_live_run(args):
pid=process.pid,
mode=mode,
opcodes=args.opcodes,
async_aware=args.async_mode if args.async_aware else None,
)
# Profile the subprocess in live mode
@ -722,6 +760,7 @@ def _handle_live_run(args):
all_threads=args.all_threads,
realtime_stats=args.realtime_stats,
mode=mode,
async_aware=args.async_mode if args.async_aware else None,
native=args.native,
gc=args.gc,
opcodes=args.opcodes,