]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: use C++ exceptions instead of longjmp(), to make Windows crash more
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 2 Apr 2010 18:10:55 +0000 (14:10 -0400)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 2 Apr 2010 18:10:55 +0000 (14:10 -0400)
vm/collector.hpp
vm/gc.cpp
vm/gc.hpp
vm/master.hpp

index ece4926c281464e7ae1ad66b368ef9ba2d12b14a..0b8b473e8b3704fd10c5487e1e09c6c551bdfba9 100644 (file)
@@ -1,6 +1,8 @@
 namespace factor
 {
 
+struct must_start_gc_again {};
+
 template<typename TargetGeneration, typename Policy> struct data_workhorse {
        factor_vm *parent;
        TargetGeneration *target;
@@ -27,8 +29,7 @@ template<typename TargetGeneration, typename Policy> struct data_workhorse {
        {
                cell size = untagged->size();
                object *newpointer = target->allot(size);
-               /* XXX not exception-safe */
-               if(!newpointer) longjmp(parent->current_gc->gc_unwind,1);
+               if(!newpointer) throw must_start_gc_again();
 
                memcpy(newpointer,untagged,size);
                untagged->forward_to(newpointer);
index a57f338c4473db4c59316cff42cbe588b6cebc8a..e01a05aa5ba8e4f5eee3dba8ca8b912c9813c3ab 100755 (executable)
--- a/vm/gc.cpp
+++ b/vm/gc.cpp
@@ -135,49 +135,57 @@ void factor_vm::gc(gc_op op, cell requested_bytes, bool trace_contexts_p)
 
        /* Keep trying to GC higher and higher generations until we don't run out
        of space */
-       if(setjmp(current_gc->gc_unwind))
+       for(;;)
        {
-               /* We come back here if a generation is full */
-               start_gc_again();
-       }
-
-       current_gc->event->op = current_gc->op;
-
-       switch(current_gc->op)
-       {
-       case collect_nursery_op:
-               collect_nursery();
-               break;
-       case collect_aging_op:
-               collect_aging();
-               if(data->high_fragmentation_p())
+               try
                {
-                       current_gc->op = collect_full_op;
-                       current_gc->event->op = collect_full_op;
-                       collect_full(trace_contexts_p);
+                       current_gc->event->op = current_gc->op;
+
+                       switch(current_gc->op)
+                       {
+                       case collect_nursery_op:
+                               collect_nursery();
+                               break;
+                       case collect_aging_op:
+                               collect_aging();
+                               if(data->high_fragmentation_p())
+                               {
+                                       current_gc->op = collect_full_op;
+                                       current_gc->event->op = collect_full_op;
+                                       collect_full(trace_contexts_p);
+                               }
+                               break;
+                       case collect_to_tenured_op:
+                               collect_to_tenured();
+                               if(data->high_fragmentation_p())
+                               {
+                                       current_gc->op = collect_full_op;
+                                       current_gc->event->op = collect_full_op;
+                                       collect_full(trace_contexts_p);
+                               }
+                               break;
+                       case collect_full_op:
+                               collect_full(trace_contexts_p);
+                               break;
+                       case collect_compact_op:
+                               collect_compact(trace_contexts_p);
+                               break;
+                       case collect_growing_heap_op:
+                               collect_growing_heap(requested_bytes,trace_contexts_p);
+                               break;
+                       default:
+                               critical_error("Bad GC op",current_gc->op);
+                               break;
+                       }
+
+                       break;
                }
-               break;
-       case collect_to_tenured_op:
-               collect_to_tenured();
-               if(data->high_fragmentation_p())
+               catch(const must_start_gc_again e)
                {
-                       current_gc->op = collect_full_op;
-                       current_gc->event->op = collect_full_op;
-                       collect_full(trace_contexts_p);
+                       /* We come back here if a generation is full */
+                       start_gc_again();
+                       continue;
                }
-               break;
-       case collect_full_op:
-               collect_full(trace_contexts_p);
-               break;
-       case collect_compact_op:
-               collect_compact(trace_contexts_p);
-               break;
-       case collect_growing_heap_op:
-               collect_growing_heap(requested_bytes,trace_contexts_p);
-               break;
-       default:
-               critical_error("Bad GC op",current_gc->op);
-               break;
        }
 
        end_gc();
index 5224dec3e296c21b515b4d4766095733a028eb0d..5129ced909179996cb829f3850520ed0a7bf5c96 100755 (executable)
--- a/vm/gc.hpp
+++ b/vm/gc.hpp
@@ -45,7 +45,6 @@ struct gc_event {
 struct gc_state {
        gc_op op;
        u64 start_time;
-       jmp_buf gc_unwind;
        gc_event *event;
 
        explicit gc_state(gc_op op_, factor_vm *parent);
index 9879fa607a3cccf8f8ab27d5770fa1f3916b34a6..a111a86b699be1d910347f1de2ef28f28adffa84 100755 (executable)
@@ -16,7 +16,6 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <math.h>
-#include <setjmp.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>