まつもと ゆきひろです In message "[ruby-dev:13662] Re: very long array and GC." on 01/06/26, 石塚圭樹 <keiju / ishitsuka.com> writes: |というか, こういうのって, どういう風に使っているかですよね. ですので, ヒー |プの割り当てアルゴリズムを指定できると嬉しいとおもいますが. それは私の考えとは違います。 というのも、現状のRubyではヒープの解放ができないので、調整で きる選択肢は非常に限定されます。オブジェクトの割り当てパター ンなんてそんなに多彩ではないので、その限られた選択肢の中で判 断するのに必要な情報をGCは十分に入手できると思います。 また、GCのような裏方には賢くあってほしいというのが私の好みで もあります。 というわけで添付のようなパッチを作ってみました。田中さんの基 本的なアイディアの通り倍々で増やしていきますが、mallocに失敗 した時点でヒープの増加サイズを初期値に戻してやり直しています。 まつもと ゆきひろ /:|) --- gc.c 2001/06/19 15:41:18 1.70 +++ gc.c 2001/06/26 09:39:53 @@ -260,3 +260,6 @@ -#define HEAP_SLOTS 10000 +#define HEAP_MIN_SLOTS 10000 +static int *heaps_limits; +static int heap_slots = HEAP_MIN_SLOTS; + #define FREE_MIN 4096 @@ -277,9 +280,25 @@ if (heaps == 0) mem_error("heaps: can't alloc memory"); + RUBY_CRITICAL(heaps_limits = (heaps_used>0)? + (int*)realloc(heaps_limits, heaps_length*sizeof(int)): + (int*)malloc(heaps_length*sizeof(int))); + if (heaps_limits == 0) mem_error("heaps_limits: can't alloc memory"); } - RUBY_CRITICAL(p = heaps[heaps_used++] = (RVALUE*)malloc(sizeof(RVALUE)*HEAP_SLOTS)); - if (p == 0) mem_error("add_heap: can't alloc memory"); - pend = p + HEAP_SLOTS; + for (;;) { + RUBY_CRITICAL(p = heaps[heaps_used] = (RVALUE*)malloc(sizeof(RVALUE)*heap_slots)); + heaps_limits[heaps_used] = heap_slots; + if (p == 0) { + if (heap_slots == HEAP_MIN_SLOTS) { + mem_error("add_heap: can't alloc memory"); + } + heap_slots = HEAP_MIN_SLOTS; + continue; + } + break; + } + pend = p + heap_slots; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; + heaps_used++; + heap_slots *= 2; @@ -339,4 +358,4 @@ heap_org = heaps[i]; - if (heap_org <= p && p < heap_org + HEAP_SLOTS - && ((((char*)p)-((char*)heap_org))%sizeof(RVALUE)) == 0) + if (heap_org <= p && p < heap_org + heaps_limits[i] && + ((((char*)p)-((char*)heap_org))%sizeof(RVALUE)) == 0) return Qtrue; @@ -514,2 +533,4 @@ case NODE_RETURN: + case NODE_BREAK: + case NODE_NEXT: case NODE_YIELD: @@ -541,4 +562,2 @@ case NODE_VALIAS: - case NODE_BREAK: - case NODE_NEXT: case NODE_REDO: @@ -678,3 +697,3 @@ for (i = 0; i < used; i++) { - p = heaps[i]; pend = p + HEAP_SLOTS; + p = heaps[i]; pend = p + heaps_limits[i]; while (p < pend) { @@ -693,3 +712,3 @@ - p = heaps[i]; pend = p + HEAP_SLOTS; + p = heaps[i]; pend = p + heaps_limits[i]; while (p < pend) { @@ -1047,3 +1066,3 @@ - p = heaps[i]; pend = p + HEAP_SLOTS; + p = heaps[i]; pend = p + heaps_limits[i]; for (;p < pend; p++) { @@ -1080,3 +1099,3 @@ - p = heaps[i]; pend = p + HEAP_SLOTS; + p = heaps[i]; pend = p + heaps_limits[i]; for (;p < pend; p++) { @@ -1247,3 +1266,3 @@ for (i = 0; i < heaps_used; i++) { - p = heaps[i]; pend = p + HEAP_SLOTS; + p = heaps[i]; pend = p + heaps_limits[i]; while (p < pend) { @@ -1260,3 +1279,3 @@ for (i = 0; i < heaps_used; i++) { - p = heaps[i]; pend = p + HEAP_SLOTS; + p = heaps[i]; pend = p + heaps_limits[i]; while (p < pend) {