Remove callgrind generation from VM

This commit is contained in:
K. Lange 2024-03-06 16:37:26 +09:00
parent 6b134d11ff
commit 0eaa455fbe
7 changed files with 1 additions and 137 deletions

View File

@ -45,8 +45,6 @@ Halts execution and calls the debugger before every instruction.
Prints a message each time the garbage collector is run.
- `KRK_GLOBAL_ENABLE_STRESS_GC`
Causes the garbage collector to be called on every allocation (from the main thread).
- `KRK_GLOBAL_CALLGRIND`
Generate tracing data. `vm.callgrindFile` must be set to a writable stream to store the intermediate data collected by the VM.
- `KRK_GLOBAL_CLEAN_OUTPUT`
Disables automatic printing of uncaught exception tracebacks. Use `krk_dumpTraceback()` to print a traceback from the exception in the current thread to `stderr`.

View File

@ -1,65 +0,0 @@
'''
@brief Tool to process VM trace reports and generate callgrind-formatted output.
'''
import kuroko
import fileio
def processFile(sourcePath: str, pid: int , cmd: str):
'''@brief Process @p sourcePath from process @p pid with command @p cmd as a VM trace file.'''
let funcs = {}
with fileio.open(sourcePath,'r') as f:
for line in f.readlines():
let callerFile, callerFunc, callerLine, calleeFile, calleeFunc, calleeLine, nsecs = line.split(' ')
nsecs = float(nsecs)
let data = funcs.get((callerFile,callerFunc),{})
let call = data.get((callerLine,calleeFile,calleeFunc,calleeLine),(0,0))
let out = (call[0] + 1, call[1] + nsecs)
data[callerLine,calleeFile,calleeFunc,calleeLine] = out
funcs[callerFile,callerFunc] = data
let called = funcs.get((calleeFile,calleeFunc),{})
let times = called.get(None,(1,0))
called[None] = (calleeLine, times[1] + nsecs)
funcs[calleeFile,calleeFunc] = called
with fileio.open(f'callgrind.out.{pid}','w') as out:
out.write('# callgrind format\n')
out.write('creator: Kuroko\n')
out.write('positions: line\n')
out.write('events: nanoseconds\n')
out.write(f'cmd: {cmd}\n\n')
def defloat(f):
let s = int(f)
let n = str(int(f * 1000000000))
if len(n) > 9: n = n[-9:]
let o = (str(s) + '0' * (9 - len(n)) + n).lstrip('0')
return o if o else '0'
def cleanfunc(func):
for s in ['<module>','<listcomp>','<setcomp>','<dictcomp>','<lambda>']:
func = func.replace(s,'['+s[1:-1]+']')
return func.replace('@','<') + '>'
for key, value in funcs.items():
let sFile, sFunc = key
out.write(f'fl={sFile}\n')
out.write(f'fn={cleanfunc(sFunc)}\n')
if not sFunc.startswith('(root)'):
let startLine, totalNsecs = value[None]
for k, v in value.items():
if not k: continue
let sourceLine, file, func, destLine = k
let count, nsecs = v
totalNsecs -= nsecs
out.write(f'{startLine} {defloat(totalNsecs)}\n')
for k, v in value.items():
if not k: continue
let sourceLine, file, func, destLine = k
let count, totalNsecs = v
if file != sFile: out.write(f'cfi={file}\n')
out.write(f'cfn={cleanfunc(func)}\n')
out.write(f'calls={count} {destLine}\n')
out.write(f'{sourceLine} {defloat(totalNsecs)}\n')
out.write('\n')

View File

@ -33,8 +33,6 @@
#define PROMPT_MAIN ">>> "
#define PROMPT_BLOCK " > "
#define CALLGRIND_TMP_FILE "/tmp/kuroko.callgrind.tmp"
static int enableRline = 1;
static int exitRepl = 0;
static int pasteEnabled = 0;
@ -787,11 +785,6 @@ int main(int argc, char * argv[]) {
/* Disassemble instructions as they are executed. */
flags |= KRK_THREAD_ENABLE_TRACING;
break;
case 'T': {
flags |= KRK_GLOBAL_CALLGRIND;
vm.callgrindFile = fopen(CALLGRIND_TMP_FILE,"w");
break;
}
case 'i':
inspectAfter = 1;
break;
@ -837,7 +830,6 @@ int main(int argc, char * argv[]) {
" -r Disable complex line editing in the REPL.\n"
" -R depth Set maximum recursion depth.\n"
" -t Disassemble instructions as they are exceuted.\n"
" -T Write call trace file.\n"
" -C file Compile 'file', but do not execute it.\n"
" -M Print the default module import paths.\n"
" -S Enable single-step debugging.\n"
@ -1186,20 +1178,6 @@ _finishArgs:
}
}
if (vm.globalFlags & KRK_GLOBAL_CALLGRIND) {
fclose(vm.callgrindFile);
vm.globalFlags &= ~(KRK_GLOBAL_CALLGRIND);
krk_resetStack();
krk_startModule("<callgrind>");
krk_attachNamedObject(&krk_currentThread.module->fields, "filename", (KrkObj*)S(CALLGRIND_TMP_FILE));
krk_interpret(
"from callgrind import processFile\n"
"import kuroko\n"
"import os\n"
"processFile(filename, os.getpid(), ' '.join(kuroko.argv))","<callgrind>");
}
krk_freeVM();
if (IS_INTEGER(result)) return AS_INTEGER(result);

View File

@ -35,7 +35,6 @@ typedef int64_t krk_integer_type;
#if defined(_MSC_VER) && !defined(__clang__)
#define KRK_NO_DOCUMENTATION 1
#define KRK_NO_GC_TRACING 1
#define KRK_NO_CALLGRIND 1
typedef intptr_t ssize_t;
#pragma warning(disable : 4146) /* unary minus on unsigned */
#pragma warning(disable : 4996) /* sterror */

View File

@ -7,7 +7,6 @@
* for Kuroko, including initializing the VM and passing code to be interpreted.
*/
#include <stdarg.h>
#include <time.h>
#include <sys/types.h>
#include "kuroko.h"
#include "value.h"
@ -49,9 +48,6 @@ typedef struct {
size_t outSlots; /**< Offset into the stack at which stackTop will be reset upon return */
KrkTable * globals; /**< Pointer to the attribute table containing valud global vairables for this call */
KrkValue globalsOwner; /**< Owner of the current globals context, to give to new closures. */
#ifndef KRK_NO_CALLGRIND
struct timespec in_time;
#endif
} KrkCallFrame;
/**
@ -201,7 +197,6 @@ typedef struct KrkVM {
KrkObj** grayStack; /**< Scan list */
KrkThreadState * threads; /**< Invasive linked list of all VM threads. */
FILE * callgrindFile; /**< File to write unprocessed callgrind data to. */
struct DebuggerState * dbgState; /**< Opaque debugger state pointer. */
} KrkVM;
@ -218,7 +213,7 @@ typedef struct KrkVM {
#define KRK_GLOBAL_ENABLE_STRESS_GC (1 << 8)
#define KRK_GLOBAL_GC_PAUSED (1 << 9)
#define KRK_GLOBAL_CLEAN_OUTPUT (1 << 10)
#define KRK_GLOBAL_CALLGRIND (1 << 11)
/* 11 is available again */
#define KRK_GLOBAL_REPORT_GC_COLLECTS (1 << 12)
#define KRK_GLOBAL_THREADS (1 << 13)
#define KRK_GLOBAL_NO_DEFAULT_MODULES (1 << 14)

View File

@ -66,44 +66,6 @@ void krk_forceThreadData(void) {
#define krk_currentThread (*_macos_currentThread())
#endif
#if !defined(KRK_NO_TRACING) && !defined(__EMSCRIPTEN__) && !defined(KRK_NO_CALLGRIND)
static void _frame_in(KrkCallFrame * frame) {
clock_gettime(CLOCK_MONOTONIC, &frame->in_time);
}
static void _frame_out(KrkCallFrame * frame) {
if (frame->closure->function->obj.flags & KRK_OBJ_FLAGS_CODEOBJECT_IS_GENERATOR) return;
KrkCallFrame * caller = krk_currentThread.frameCount > 1 ? &krk_currentThread.frames[krk_currentThread.frameCount-2] : NULL;
struct timespec outTime, diff;
clock_gettime(CLOCK_MONOTONIC, &outTime);
diff.tv_sec = outTime.tv_sec - frame->in_time.tv_sec;
diff.tv_nsec = outTime.tv_nsec - frame->in_time.tv_nsec;
if (diff.tv_nsec < 0) {
diff.tv_sec--;
diff.tv_nsec += 1000000000L;
}
fprintf(vm.callgrindFile, "%s %s@%p %d %s %s@%p %d %lld.%.9ld\n",
caller ? (caller->closure->function->chunk.filename->chars) : "stdin",
caller ? (caller->closure->function->qualname ? caller->closure->function->qualname->chars : caller->closure->function->name->chars) : "(root)",
caller ? ((void*)caller->closure->function) : NULL,
caller ? ((int)krk_lineNumber(&caller->closure->function->chunk, caller->ip - caller->closure->function->chunk.code)) : 1,
frame->closure->function->chunk.filename->chars,
frame->closure->function->qualname ? frame->closure->function->qualname->chars : frame->closure->function->name->chars,
(void*)frame->closure->function,
(int)krk_lineNumber(&frame->closure->function->chunk, 0),
(long long)diff.tv_sec, diff.tv_nsec);
}
# define FRAME_IN(frame) if (unlikely(vm.globalFlags & KRK_GLOBAL_CALLGRIND)) { _frame_in(frame); }
# define FRAME_OUT(frame) if (unlikely(vm.globalFlags & KRK_GLOBAL_CALLGRIND)) { _frame_out(frame); }
#else
# define FRAME_IN(frame)
# define FRAME_OUT(frame)
#endif
/*
* In some threading configurations, particular on Windows,
* we can't have executables reference our thread-local thread
@ -621,7 +583,6 @@ _finishKwarg:
frame->outSlots = frame->slots - returnDepth;
frame->globalsOwner = closure->globalsOwner;
frame->globals = closure->globalsTable;
FRAME_IN(frame);
return 1;
_errorDuringPositionals:
@ -2220,7 +2181,6 @@ _finishReturn: (void)0;
break;
}
closeUpvalues(frame->slots);
FRAME_OUT(frame);
krk_currentThread.frameCount--;
if (krk_currentThread.frameCount == 0) {
krk_pop();

View File

@ -122,7 +122,6 @@ let modules = [
'json',
'collections',
'string',
'callgrind',
# Other stuff
'tools.gendoc',