Garbage collection in D

bearophile bearophileHUGS at lycos.com
Wed Jun 10 11:18:18 PDT 2009


LDC is a moving target because it's actively developed, and generally things improve with time.
This is a recent change by the quite active Frits van Bommel:
http://www.dsource.org/projects/ldc/changeset/1486%3A9ed0695cb93c

This is a cleaned up version discussed in this thread:

import tango.stdc.stdio: printf;
import Integer = tango.text.convert.Integer;

class AllocationItem {
    int value;
    this(int v) { this.value = v; }
}

int foo(int iters) {
    int sum = 0;
    for (int i = 0; i < iters; ++i) {
        auto item = new AllocationItem(i);
        sum += item.value;
    }
    return sum;
}

void main(char[][] args) {
    int iters = Integer.parse(args[1]);
    printf("%d\n", foo(iters));        
}


The asm generated by the last LDC (based on DMD v1.045 and llvm 2.6svn (Tue Jun  9 22:34:25 2009)) (this is just the important part of the asm):

foo:
	testl	%eax, %eax
	jle	.LBB2_4
	movl	%eax, %ecx
	xorl	%eax, %eax
	.align	16
.LBB2_2:
	incl	%eax
	cmpl	%ecx, %eax
	jne	.LBB2_2
	leal	-2(%ecx), %eax
	leal	-1(%ecx), %edx
	mull	%edx
	shldl	$31, %eax, %edx
	leal	-1(%edx,%ecx), %eax
	ret
.LBB2_4:
	xorl	%eax, %eax
	ret
*/


This is the same code with "scope" added:

import tango.stdc.stdio: printf;
import Integer = tango.text.convert.Integer;

class AllocationItem {
    int value;
    this(int v) { this.value = v; }
}

int foo(int iters) {
    int sum = 0;
    for (int i = 0; i < iters; ++i) {
        scope auto item = new AllocationItem(i);
        sum += item.value;
    }
    return sum;
}

void main(char[][] args) {
    int iters = Integer.parse(args[1]);
    printf("%d\n", foo(iters));        
}

Its asm:

/*
foo:
	pushl	%ebx
	pushl	%edi
	pushl	%esi
	subl	$24, %esp
	testl	%eax, %eax
	jle	.LBB2_4
	movl	%eax, %esi
	xorl	%edi, %edi
	leal	8(%esp), %ebx
	.align	16
.LBB2_2:
	movl	$_D11gc_test2b_d14AllocationItem6__vtblZ, 8(%esp)
	movl	$0, 12(%esp)
	movl	%edi, 16(%esp)
	movl	%ebx, (%esp)
	call	_d_callfinalizer
	incl	%edi
	cmpl	%esi, %edi
	jne	.LBB2_2
	leal	-2(%esi), %eax
	leal	-1(%esi), %ecx
	mull	%ecx
	shldl	$31, %eax, %edx
	leal	-1(%edx,%esi), %eax
	jmp	.LBB2_5
.LBB2_4:
	xorl	%eax, %eax
.LBB2_5:
	addl	$24, %esp
	popl	%esi
	popl	%edi
	popl	%ebx
	ret
*/


The running time:
...$ elaps ./gc_test1 250000000
-1782069568
real	0m0.170s
user	0m0.160s
sys	0m0.010s

The version with "scope":
...$ elaps ./gc_test2 250000000
-1782069568
real	0m6.430s
user	0m6.430s
sys	0m0.000s

(Later I may try again with a less simple and more realistic benchmark, because this is too much a toy to be interesting.)

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list