draft LineProfiler

This commit is contained in:
blueloveTH 2025-05-28 01:49:33 +08:00
parent 33963d7054
commit c4ab63ca15
7 changed files with 93 additions and 3 deletions

View File

@ -24,7 +24,7 @@
#define SMALLMAP_T__HEADER
#define K void*
#define V int
#define V py_i64
#define NAME c11_smallmap_p2i
#include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__HEADER

View File

@ -0,0 +1,25 @@
#pragma once
#include "pocketpy/pocketpy.h"
#include <time.h>
#include "pocketpy/interpreter/frame.h"
typedef struct LineRecord {
py_i64 hits;
clock_t time;
} LineRecord;
typedef struct LineProfiler {
c11_smallmap_p2i records; // SourceData* -> LineRecord[]
SourceLocation prev_loc;
clock_t prev_time;
} LineProfiler;
void LineProfiler__ctor(LineProfiler* self);
void LineProfiler__dtor(LineProfiler* self);
LineRecord* LineProfiler__get_record(LineProfiler* self, SourceLocation loc);
void LineProfiler__begin(LineProfiler* self, bool reset);
void LineProfiler__tracefunc_line(LineProfiler* self, py_Frame* frame);
void LineProfiler__end(LineProfiler* self);
void VM__set_line_profiler(VM* self, LineProfiler* profiler);

View File

@ -7,6 +7,7 @@
#include "pocketpy/interpreter/frame.h"
#include "pocketpy/interpreter/typeinfo.h"
#include "pocketpy/interpreter/name.h"
#include "pocketpy/interpreter/line_profiler.h"
#include <time.h>
// TODO:
@ -52,6 +53,7 @@ typedef struct VM {
py_StackRef curr_decl_based_function;
TraceInfo trace_info;
WatchdogInfo watchdog_info;
LineProfiler* line_profiler;
py_TValue vectorcall_buffer[PK_MAX_CO_VARNAMES];
InternedNames names;

View File

@ -20,7 +20,7 @@
#define SMALLMAP_T__SOURCE
#define K void*
#define V int
#define V py_i64
#define NAME c11_smallmap_p2i
#include "pocketpy/xmacros/smallmap.h"
#undef SMALLMAP_T__SOURCE

View File

@ -105,11 +105,14 @@ FrameResult VM__run_top_frame(VM* self) {
PK_INCREF(loc.src);
self->trace_info.prev_loc = loc;
self->trace_info.func(frame, TRACE_EVENT_LINE);
if(self->line_profiler) {
LineProfiler__tracefunc_line(self->line_profiler, frame);
}
}
}
#if PK_ENABLE_WATCHDOG
if(self->watchdog_info.max_reset_time > 0){
if(self->watchdog_info.max_reset_time > 0) {
clock_t now = clock();
if(now > self->watchdog_info.max_reset_time) {
self->watchdog_info.max_reset_time = 0;

View File

@ -0,0 +1,56 @@
#include "pocketpy/interpreter/line_profiler.h"
void LineProfiler__ctor(LineProfiler* self) {
c11_smallmap_p2i__ctor(&self->records);
self->prev_loc.src = NULL;
self->prev_time = 0;
}
void LineProfiler__dtor(LineProfiler* self) {
for(int i = 0; i < self->records.length; i++) {
LineRecord* lines = c11__getitem(LineRecord*, &self->records, i);
PK_FREE(lines);
}
c11_smallmap_p2i__dtor(&self->records);
}
LineRecord* LineProfiler__get_record(LineProfiler* self, SourceLocation loc) {
LineRecord* lines = (LineRecord*)c11_smallmap_p2i__get(&self->records, loc.src, 0);
if(lines == NULL) {
int max_lineno = loc.src->line_starts.length;
lines = PK_MALLOC(sizeof(LineRecord) * (max_lineno + 1));
memset(lines, 0, sizeof(LineRecord) * (max_lineno + 1));
c11_smallmap_p2i__set(&self->records, loc.src, (py_i64)lines);
}
return &lines[loc.lineno];
}
void LineProfiler__begin(LineProfiler* self, bool reset) {
if(self->records.length > 0 && reset) {
LineProfiler__dtor(self);
LineProfiler__ctor(self);
}
self->prev_loc.src = NULL;
self->prev_time = 0;
VM__set_line_profiler(pk_current_vm, self);
}
void LineProfiler__tracefunc_line(LineProfiler* self, py_Frame* frame) {
clock_t now = clock();
if(self->prev_loc.src != NULL) {
LineRecord* line = LineProfiler__get_record(self, self->prev_loc);
line->hits++;
line->time += now - self->prev_time;
}
self->prev_loc = Frame__source_location(frame);
self->prev_time = now;
}
void LineProfiler__end(LineProfiler* self) {
if(self->prev_loc.src != NULL) {
LineRecord* line = LineProfiler__get_record(self, self->prev_loc);
line->hits++;
line->time += clock() - self->prev_time;
}
VM__set_line_profiler(pk_current_vm, NULL);
}

View File

@ -85,6 +85,8 @@ void VM__ctor(VM* self) {
self->curr_class = NULL;
self->curr_decl_based_function = NULL;
memset(&self->trace_info, 0, sizeof(TraceInfo));
memset(&self->watchdog_info, 0, sizeof(WatchdogInfo));
self->line_profiler = NULL;
FixedMemoryPool__ctor(&self->pool_frame, sizeof(py_Frame), 32);
@ -269,6 +271,8 @@ void VM__dtor(VM* self) {
InternedNames__dtor(&self->names);
}
void VM__set_line_profiler(VM* self, LineProfiler* profiler) { self->line_profiler = profiler; }
void VM__push_frame(VM* self, py_Frame* frame) {
frame->f_back = self->top_frame;
self->top_frame = frame;