]> gitweb.factorcode.org Git - factor.git/commitdiff
VM: clear the local roots before garbage collection in general_error()
authorBjörn Lindqvist <bjourne@gmail.com>
Sat, 21 Jun 2014 23:24:43 +0000 (01:24 +0200)
committerDoug Coleman <doug.coleman@gmail.com>
Wed, 16 Jul 2014 21:54:29 +0000 (14:54 -0700)
If we got here from memory_protection_error(), then the stack pointer
has been fiddled with and the elements of these vectors, which address
stack-allocated objects, are bogus and needs to be resetted.

vm/cpu-x86.cpp
vm/errors.cpp

index bce75a4edc4fae13e977db03fb7347e1e1dbd2cc..85a8186d9fd013bacf0c62901be353a05f57815d 100644 (file)
@@ -5,11 +5,12 @@ namespace factor {
 void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
   if (!code->seg->in_segment_p(*pc) ||
       *sp < ctx->callstack_seg->start + stack_reserved) {
-    /* Fault came from foreign code or a callstack overflow, or we don't
-       have enough callstack room to try the resumable handler. Cut the
-       callstack down to the shallowest Factor stack frame that leaves room for
-       the signal handler to do its thing, and launch the handler without going
-       through the resumable subprimitive. */
+    /* Fault came from the VM, foreign code, a callstack overflow, or
+       we don't have enough callstack room to try the resumable
+       handler. Cut the callstack down to the shallowest Factor stack
+       frame that leaves room for the signal handler to do its thing,
+       and launch the handler without going through the resumable
+       subprimitive. */
     signal_resumable = false;
     void* frame_top = (void*)ctx->callstack_top;
 
@@ -23,8 +24,8 @@ void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
     *pc = handler;
   } else {
     signal_resumable = true;
-    // Fault came from Factor, and we've got a good callstack. Route the signal
-    // handler through the resumable signal handler subprimitive.
+    /* Fault came from Factor, and we've got a good callstack. Route
+       the signal handler through the resumable signal handler subprimitive. */
     cell offset = *sp % 16;
 
     signal_handler_addr = handler;
@@ -43,7 +44,7 @@ void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
       *sp = newsp;
       *(cell*)newsp = *pc;
     } else if (offset == 16 - sizeof(cell)) {
-      // Make a fake frame for the leaf procedure
+      /* Make a fake frame for the leaf procedure */
       FACTOR_ASSERT(code->code_block_for_address(*pc) != NULL);
 
       cell newsp = *sp - LEAF_FRAME_SIZE;
index 9814a8f988a3651d48ffacaba8bdb67d262fba56..aee0fdbcf43818972e48980b6db1db239d1ca394 100644 (file)
@@ -38,6 +38,15 @@ void out_of_memory() {
 
 /* Allocates memory */
 void factor_vm::general_error(vm_error_type error, cell arg1_, cell arg2_) {
+
+  /* If we got here from memory_protection_error(), then the stack
+     pointer has been fiddled with and the elements of these vectors,
+     which address stack-allocated objects, are bogus and needs to be
+     resetted. */
+  data_roots.clear();
+  bignum_roots.clear();
+  code_roots.clear();
+
   data_root<object> arg1(arg1_, this);
   data_root<object> arg2(arg2_, this);
 
@@ -66,11 +75,6 @@ void factor_vm::general_error(vm_error_type error, cell arg1_, cell arg2_) {
 
     ctx->push(error_object);
 
-    /* Reset local roots */
-    data_roots.clear();
-    bignum_roots.clear();
-    code_roots.clear();
-
     /* The unwind-native-frames subprimitive will clear faulting_p
        if it was successfully reached. */
     unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],