mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +00:00 
			
		
		
		
	Add auto-resizing of gc interval.
This should prevent over use of GC and O(n^2) behavior.
This commit is contained in:
		| @@ -390,6 +390,16 @@ | ||||
|          ,;body | ||||
|          (set ,i (,delta ,i ,step)))))) | ||||
|  | ||||
| (defn- for-var-template | ||||
|   [i start stop step comparison delta body] | ||||
|   (with-syms [s] | ||||
|     ~(do | ||||
|        (var ,i ,start) | ||||
|        (def ,s ,stop) | ||||
|        (while (,comparison ,i ,s) | ||||
|          ,;body | ||||
|          (set ,i (,delta ,i ,step)))))) | ||||
|  | ||||
| (defn- check-indexed [x] | ||||
|   (if (indexed? x) | ||||
|     x | ||||
| @@ -484,6 +494,12 @@ | ||||
|       :generate (loop-fiber-template binding object [rest]) | ||||
|       (error (string "unexpected loop verb " verb))))) | ||||
|  | ||||
| (defmacro forv | ||||
|   "Do a c style for loop for side effects. The iteration variable i | ||||
|   can be mutated in the loop, unlike normal for. Returns nil." | ||||
|   [i start stop & body] | ||||
|   (for-var-template i start stop 1 < + body)) | ||||
|  | ||||
| (defmacro for | ||||
|   "Do a c style for loop for side effects. Returns nil." | ||||
|   [i start stop & body] | ||||
| @@ -556,6 +572,7 @@ | ||||
| (put _env 'loop1 nil) | ||||
| (put _env 'check-indexed nil) | ||||
| (put _env 'for-template nil) | ||||
| (put _env 'for-var-template nil) | ||||
| (put _env 'iterate-template nil) | ||||
| (put _env 'each-template nil) | ||||
| (put _env 'keys-template nil) | ||||
|   | ||||
| @@ -39,6 +39,7 @@ struct JanetScratch { | ||||
| JANET_THREAD_LOCAL void *janet_vm_blocks; | ||||
| JANET_THREAD_LOCAL size_t janet_vm_gc_interval; | ||||
| JANET_THREAD_LOCAL size_t janet_vm_next_collection; | ||||
| JANET_THREAD_LOCAL size_t janet_vm_block_count; | ||||
| JANET_THREAD_LOCAL int janet_vm_gc_suspend = 0; | ||||
|  | ||||
| /* Roots */ | ||||
| @@ -327,6 +328,7 @@ void janet_sweep() { | ||||
|             previous = current; | ||||
|             current->flags &= ~JANET_MEM_REACHABLE; | ||||
|         } else { | ||||
|             janet_vm_block_count--; | ||||
|             janet_deinit_block(current); | ||||
|             if (NULL != previous) { | ||||
|                 previous->next = next; | ||||
| @@ -359,6 +361,7 @@ void *janet_gcalloc(enum JanetMemoryType type, size_t size) { | ||||
|     janet_vm_next_collection += size; | ||||
|     mem->next = janet_vm_blocks; | ||||
|     janet_vm_blocks = mem; | ||||
|     janet_vm_block_count++; | ||||
|  | ||||
|     return (void *)mem; | ||||
| } | ||||
| @@ -388,6 +391,14 @@ void janet_collect(void) { | ||||
|     uint32_t i; | ||||
|     if (janet_vm_gc_suspend) return; | ||||
|     depth = JANET_RECURSION_GUARD; | ||||
|     /* Try and prevent many major collections back to back. | ||||
|      * A full collection will take O(janet_vm_block_count) time. | ||||
|      * If we have a large heap, make sure our interval is not too | ||||
|      * small so we won't make many collections over it. This is just a | ||||
|      * heuristic for automatically changing the gc interval */ | ||||
|     if (janet_vm_block_count * 8 > janet_vm_gc_interval) { | ||||
|         janet_vm_gc_interval = janet_vm_block_count * sizeof(JanetGCObject); | ||||
|     } | ||||
|     orig_rootcount = janet_vm_root_count; | ||||
| #ifdef JANET_NET | ||||
|     janet_net_markloop(); | ||||
|   | ||||
| @@ -71,6 +71,7 @@ extern JANET_THREAD_LOCAL uint32_t janet_vm_cache_deleted; | ||||
| extern JANET_THREAD_LOCAL void *janet_vm_blocks; | ||||
| extern JANET_THREAD_LOCAL size_t janet_vm_gc_interval; | ||||
| extern JANET_THREAD_LOCAL size_t janet_vm_next_collection; | ||||
| extern JANET_THREAD_LOCAL size_t janet_vm_block_count; | ||||
| extern JANET_THREAD_LOCAL int janet_vm_gc_suspend; | ||||
|  | ||||
| /* GC roots */ | ||||
|   | ||||
| @@ -1395,11 +1395,8 @@ int janet_init(void) { | ||||
|     /* Garbage collection */ | ||||
|     janet_vm_blocks = NULL; | ||||
|     janet_vm_next_collection = 0; | ||||
|     /* Setting memoryInterval to zero forces | ||||
|      * a collection pretty much every cycle, which is | ||||
|      * incredibly horrible for performance, but can help ensure | ||||
|      * there are no memory bugs during development */ | ||||
|     janet_vm_gc_interval = 0x400000; | ||||
|     janet_vm_block_count = 0; | ||||
|     janet_symcache_init(); | ||||
|     /* Initialize gc roots */ | ||||
|     janet_vm_roots = NULL; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose