mirror of
https://github.com/janet-lang/janet
synced 2025-01-24 14:16:52 +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:
parent
d033412b1f
commit
95c633914f
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user