Make maximumCallDepth thread-local, expose changing it when feasible
This commit is contained in:
parent
80754593ad
commit
416ed28206
@ -167,6 +167,7 @@ typedef struct KrkThreadState {
|
||||
KrkInstance * module; /**< The current module execution context. */
|
||||
KrkValue currentException; /**< When an exception is thrown, it is stored here. */
|
||||
int flags; /**< Thread-local VM flags; each thread inherits the low byte of the global VM flags. */
|
||||
unsigned int maximumCallDepth; /**< Maximum recursive call depth. */
|
||||
KrkValue * stackMax; /**< End of allocated stack space. */
|
||||
|
||||
KrkValue scratchSpace[KRK_THREAD_SCRATCH_SIZE]; /**< A place to store a few values to keep them from being prematurely GC'd. */
|
||||
@ -201,7 +202,6 @@ typedef struct KrkVM {
|
||||
|
||||
KrkThreadState * threads; /**< Invasive linked list of all VM threads. */
|
||||
FILE * callgrindFile; /**< File to write unprocessed callgrind data to. */
|
||||
size_t maximumCallDepth; /**< Maximum recursive call depth. */
|
||||
struct DebuggerState * dbgState; /**< Opaque debugger state pointer. */
|
||||
} KrkVM;
|
||||
|
||||
|
12
src/sys.c
12
src/sys.c
@ -201,6 +201,16 @@ KRK_Function(members) {
|
||||
return krk_pop();
|
||||
}
|
||||
|
||||
KRK_Function(set_recursion_depth) {
|
||||
unsigned int maxdepth;
|
||||
if (!krk_parseArgs("I",(const char*[]){"maxdepth"},&maxdepth)) return NONE_VAL();
|
||||
if (krk_currentThread.exitOnFrame != 0) {
|
||||
return krk_runtimeError(vm.exceptions->valueError, "Can not change recursion depth in this context.");
|
||||
}
|
||||
krk_setMaximumRecursionDepth(maxdepth);
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
void krk_module_init_kuroko(void) {
|
||||
/**
|
||||
* kuroko = module()
|
||||
@ -250,6 +260,8 @@ void krk_module_init_kuroko(void) {
|
||||
"Obtain the memory representation of a stack value.");
|
||||
KRK_DOC(BIND_FUNC(vm.system,members),
|
||||
"Obtain a copy of a dict of the direct members of an object.");
|
||||
KRK_DOC(BIND_FUNC(vm.system,set_recursion_depth),
|
||||
"Change the maximum recursion depth of the current thread if possible.");
|
||||
krk_attachNamedObject(&vm.system->fields, "module", (KrkObj*)vm.baseClasses->moduleClass);
|
||||
krk_attachNamedObject(&vm.system->fields, "path_sep", (KrkObj*)S(PATH_SEP));
|
||||
KrkValue module_paths = krk_list_of(0,NULL,0);
|
||||
|
@ -36,6 +36,7 @@ struct Thread {
|
||||
pid_t tid;
|
||||
unsigned int started:1;
|
||||
unsigned int alive:1;
|
||||
unsigned int maxrec;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -61,11 +62,13 @@ KRK_Function(current_thread) {
|
||||
|
||||
static volatile int _threadLock = 0;
|
||||
static void * _startthread(void * _threadObj) {
|
||||
struct Thread * self = _threadObj;
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
krk_forceThreadData();
|
||||
#endif
|
||||
memset(&krk_currentThread, 0, sizeof(KrkThreadState));
|
||||
krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame));
|
||||
krk_currentThread.maximumCallDepth = self->maxrec;
|
||||
krk_currentThread.frames = calloc(krk_currentThread.maximumCallDepth,sizeof(KrkCallFrame));
|
||||
vm.globalFlags |= KRK_GLOBAL_THREADS;
|
||||
_obtain_lock(_threadLock);
|
||||
if (vm.threads->next) {
|
||||
@ -75,7 +78,6 @@ static void * _startthread(void * _threadObj) {
|
||||
_release_lock(_threadLock);
|
||||
|
||||
/* Get our run function */
|
||||
struct Thread * self = _threadObj;
|
||||
self->threadState = &krk_currentThread;
|
||||
self->tid = gettid();
|
||||
|
||||
@ -126,13 +128,15 @@ KRK_Method(Thread,join) {
|
||||
}
|
||||
|
||||
KRK_Method(Thread,start) {
|
||||
METHOD_TAKES_NONE();
|
||||
unsigned int maxrec = krk_currentThread.maximumCallDepth;
|
||||
if (!krk_parseArgs(".|I", (const char*[]){"maxrec"}, &maxrec)) return NONE_VAL();
|
||||
|
||||
if (self->started)
|
||||
return krk_runtimeError(KRK_EXC(ThreadError), "Thread has already been started.");
|
||||
|
||||
self->started = 1;
|
||||
self->alive = 1;
|
||||
self->maxrec = maxrec;
|
||||
pthread_create(&self->nativeRef, NULL, _startthread, (void*)self);
|
||||
|
||||
return argv[0];
|
||||
|
15
src/vm.c
15
src/vm.c
@ -606,7 +606,7 @@ _finishKwarg:
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (unlikely(krk_currentThread.frameCount == vm.maximumCallDepth)) {
|
||||
if (unlikely(krk_currentThread.frameCount == (size_t)krk_currentThread.maximumCallDepth)) {
|
||||
krk_runtimeError(vm.exceptions->baseException, "maximum recursion depth exceeded");
|
||||
goto _errorAfterKeywords;
|
||||
}
|
||||
@ -892,13 +892,8 @@ int krk_isFalsey(KrkValue value) {
|
||||
}
|
||||
|
||||
void krk_setMaximumRecursionDepth(size_t maxDepth) {
|
||||
vm.maximumCallDepth = maxDepth;
|
||||
|
||||
KrkThreadState * thread = vm.threads;
|
||||
while (thread) {
|
||||
thread->frames = realloc(thread->frames, maxDepth * sizeof(KrkCallFrame));
|
||||
thread = thread->next;
|
||||
}
|
||||
krk_currentThread.maximumCallDepth = maxDepth;
|
||||
krk_currentThread.frames = realloc(krk_currentThread.frames, maxDepth * sizeof(KrkCallFrame));
|
||||
}
|
||||
|
||||
void krk_initVM(int flags) {
|
||||
@ -907,11 +902,11 @@ void krk_initVM(int flags) {
|
||||
#endif
|
||||
|
||||
vm.globalFlags = flags & 0xFF00;
|
||||
vm.maximumCallDepth = KRK_CALL_FRAMES_MAX;
|
||||
|
||||
/* Reset current thread */
|
||||
krk_resetStack();
|
||||
krk_currentThread.frames = calloc(vm.maximumCallDepth,sizeof(KrkCallFrame));
|
||||
krk_currentThread.maximumCallDepth = KRK_CALL_FRAMES_MAX;
|
||||
krk_currentThread.frames = calloc(krk_currentThread.maximumCallDepth,sizeof(KrkCallFrame));
|
||||
krk_currentThread.flags = flags & 0x00FF;
|
||||
krk_currentThread.module = NULL;
|
||||
vm.threads = &krk_currentThread;
|
||||
|
Loading…
Reference in New Issue
Block a user