# GC heap size less patch

**URL:** <https://www.ruby-forum.com/t/gc-heap-size-less-patch/133129>\
**Category:** Development\
**Created:** [March 28, 2008, 4:48am UTC](https://www.ruby-forum.com/t/gc-heap-size-less-patch/133129 "2008-03-28T04:48:03Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![authorNari](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/9e8a1a/32.png) [@authorNari](https://www.ruby-forum.com/u/authorNari)\
**Post date:** [March 28, 2008, 4:48am UTC](https://www.ruby-forum.com/t/gc-heap-size-less-patch/133129/1 "2008-03-28T04:48:03Z")

</div>

authorNarie$B$G$9!#e(B

e$B$3$NA0$KOC$7$K$“$C$?!”%R!\<%W$N:YJ,2=$N%Q%C%A$r:n$j$^$7$?!#e(B

e$B\>:Y$O$3$A$i$K=q$$$F$\*$j$^$9!#e(B  
[http://d.hatena.ne.jp/authorNari/20080328/1206675485](http://d.hatena.ne.jp/authorNari/20080328/1206675485)

e$B$b$C$H%Y%s%A%^!\<%/MQ$N%3!\<%I$r:n$C$F@:::$9$kI,MW$,$“$j$^$9$,e(B  
pree$BHG$H$$$&;v$G!”$h$m$7$/$\*4j$$$7$^$9!#e(B

* * *

id: authorNari

* * *

# Index: gc.c

— gc.c (e$B%j%S%8%g%se(B 15844)  
+++ gc.c (e$B:n6H%3%T!\<e(B)  
@@ -143,7 +143,6 @@  
static RVALUE \*freelist = 0;  
static RVALUE \*deferred\_final\_list = 0;

-#define HEAPS\_INCREMENT 10  
static struct heaps\_slot {  
void \*membase;  
RVALUE \*slot;  
@@ -153,9 +152,27 @@  
static int heaps\_used = 0;

#define HEAP\_MIN\_SLOTS 10000  
-static int heap\_slots = HEAP\_MIN\_SLOTS;  
+static int add\_objects = HEAP\_MIN\_SLOTS;

+/\* tiny heap size \*/  
+// 32KB  
+#define HEAP\_SIZE 0x8000  
+// 128KB  
+//#define HEAP\_SIZE 0x20000  
+// 64KB  
+//#define HEAP\_SIZE 0x10000  
+// 16KB  
+//#define HEAP\_SIZE 0x4000  
+// 8KB  
+//#define HEAP\_SIZE 0x2000  
+// 4KB  
+//#define HEAP\_SIZE 0x1000  
+// 2KB  
+//#define HEAP\_SIZE 0x800  
+  
+#define HEAP\_OBJ\_LIMIT (HEAP\_SIZE / sizeof(struct RVALUE))  
#define FREE\_MIN 4096  
+static int add\_inc\_time = 0;

static RVALUE \*himem, \*lomem;

@@ -179,8 +196,6 @@  
size\_t rb\_gc\_stack\_maxsize = 655300\*sizeof(VALUE);  
#endif

- 
- 

static void run\_final(VALUE obj);  
static int garbage\_collect(void);

@@ -417,43 +432,39 @@  
}  
}

- 

static void  
-add\_heap(void)  
+allocate\_heaps(void)  
{

- struct heaps\_slot \*p;
- int length;
- 
- heaps\_length += add\_objects / HEAP\_OBJ\_LIMIT;
- length = heaps\_length\*sizeof(struct heaps\_slot);
- RUBY\_CRITICAL(
- 

```
 if (heaps_used > 0) {

```

- 

```
     p = (struct heaps_slot *)realloc(heaps, length);

```

- 

```
     if (p) heaps = p;

```

- 

```
 }

```

- 

```
 else {

```

- 

```
     p = heaps = (struct heaps_slot *)malloc(length);

```

- 

```
 }

```

- 

```
 );

```

- if (p == 0) rb\_memerror();  
+}
- 

+static void  
+assign\_heap\_slot(void)  
+{  
RVALUE \*p, \*pend, \*membase;  
long hi, lo, mid;

- int objs;
- 
- objs = HEAP\_OBJ\_LIMIT;
- RUBY\_CRITICAL(p = (RVALUE\*)malloc(HEAP\_SIZE));
- if (p == 0)
- rb\_memerror();

- if (heaps\_used == heaps\_length) {

- /\* Realloc heaps \*/

- struct heaps\_slot \*p;

- int length;

- 
- heaps\_length += HEAPS\_INCREMENT;

- length = heaps\_length\*sizeof(struct heaps\_slot);

- RUBY\_CRITICAL(

- 

```
 if (heaps_used > 0) {

```

- p = (struct heaps\_slot \*)realloc(heaps, length);

- if (p) heaps = p;

- 

```
 }

```

- 

```
 else {

```

- p = heaps = (struct heaps\_slot \*)malloc(length);

- 

```
 });

```

- if (p == 0) rb\_memerror();

- }

- 
- for (;😉 {

- RUBY\_CRITICAL(p = (RVALUE\*)malloc(sizeof(RVALUE)\*(heap\_slots+1)));

- if (p == 0) {

- 

```
 if (heap_slots == HEAP_MIN_SLOTS) {

```

- rb\_memerror();

- 

```
 }

```

- 

```
 heap_slots = HEAP_MIN_SLOTS;

```

- }

- else {

- 

```
 break;

```

- }

- }

- lo = 0;  
hi = heaps\_used;  
while (lo \< hi) {  
@@ -471,21 +482,25 @@  
}

- if ((VALUE)p % sizeof(RVALUE) == 0)

- heap\_slots += 1;

- else

- 
- if ((VALUE)p % sizeof(RVALUE) != 0) {  
p = (RVALUE\*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p %  
sizeof(RVALUE)));
- if ((membase + HEAP\_SIZE) \< (p + HEAP\_SIZE)) {
- 

```
 objs--;

```

- }
- }
- 
- if (hi \< heaps\_used) {  
MEMMOVE(&heaps[hi+1], &heaps[hi], struct heaps\_slot, heaps\_used -  
hi);  
}  
heaps[hi].membase = membase;  
heaps[hi].slot = p;

- heaps[hi].limit = heap\_slots;
- pend = p + heap\_slots;

- heaps[hi].limit = objs;
- pend = p + objs;  
if (lomem == 0 || lomem \> p) lomem = p;  
if (himem \< pend) himem = pend;  
heaps\_used++;

- heap\_slots \*= 1.8;

+static void  
+add\_heap(void)  
+{

- int add, i;
- 
- add = add\_objects / HEAP\_OBJ\_LIMIT;
- add\_objects \*= 1.8;
- 
- if ((heaps\_used + add) \> heaps\_length) {
- 

```
 allocate_heaps();

```

- }
- 
- for (i = 0; i \< add; i++) {
- 

```
 assign_heap_slot();

```

- }
- add\_inc\_time = 0;  
+}
- 
- 

+static void  
+set\_add\_inc\_time(void)  
+{

- add\_inc\_time += add\_objects / HEAP\_OBJ\_LIMIT;
- add\_objects \*= 1.8;
- 
- if ((heaps\_used + add\_inc\_time) \> heaps\_length) {
- allocate\_heaps();
- }  
+}
- 

+static int  
+add\_heap\_increment(void)  
+{

- if (add\_inc\_time \> 0) {
- assign\_heap\_slot();
- add\_inc\_time–;
- return Qtrue;
- }
- return Qfalse;  
+}
- 

#define RANY(o) ((RVALUE\*)(o))

## static VALUE rb\_newobj\_from\_heap(void) { VALUE obj;

- if (ruby\_gc\_stress || !freelist) {

- if(!garbage\_collect()) {

- 

```
 if (!add_heap_increment() && !garbage_collect()) {
 rb_memerror();

```

}  
}  
@@ -516,6 +572,7 @@  
RANY(obj)-\>file = rb\_sourcefile();  
RANY(obj)-\>line = rb\_sourceline();  
#endif
- return obj;  
}

@@ -1202,6 +1259,9 @@  
j++;  
}  
}

- if (i != j) {
- add\_objects = heaps\_used \* HEAP\_OBJ\_LIMIT;
- }  
}

void rb\_gc\_abort\_threads(void);  
@@ -1212,15 +1272,14 @@  
RVALUE \*p, \*pend, \*final\_list;  
int freed = 0;  
int i;

- unsigned long live = 0;
- unsigned long free\_min = 0;

- unsigned long live = 0, free\_min = 0, do\_heap\_free = 0;

- for (i = 0; i \< heaps\_used; i++) {
- 

```
   free_min += heaps[i].limit;

```

- do\_heap\_free = (heaps\_used \* HEAP\_OBJ\_LIMIT) \* 0.65;
- free\_min = (heaps\_used \* HEAP\_OBJ\_LIMIT) \* 0.2;
- if (free\_min \< FREE\_MIN) {
- do\_heap\_free = heaps\_used \* HEAP\_OBJ\_LIMIT;
- 

```
   free_min = FREE_MIN;

```

}

- free\_min = free\_min \* 0.2;

- if (free\_min \< FREE\_MIN)

- 

```
   free_min = FREE_MIN;

```

if (source\_filenames) {  
st\_foreach(source\_filenames, sweep\_source\_filename, 0);  
@@ -1263,7 +1322,7 @@  
}  
p++;  
}

- if (n == heaps[i].limit && freed \> free\_min) {

- if (n == heaps[i].limit && freed \> do\_heap\_free) {  
RVALUE \*pp;

@@ -1282,7 +1341,8 @@  
}  
malloc\_increase = 0;  
if (freed \< free\_min) {

- add\_heap();

- 

```
 set_add_inc_time();

```

- add\_heap\_increment();  
}  
during\_gc = 0;

@@ -1572,6 +1632,7 @@  
}

```
 gc_sweep();

```

- if (GC\_NOTIFY) printf(“end garbage\_collect()\n”);  
return Qtrue;  
}
