From 98f9cc02546e40728a8b4654ef4b1d80cd396426 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Tue, 6 Nov 2018 16:18:09 +0300 Subject: [PATCH 01/19] gc data scan init + temp test --- runtime/runtime.c | 31 +++++++++++++++++++++++++++++++ src/testgc.expr | 11 +++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/testgc.expr diff --git a/runtime/runtime.c b/runtime/runtime.c index c4a110dad..dc136ae0b 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -348,3 +348,34 @@ extern int Lwrite (int n) { return 0; } +/* GC starts here */ + +extern const size_t __gc_data_end, __gc_data_start; + +extern void __gc_root_scan_data () { + size_t * p = &__gc_data_start; + + printf ("Start, end: %d, %d\n", &__gc_data_start, &__gc_data_end); + + while (p != &__gc_data_end) { + if (!UNBOXED(*p)) printf ("Root: %d\n", p); + p++; + } +} + +/* extern const void * __gc_data_end, * __gc_data_start; */ + +/* extern void __gc_root_scan_data () { */ +/* void * p = &__gc_data_start; */ + +/* printf ("Start, end: %d, %d\n", &__gc_data_start, &__gc_data_end); */ + +/* while (p != &__gc_data_end) { */ +/* if (!UNBOXED(* (size_t *) p)) printf ("Root: %d\n", p); */ +/* p = p + sizeof(size_t); */ +/* } */ +/* } */ + +extern void Ltest () { + __gc_root_scan_data (); +} diff --git a/src/testgc.expr b/src/testgc.expr new file mode 100644 index 000000000..7964e97c7 --- /dev/null +++ b/src/testgc.expr @@ -0,0 +1,11 @@ +x := 0; +y := 0; +z := 0; +t := 0; +test (); +y := "abc"; +test (); +t := []; +test (); +t := 0; +test () \ No newline at end of file From 16d3f839ce633f6b8593e0af69188ed2a7fd2642 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 21 Nov 2018 14:23:35 +0300 Subject: [PATCH 02/19] add stack roots scanning --- runtime/Makefile | 12 +- runtime/gc_runtime.s | 68 ++ runtime/runtime.c | 21 +- runtime/runtime.s | 1640 ++++++++++++++++++++++++++++++++++++++++++ src/X86.ml | 47 +- src/testgc.expr | 23 +- 6 files changed, 1784 insertions(+), 27 deletions(-) create mode 100644 runtime/gc_runtime.s create mode 100644 runtime/runtime.s diff --git a/runtime/Makefile b/runtime/Makefile index c4414a5c8..906aa571d 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -1,6 +1,12 @@ -all: - gcc -m32 -c runtime.c +all: gc_runtime.o runtime.o + ar rc runtime.a gc_runtime.o runtime.o + +gc_runtime.o: gc_runtime.s + gcc -g -m32 -c gc_runtime.s + +runtime.o: runtime.c + gcc -g -m32 -c runtime.c clean: - rm -f runtime.o *~ + rm -f *.a *.o *~ diff --git a/runtime/gc_runtime.s b/runtime/gc_runtime.s new file mode 100644 index 000000000..3df87be0a --- /dev/null +++ b/runtime/gc_runtime.s @@ -0,0 +1,68 @@ + .data +printf_format: .string "Stack root: %lx\n" +printf_format2: .string "BOT: %lx\n" +printf_format3: .string "TOP: %lx\n" +printf_format4: .string "EAX: %lx\n" +printf_format5: .string "LOL\n" +__gc_stack_bottom: .long 0 +__gc_stack_top: .long 0 + + .globl L__gc_init + .globl __gc_root_scan_stack + + .text +L__gc_init: movl %esp, __gc_stack_bottom + addl $4, __gc_stack_bottom + ret + +__gc_root_scan_stack: + movl %esp, __gc_stack_top + movl %esp, %eax + jmp next + +loop: + movl (%eax), %ebx + + // check that it is not a pointer to code section + // i.e. the following is not true: + // __executable_start <= (%eax) <= __etext +check11: + leal __executable_start, %edx + cmpl %ebx, %edx + jna check12 + jmp check21 + +check12: + leal __etext, %edx + cmpl %ebx, %edx + jnb next + + // check that it is not a pointer into the program stack + // i.e. the following is not true: + // __gc_stack_bottom <= (%eax) <= __gc_stack_top +check21: + cmpl %ebx, __gc_stack_top + jna check22 + jmp loop2 + +check22: + cmpl %ebx, __gc_stack_bottom + jnb next + + // check if it a valid pointer + // i.e. the lastest bit is set to zero +loop2: + andl $0x00000001, %ebx + jnz next + pushl %eax + pushl (%eax) + pushl $printf_format + call printf + addl $8, %esp + popl %eax + +next: + addl $4, %eax + cmpl %eax, __gc_stack_bottom + jne loop + ret diff --git a/runtime/runtime.c b/runtime/runtime.c index dc136ae0b..530990f8b 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -351,18 +351,24 @@ extern int Lwrite (int n) { /* GC starts here */ extern const size_t __gc_data_end, __gc_data_start; +extern size_t __gc_stack_bottom, __gc_stack_top; + +extern void L__gc_init (); extern void __gc_root_scan_data () { size_t * p = &__gc_data_start; - printf ("Start, end: %d, %d\n", &__gc_data_start, &__gc_data_end); + printf ("Start, end: %lx, %lx\n", &__gc_data_start, &__gc_data_end); while (p != &__gc_data_end) { - if (!UNBOXED(*p)) printf ("Root: %d\n", p); + if (!UNBOXED(*p)) printf ("Root: %lx\n", *p); p++; } } +extern void __gc_root_scan_stack (); + + /* extern const void * __gc_data_end, * __gc_data_start; */ /* extern void __gc_root_scan_data () { */ @@ -376,6 +382,17 @@ extern void __gc_root_scan_data () { /* } */ /* } */ +extern char __executable_start; +extern char __etext; + extern void Ltest () { + printf("\n"); + printf("STA 0x%lx\n", (unsigned long)&__executable_start); + printf("END 0x%lx\n", (unsigned long)&__etext); __gc_root_scan_data (); + __gc_root_scan_stack (); + + // printf("STA 0x%lx\n", (unsigned long)&__executable_start); + // printf("END 0x%lx\n", (unsigned long)&__etext); + // printf("RET 0x%lx\n\n", __builtin_return_address(0)); } diff --git a/runtime/runtime.s b/runtime/runtime.s new file mode 100644 index 000000000..8181e2ecf --- /dev/null +++ b/runtime/runtime.s @@ -0,0 +1,1640 @@ + .file "runtime.c" + .text + .globl Blength + .type Blength, @function +Blength: +.LFB6: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + addl %eax, %eax + andl $33554430, %eax + orl $1, %eax + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE6: + .size Blength, .-Blength + .globl de_hash + .type de_hash, @function +de_hash: +.LFB7: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $16, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + leal 5+buf.3077@GOTOFF(%eax), %edx + movl %edx, -8(%ebp) + movl -8(%ebp), %edx + leal -1(%edx), %ecx + movl %ecx, -8(%ebp) + movb $0, (%edx) + jmp .L4 +.L5: + movl chars.3076@GOTOFF(%eax), %edx + movl 8(%ebp), %ecx + andl $63, %ecx + leal (%edx,%ecx), %ebx + movl -8(%ebp), %edx + leal -1(%edx), %ecx + movl %ecx, -8(%ebp) + movzbl (%ebx), %ecx + movb %cl, (%edx) + sarl $6, 8(%ebp) +.L4: + cmpl $0, 8(%ebp) + jne .L5 + addl $1, -8(%ebp) + movl -8(%ebp), %eax + addl $16, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE7: + .size de_hash, .-de_hash + .local stringBuf + .comm stringBuf,12,4 + .type createStringBuf, @function +createStringBuf: +.LFB8: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $12, %esp + pushl $128 + call malloc@PLT + addl $16, %esp + movl %eax, stringBuf@GOTOFF(%ebx) + movl $0, 4+stringBuf@GOTOFF(%ebx) + movl $128, 8+stringBuf@GOTOFF(%ebx) + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE8: + .size createStringBuf, .-createStringBuf + .type deleteStringBuf, @function +deleteStringBuf: +.LFB9: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl stringBuf@GOTOFF(%eax), %edx + subl $12, %esp + pushl %edx + movl %eax, %ebx + call free@PLT + addl $16, %esp + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE9: + .size deleteStringBuf, .-deleteStringBuf + .type extendStringBuf, @function +extendStringBuf: +.LFB10: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8+stringBuf@GOTOFF(%ebx), %eax + addl %eax, %eax + movl %eax, -12(%ebp) + movl -12(%ebp), %edx + movl stringBuf@GOTOFF(%ebx), %eax + subl $8, %esp + pushl %edx + pushl %eax + call realloc@PLT + addl $16, %esp + movl %eax, stringBuf@GOTOFF(%ebx) + movl -12(%ebp), %eax + movl %eax, 8+stringBuf@GOTOFF(%ebx) + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE10: + .size extendStringBuf, .-extendStringBuf + .type printStringBuf, @function +printStringBuf: +.LFB11: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $52, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + movl %eax, -44(%ebp) + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax +.L11: + leal 12(%ebp), %eax + movl %eax, -28(%ebp) + movl stringBuf@GOTOFF(%ebx), %eax + movl 4+stringBuf@GOTOFF(%ebx), %edx + addl %edx, %eax + movl %eax, -24(%ebp) + movl 8+stringBuf@GOTOFF(%ebx), %edx + movl 4+stringBuf@GOTOFF(%ebx), %eax + subl %eax, %edx + movl %edx, %eax + movl %eax, -20(%ebp) + movl -28(%ebp), %edx + movl -20(%ebp), %eax + pushl %edx + pushl -44(%ebp) + pushl %eax + pushl -24(%ebp) + call vsnprintf@PLT + addl $16, %esp + movl %eax, -16(%ebp) + movl -16(%ebp), %eax + cmpl -20(%ebp), %eax + jl .L12 + call extendStringBuf + jmp .L11 +.L12: + movl 4+stringBuf@GOTOFF(%ebx), %edx + movl -16(%ebp), %eax + addl %edx, %eax + movl %eax, 4+stringBuf@GOTOFF(%ebx) + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L13 + call __stack_chk_fail_local +.L13: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE11: + .size printStringBuf, .-printStringBuf + .section .rodata +.LC0: + .string "%d" +.LC1: + .string "\"%s\"" +.LC2: + .string "[" +.LC3: + .string ", " +.LC4: + .string "]" +.LC5: + .string "`%s" +.LC6: + .string " (" +.LC7: + .string ")" +.LC8: + .string "*** invalid tag: %x ***" + .text + .type printValue, @function +printValue: +.LFB12: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L15 + movl 8(%ebp), %eax + sarl %eax + subl $8, %esp + pushl %eax + leal .LC0@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L28 +.L15: + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -12(%ebp) + movl -12(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $16777216, %eax + je .L17 + cmpl $33554432, %eax + je .L18 + testl %eax, %eax + jne .L19 + movl -12(%ebp), %eax + addl $4, %eax + subl $8, %esp + pushl %eax + leal .LC1@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L16 +.L17: + subl $12, %esp + leal .LC2@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + movl $0, -20(%ebp) + jmp .L20 +.L22: + movl -12(%ebp), %eax + leal 4(%eax), %edx + movl -20(%ebp), %eax + sall $2, %eax + addl %edx, %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call printValue + addl $16, %esp + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + subl $1, %eax + cmpl %eax, -20(%ebp) + je .L21 + subl $12, %esp + leal .LC3@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp +.L21: + addl $1, -20(%ebp) +.L20: + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, -20(%ebp) + jl .L22 + subl $12, %esp + leal .LC4@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L16 +.L18: + movl 8(%ebp), %eax + subl $8, %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call de_hash + addl $16, %esp + subl $8, %esp + pushl %eax + leal .LC5@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + testl %eax, %eax + je .L27 + subl $12, %esp + leal .LC6@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + movl $0, -16(%ebp) + jmp .L24 +.L26: + movl -12(%ebp), %eax + leal 4(%eax), %edx + movl -16(%ebp), %eax + sall $2, %eax + addl %edx, %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call printValue + addl $16, %esp + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + subl $1, %eax + cmpl %eax, -16(%ebp) + je .L25 + subl $12, %esp + leal .LC3@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp +.L25: + addl $1, -16(%ebp) +.L24: + movl -12(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, -16(%ebp) + jl .L26 + subl $12, %esp + leal .LC7@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L27 +.L19: + movl -12(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + subl $8, %esp + pushl %eax + leal .LC8@GOTOFF(%ebx), %eax + pushl %eax + call printStringBuf + addl $16, %esp + jmp .L28 +.L27: + nop +.L16: +.L28: + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE12: + .size printValue, .-printValue + .globl Belem + .type Belem, @function +Belem: +.LFB13: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + sarl 12(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + testl %eax, %eax + jne .L30 + movl -4(%ebp), %edx + movl 12(%ebp), %eax + addl %edx, %eax + addl $4, %eax + movzbl (%eax), %eax + movsbl %al, %eax + addl %eax, %eax + orl $1, %eax + jmp .L31 +.L30: + movl -4(%ebp), %eax + leal 4(%eax), %edx + movl 12(%ebp), %eax + sall $2, %eax + addl %edx, %eax + movl (%eax), %eax +.L31: + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE13: + .size Belem, .-Belem + .globl Bstring + .type Bstring, @function +Bstring: +.LFB14: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $12, %esp + pushl 8(%ebp) + call strlen@PLT + addl $16, %esp + movl %eax, -16(%ebp) + movl -16(%ebp), %eax + addl $5, %eax + subl $12, %esp + pushl %eax + call malloc@PLT + addl $16, %esp + movl %eax, -12(%ebp) + movl -12(%ebp), %eax + movl -16(%ebp), %edx + movl %edx, (%eax) + movl -16(%ebp), %eax + addl $1, %eax + movl %eax, %edx + movl -12(%ebp), %eax + addl $4, %eax + subl $4, %esp + pushl %edx + pushl 8(%ebp) + pushl %eax + call strncpy@PLT + addl $16, %esp + movl -12(%ebp), %eax + addl $4, %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE14: + .size Bstring, .-Bstring + .globl Bstringval + .type Bstringval, @function +Bstringval: +.LFB15: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + call createStringBuf + subl $12, %esp + pushl 8(%ebp) + call printValue + addl $16, %esp + movl stringBuf@GOTOFF(%ebx), %eax + subl $12, %esp + pushl %eax + call Bstring + addl $16, %esp + movl %eax, -12(%ebp) + call deleteStringBuf + movl -12(%ebp), %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE15: + .size Bstringval, .-Bstringval + .globl Barray + .type Barray, @function +Barray: +.LFB16: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + movl 8(%ebp), %edx + addl $1, %edx + sall $2, %edx + subl $12, %esp + pushl %edx + movl %eax, %ebx + call malloc@PLT + addl $16, %esp + movl %eax, -20(%ebp) + movl 8(%ebp), %eax + orl $16777216, %eax + movl %eax, %edx + movl -20(%ebp), %eax + movl %edx, (%eax) + leal 12(%ebp), %eax + movl %eax, -28(%ebp) + movl $0, -24(%ebp) + jmp .L37 +.L38: + movl -28(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -28(%ebp) + movl (%eax), %eax + movl %eax, -16(%ebp) + movl -20(%ebp), %eax + leal 4(%eax), %edx + movl -24(%ebp), %eax + sall $2, %eax + addl %eax, %edx + movl -16(%ebp), %eax + movl %eax, (%edx) + addl $1, -24(%ebp) +.L37: + movl -24(%ebp), %eax + cmpl 8(%ebp), %eax + jl .L38 + movl -20(%ebp), %eax + addl $4, %eax + movl -12(%ebp), %ecx + xorl %gs:20, %ecx + je .L40 + call __stack_chk_fail_local +.L40: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE16: + .size Barray, .-Barray + .globl Bsexp + .type Bsexp, @function +Bsexp: +.LFB17: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + movl 8(%ebp), %edx + addl $2, %edx + sall $2, %edx + subl $12, %esp + pushl %edx + movl %eax, %ebx + call malloc@PLT + addl $16, %esp + movl %eax, -24(%ebp) + movl -24(%ebp), %eax + addl $4, %eax + movl %eax, -20(%ebp) + movl 8(%ebp), %eax + subl $1, %eax + orl $33554432, %eax + movl %eax, %edx + movl -20(%ebp), %eax + movl %edx, (%eax) + leal 12(%ebp), %eax + movl %eax, -32(%ebp) + movl $0, -28(%ebp) + jmp .L42 +.L43: + movl -32(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -32(%ebp) + movl (%eax), %eax + movl %eax, -16(%ebp) + movl -20(%ebp), %eax + leal 4(%eax), %edx + movl -28(%ebp), %eax + sall $2, %eax + addl %eax, %edx + movl -16(%ebp), %eax + movl %eax, (%edx) + addl $1, -28(%ebp) +.L42: + movl 8(%ebp), %eax + subl $1, %eax + cmpl %eax, -28(%ebp) + jl .L43 + movl -32(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -32(%ebp) + movl (%eax), %edx + movl -24(%ebp), %eax + movl %edx, (%eax) + movl -20(%ebp), %eax + addl $4, %eax + movl -12(%ebp), %ecx + xorl %gs:20, %ecx + je .L45 + call __stack_chk_fail_local +.L45: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE17: + .size Bsexp, .-Bsexp + .globl Btag + .type Btag, @function +Btag: +.LFB18: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $33554432, %eax + jne .L47 + movl 8(%ebp), %eax + subl $8, %eax + movl (%eax), %eax + cmpl %eax, 12(%ebp) + jne .L47 + movl -4(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, 16(%ebp) + jne .L47 + movl $1, %eax + jmp .L48 +.L47: + movl $0, %eax +.L48: + addl %eax, %eax + orl $1, %eax + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE18: + .size Btag, .-Btag + .globl Barray_patt + .type Barray_patt, @function +Barray_patt: +.LFB19: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L51 + movl $1, %eax + jmp .L52 +.L51: + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -4(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $16777216, %eax + jne .L53 + movl -4(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + cmpl %eax, 12(%ebp) + jne .L53 + movl $1, %eax + jmp .L54 +.L53: + movl $0, %eax +.L54: + addl %eax, %eax + orl $1, %eax +.L52: + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE19: + .size Barray_patt, .-Barray_patt + .globl Bstring_patt + .type Bstring_patt, @function +Bstring_patt: +.LFB20: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %edx + andl $1, %edx + testl %edx, %edx + je .L56 + movl $1, %eax + jmp .L57 +.L56: + movl 8(%ebp), %edx + subl $4, %edx + movl %edx, -16(%ebp) + movl 12(%ebp), %edx + subl $4, %edx + movl %edx, -12(%ebp) + movl -16(%ebp), %edx + movl (%edx), %edx + andl $-16777216, %edx + testl %edx, %edx + je .L58 + movl $1, %eax + jmp .L57 +.L58: + movl -12(%ebp), %edx + leal 4(%edx), %ecx + movl -16(%ebp), %edx + addl $4, %edx + subl $8, %esp + pushl %ecx + pushl %edx + movl %eax, %ebx + call strcmp@PLT + addl $16, %esp + testl %eax, %eax + jne .L59 + movl $3, %eax + jmp .L57 +.L59: + movl $1, %eax +.L57: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE20: + .size Bstring_patt, .-Bstring_patt + .globl Bboxed_patt + .type Bboxed_patt, @function +Bboxed_patt: +.LFB21: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + jne .L62 + movl $3, %eax + jmp .L64 +.L62: + movl $1, %eax +.L64: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE21: + .size Bboxed_patt, .-Bboxed_patt + .globl Bunboxed_patt + .type Bunboxed_patt, @function +Bunboxed_patt: +.LFB22: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + addl %eax, %eax + andl $2, %eax + orl $1, %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE22: + .size Bunboxed_patt, .-Bunboxed_patt + .globl Barray_tag_patt + .type Barray_tag_patt, @function +Barray_tag_patt: +.LFB23: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L68 + movl $1, %eax + jmp .L69 +.L68: + movl 8(%ebp), %eax + subl $4, %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $16777216, %eax + jne .L70 + movl $3, %eax + jmp .L69 +.L70: + movl $1, %eax +.L69: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE23: + .size Barray_tag_patt, .-Barray_tag_patt + .globl Bstring_tag_patt + .type Bstring_tag_patt, @function +Bstring_tag_patt: +.LFB24: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L73 + movl $1, %eax + jmp .L74 +.L73: + movl 8(%ebp), %eax + subl $4, %eax + movl (%eax), %eax + andl $-16777216, %eax + testl %eax, %eax + jne .L75 + movl $3, %eax + jmp .L74 +.L75: + movl $1, %eax +.L74: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE24: + .size Bstring_tag_patt, .-Bstring_tag_patt + .globl Bsexp_tag_patt + .type Bsexp_tag_patt, @function +Bsexp_tag_patt: +.LFB25: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + andl $1, %eax + testl %eax, %eax + je .L78 + movl $1, %eax + jmp .L79 +.L78: + movl 8(%ebp), %eax + subl $4, %eax + movl (%eax), %eax + andl $-16777216, %eax + cmpl $33554432, %eax + jne .L80 + movl $3, %eax + jmp .L79 +.L80: + movl $1, %eax +.L79: + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE25: + .size Bsexp_tag_patt, .-Bsexp_tag_patt + .globl Bsta + .type Bsta, @function +Bsta: +.LFB26: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $56, %esp + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 16(%ebp), %eax + movl %eax, -44(%ebp) + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax + leal 20(%ebp), %eax + movl %eax, -28(%ebp) + movl $0, -24(%ebp) + jmp .L83 +.L84: + movl -28(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -28(%ebp) + movl (%eax), %eax + sarl %eax + movl %eax, -20(%ebp) + movl -20(%ebp), %eax + leal 0(,%eax,4), %edx + movl -44(%ebp), %eax + addl %edx, %eax + movl (%eax), %eax + movl %eax, -44(%ebp) + addl $1, -24(%ebp) +.L83: + movl 8(%ebp), %eax + subl $1, %eax + cmpl %eax, -24(%ebp) + jl .L84 + movl -28(%ebp), %eax + leal 4(%eax), %edx + movl %edx, -28(%ebp) + movl (%eax), %eax + sarl %eax + movl %eax, -20(%ebp) + movl -44(%ebp), %eax + subl $4, %eax + movl %eax, -16(%ebp) + movl -16(%ebp), %eax + movl (%eax), %eax + andl $-16777216, %eax + testl %eax, %eax + jne .L85 + movl 12(%ebp), %eax + sarl %eax + movl %eax, %ecx + movl -20(%ebp), %edx + movl -44(%ebp), %eax + addl %edx, %eax + movl %ecx, %edx + movb %dl, (%eax) + jmp .L88 +.L85: + movl -20(%ebp), %eax + leal 0(,%eax,4), %edx + movl -44(%ebp), %eax + addl %eax, %edx + movl 12(%ebp), %eax + movl %eax, (%edx) +.L88: + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L87 + call __stack_chk_fail_local +.L87: + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE26: + .size Bsta, .-Bsta + .globl Lraw + .type Lraw, @function +Lraw: +.LFB27: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %eax + sarl %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE27: + .size Lraw, .-Lraw + .globl Lprintf + .type Lprintf, @function +Lprintf: +.LFB28: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %edx + movl %edx, -28(%ebp) + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + leal 12(%ebp), %edx + movl %edx, -16(%ebp) + movl -16(%ebp), %edx + subl $8, %esp + pushl %edx + pushl -28(%ebp) + movl %eax, %ebx + call vprintf@PLT + addl $16, %esp + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L92 + call __stack_chk_fail_local +.L92: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE28: + .size Lprintf, .-Lprintf + .globl Lstrcat + .type Lstrcat, @function +Lstrcat: +.LFB29: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + subl $4, %eax + movl %eax, -20(%ebp) + movl 12(%ebp), %eax + subl $4, %eax + movl %eax, -16(%ebp) + movl -20(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + movl %eax, %edx + movl -16(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + addl %edx, %eax + addl $5, %eax + subl $12, %esp + pushl %eax + call malloc@PLT + addl $16, %esp + movl %eax, -12(%ebp) + movl -20(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + movl %eax, %edx + movl -16(%ebp), %eax + movl (%eax), %eax + andl $16777215, %eax + addl %eax, %edx + movl -12(%ebp), %eax + movl %edx, (%eax) + movl -20(%ebp), %eax + leal 4(%eax), %edx + movl -12(%ebp), %eax + addl $4, %eax + subl $8, %esp + pushl %edx + pushl %eax + call strcpy@PLT + addl $16, %esp + movl -16(%ebp), %eax + leal 4(%eax), %edx + movl -12(%ebp), %eax + addl $4, %eax + subl $8, %esp + pushl %edx + pushl %eax + call strcat@PLT + addl $16, %esp + movl -12(%ebp), %eax + addl $4, %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE29: + .size Lstrcat, .-Lstrcat + .globl Lfprintf + .type Lfprintf, @function +Lfprintf: +.LFB30: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + movl 8(%ebp), %edx + movl %edx, -28(%ebp) + movl 12(%ebp), %edx + movl %edx, -32(%ebp) + movl %gs:20, %ecx + movl %ecx, -12(%ebp) + xorl %ecx, %ecx + leal 16(%ebp), %edx + movl %edx, -16(%ebp) + movl -16(%ebp), %edx + subl $4, %esp + pushl %edx + pushl -32(%ebp) + pushl -28(%ebp) + movl %eax, %ebx + call vfprintf@PLT + addl $16, %esp + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L96 + call __stack_chk_fail_local +.L96: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE30: + .size Lfprintf, .-Lfprintf + .globl Lfopen + .type Lfopen, @function +Lfopen: +.LFB31: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + subl $8, %esp + pushl 12(%ebp) + pushl 8(%ebp) + movl %eax, %ebx + call fopen@PLT + addl $16, %esp + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE31: + .size Lfopen, .-Lfopen + .globl Lfclose + .type Lfclose, @function +Lfclose: +.LFB32: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.ax + addl $_GLOBAL_OFFSET_TABLE_, %eax + subl $12, %esp + pushl 8(%ebp) + movl %eax, %ebx + call fclose@PLT + addl $16, %esp + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE32: + .size Lfclose, .-Lfclose + .section .rodata +.LC9: + .string "> " + .text + .globl Lread + .type Lread, @function +Lread: +.LFB33: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax + subl $12, %esp + leal .LC9@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + movl stdout@GOT(%ebx), %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call fflush@PLT + addl $16, %esp + subl $8, %esp + leal -16(%ebp), %eax + pushl %eax + leal .LC0@GOTOFF(%ebx), %eax + pushl %eax + call __isoc99_scanf@PLT + addl $16, %esp + movl -16(%ebp), %eax + addl %eax, %eax + orl $1, %eax + movl -12(%ebp), %edx + xorl %gs:20, %edx + je .L102 + call __stack_chk_fail_local +.L102: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE33: + .size Lread, .-Lread + .section .rodata +.LC10: + .string "%d\n" + .text + .globl Lwrite + .type Lwrite, @function +Lwrite: +.LFB34: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + sarl %eax + subl $8, %esp + pushl %eax + leal .LC10@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + movl stdout@GOT(%ebx), %eax + movl (%eax), %eax + subl $12, %esp + pushl %eax + call fflush@PLT + addl $16, %esp + movl $0, %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE34: + .size Lwrite, .-Lwrite + .section .rodata +.LC11: + .string "Start, end: %lx, %lx\n" +.LC12: + .string "Root: %lx %lx %lx\n" + .text + .globl __gc_root_scan_data + .type __gc_root_scan_data, @function +__gc_root_scan_data: +.LFB35: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl %gs:20, %eax + movl %eax, -12(%ebp) + xorl %eax, %eax + movl __gc_data_start@GOT(%ebx), %eax + movl %eax, -16(%ebp) + subl $4, %esp + movl __gc_data_end@GOT(%ebx), %eax + pushl %eax + movl __gc_data_start@GOT(%ebx), %eax + pushl %eax + leal .LC11@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + jmp .L106 +.L108: + movl -16(%ebp), %eax + movl (%eax), %eax + andl $1, %eax + testl %eax, %eax + jne .L107 + movl -16(%ebp), %eax + movl (%eax), %edx + movl -16(%ebp), %eax + leal -16(%ebp), %ecx + pushl %ecx + pushl %edx + pushl %eax + leal .LC12@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp +.L107: + movl -16(%ebp), %eax + addl $4, %eax + movl %eax, -16(%ebp) +.L106: + movl -16(%ebp), %eax + movl __gc_data_end@GOT(%ebx), %edx + cmpl %edx, %eax + jne .L108 + nop + movl -12(%ebp), %eax + xorl %gs:20, %eax + je .L109 + call __stack_chk_fail_local +.L109: + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE35: + .size __gc_root_scan_data, .-__gc_root_scan_data + .section .rodata +.LC13: + .string "STA 0x%lx\n" + .text + .globl Ltest + .type Ltest, @function +Ltest: +.LFB36: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $4, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $12, %esp + pushl $10 + call putchar@PLT + addl $16, %esp + movl __start_text@GOT(%ebx), %eax + subl $8, %esp + pushl %eax + leal .LC13@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + movl __stop_text@GOT(%ebx), %eax + subl $8, %esp + pushl %eax + leal .LC13@GOTOFF(%ebx), %eax + pushl %eax + call printf@PLT + addl $16, %esp + call __gc_root_scan_data + call __gc_root_scan_stack@PLT + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE36: + .size Ltest, .-Ltest + .local buf.3077 + .comm buf.3077,6,4 + .section .rodata + .align 4 +.LC14: + .string "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNJPQRSTUVWXYZ" + .section .data.rel.local,"aw" + .align 4 + .type chars.3076, @object + .size chars.3076, 4 +chars.3076: + .long .LC14 + .section .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat + .globl __x86.get_pc_thunk.ax + .hidden __x86.get_pc_thunk.ax + .type __x86.get_pc_thunk.ax, @function +__x86.get_pc_thunk.ax: +.LFB37: + .cfi_startproc + movl (%esp), %eax + ret + .cfi_endproc +.LFE37: + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: +.LFB38: + .cfi_startproc + movl (%esp), %ebx + ret + .cfi_endproc +.LFE38: + .hidden __stack_chk_fail_local + .ident "GCC: (GNU) 8.2.1 20180831" + .section .note.GNU-stack,"",@progbits diff --git a/src/X86.ml b/src/X86.ml index 27f6833d4..4fb198f4f 100644 --- a/src/X86.ml +++ b/src/X86.ml @@ -19,6 +19,8 @@ let word_size = 4;; | L of int (* an immediate operand *) with show +let show_opnd = show(opnd) + (* For convenience we define the following synonyms for the registers: *) let ebx = R 0 let ecx = R 1 @@ -164,7 +166,7 @@ let compile env code = (env, Mov (M ("$" ^ s), l) :: call) | LD x -> - let s, env' = (env#global x)#allocate in + let s, env' = (env#variable x)#allocate in env', (match s with | S _ | M _ -> [Mov (env'#loc x, eax); Mov (eax, s)] @@ -172,7 +174,7 @@ let compile env code = ) | STA (x, n) -> - let s, env = (env#global x)#allocate in + let s, env = (env#variable x)#allocate in let push = match s with | S _ | M _ -> [Mov (env#loc x, eax); Mov (eax, s)] @@ -182,7 +184,7 @@ let compile env code = env, push @ code | ST x -> - let s, env' = (env#global x)#pop in + let s, env' = (env#variable x)#pop in env', (match s with | S _ | M _ -> [Mov (s, eax); Mov (eax, env'#loc x)] @@ -425,13 +427,13 @@ class env = (* allocates a fresh position on a symbolic stack *) method allocate = let x, n = - let rec allocate' = function - | [] -> ebx , 0 - | (S n)::_ -> S (n+1) , n+2 - | (R n)::_ when n < num_of_regs -> R (n+1) , stack_slots - | _ -> S static_size, static_size+1 - in - allocate' stack + let rec allocate' = function + | [] -> ebx , 0 + | (S n)::_ -> S (n+1) , n+2 + | (R n)::_ when n < num_of_regs -> R (n+1) , stack_slots + | _ -> S static_size, static_size+1 + in + allocate' stack in x, {< stack_slots = max n stack_slots; stack = x::stack >} @@ -458,8 +460,11 @@ class env = done; !h - (* registers a global variable in the environment *) - method global x = {< globals = S.add ("global_" ^ x) globals >} + (* registers a variable in the environment *) + method variable x = + match self#loc x with + | M name -> {< globals = S.add name globals >} + | _ -> self (* registers a string constant *) method string x = @@ -515,14 +520,24 @@ class env = the stack code, then generates x86 assember code, then prints the assembler file *) let genasm (ds, stmt) = - let stmt = Language.Stmt.Seq (stmt, Language.Stmt.Return (Some (Language.Expr.Call ("raw", [Language.Expr.Const 0])))) in + let stmt = + Language.Stmt.Seq ( + Language.Stmt.Call ("__gc_init", []), + Language.Stmt.Seq (stmt, Language.Stmt.Return (Some (Language.Expr.Call ("raw", [Language.Expr.Const 0])))) + ) + in let env, code = compile (new env) ((LABEL "main") :: (BEGIN ("main", [], [])) :: SM.compile (ds, stmt)) in - let data = Meta "\t.data" :: (List.map (fun s -> Meta (Printf.sprintf "%s:\t.int\t0" s )) env#globals) @ - (List.map (fun (s, v) -> Meta (Printf.sprintf "%s:\t.string\t\"%s\"" v s)) env#strings) in + let gc_start, gc_end = "__gc_data_start", "__gc_data_end" in + let data = [Meta "\t.data"; Meta (Printf.sprintf "\t.globl\t%s" gc_start); Meta (Printf.sprintf "\t.globl\t%s" gc_end)] @ + [Meta (Printf.sprintf "%s:" gc_start)] @ + (List.map (fun s -> Meta (Printf.sprintf "%s:\t.int\t1" s )) env#globals) @ + [Meta (Printf.sprintf "%s:" gc_end)] @ + (List.map (fun (s, v) -> Meta (Printf.sprintf "%s:\t.string\t\"%s\"" v s)) env#strings) + in let asm = Buffer.create 1024 in List.iter (fun i -> Buffer.add_string asm (Printf.sprintf "%s\n" @@ show i)) @@ -535,5 +550,5 @@ let build prog name = Printf.fprintf outf "%s" (genasm prog); close_out outf; let inc = try Sys.getenv "RC_RUNTIME" with _ -> "../runtime" in - Sys.command (Printf.sprintf "gcc -m32 -o %s %s/runtime.o %s.s" name inc name) + Sys.command (Printf.sprintf "gcc -g -m32 -o %s %s/gc_runtime.o %s/runtime.o %s.s" name inc inc name) diff --git a/src/testgc.expr b/src/testgc.expr index 7964e97c7..595eaf0a0 100644 --- a/src/testgc.expr +++ b/src/testgc.expr @@ -1,11 +1,22 @@ -x := 0; -y := 0; -z := 0; -t := 0; -test (); +fun f () local b { + b := 7; + test (); + b := y; + test (); + b := 9; + test (); + return 0 +} + +--x := 0; +--y := 0; +--z := 0; +--t := 0; +--test (); y := "abc"; test (); t := []; test (); t := 0; -test () \ No newline at end of file +test (); +f () From 4c3dba947ce370a6a5c2b2d1fd2a5e98b379232b Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 21 Nov 2018 14:29:35 +0300 Subject: [PATCH 03/19] fix clean in Makefiles --- regression/Makefile | 3 +++ regression/deep-expressions/Makefile | 3 ++- regression/expressions/Makefile | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/regression/Makefile b/regression/Makefile index 0fc4b3f96..bc014ca91 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -13,3 +13,6 @@ $(TESTS): %: %.expr clean: rm -f test*.log *.s *~ $(TESTS) + pushd expressions && make clean && popd + pushd deep-expressions && make clean && popd + pushd x86only && make clean && popd diff --git a/regression/deep-expressions/Makefile b/regression/deep-expressions/Makefile index fe0e5468b..e46f56420 100644 --- a/regression/deep-expressions/Makefile +++ b/regression/deep-expressions/Makefile @@ -12,4 +12,5 @@ $(TESTS): %: %.expr @cat $@.input | $(RC) -s $< > $@.log && diff $@.log orig/$@.log clean: - rm -f *.log *.s *~ $(TESTS) + rm -f *.log *.s *~ + find . -maxdepth 1 -type f -not -name '*.*' -not -name 'Makefile' -delete diff --git a/regression/expressions/Makefile b/regression/expressions/Makefile index fe0e5468b..3b2afb53a 100644 --- a/regression/expressions/Makefile +++ b/regression/expressions/Makefile @@ -12,4 +12,6 @@ $(TESTS): %: %.expr @cat $@.input | $(RC) -s $< > $@.log && diff $@.log orig/$@.log clean: - rm -f *.log *.s *~ $(TESTS) + rm -f *.log *.s *~ + find . -maxdepth 1 -type f -not -name '*.*' -not -name 'Makefile' -delete + From 369c0b1ddf9486e152d16b28b12d45f714dd4fbc Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Thu, 29 Nov 2018 18:27:00 +0300 Subject: [PATCH 04/19] add a version of test039 with debug print --- regression/test039(1).expr | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 regression/test039(1).expr diff --git a/regression/test039(1).expr b/regression/test039(1).expr new file mode 100644 index 000000000..10f2761ac --- /dev/null +++ b/regression/test039(1).expr @@ -0,0 +1,41 @@ +fun insert (t, x) { + case t of + `leaf -> return `node (x, `leaf, `leaf) + | `node (y, l, r) -> if x > y + then return `node (y, insert (l, x), r) + else return `node (y, l, insert (r, x)) + fi + esac +} + +fun find (t, x) { + case t of + `leaf -> return 0 + | `node (y, l, r) -> if x == y then return 1 + elif x > y then return find (l, x) + else return find (r, x) + fi + esac +} + +n := read (); + +write (0); +t := insert (`leaf, 5); +write (2); +t := insert (t, 4); +write (3); +t := insert (t, 6); +write (4); +t := insert (t, 3); +write (5); +write (find (t, 5)); +write (6); +write (find (t, 4)); +write (find (t, 6)); +write (find (t, 3)); +write (find (t, 2)); +write (find (t, 1)); + + +t := insert (insert (insert (insert (`leaf, 5), 4), 6), 3) \ No newline at end of file From 815c3464c336688aa51ae94fe96fb6a6e9a823ae Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Thu, 29 Nov 2018 18:27:59 +0300 Subject: [PATCH 05/19] gc v 0.0.1: bug with sexp --- runtime/gc_runtime.s | 29 +++-- runtime/runtime.c | 258 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 244 insertions(+), 43 deletions(-) diff --git a/runtime/gc_runtime.s b/runtime/gc_runtime.s index 3df87be0a..1dcbe6698 100644 --- a/runtime/gc_runtime.s +++ b/runtime/gc_runtime.s @@ -7,18 +7,24 @@ printf_format5: .string "LOL\n" __gc_stack_bottom: .long 0 __gc_stack_top: .long 0 - .globl L__gc_init - .globl __gc_root_scan_stack - + .globl L__gc_init + .globl __gc_root_scan_stack + .extern init_pool + .extern __gc_test_and_copy_root .text L__gc_init: movl %esp, __gc_stack_bottom addl $4, __gc_stack_bottom + call init_pool ret __gc_root_scan_stack: + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %edx movl %esp, __gc_stack_top movl %esp, %eax - jmp next + jmp next loop: movl (%eax), %ebx @@ -54,15 +60,22 @@ check22: loop2: andl $0x00000001, %ebx jnz next +gc_run_t: pushl %eax - pushl (%eax) - pushl $printf_format - call printf - addl $8, %esp +// pushl (%eax) + pushl %eax + call __gc_test_and_copy_root + addl $4, %esp popl %eax next: addl $4, %eax cmpl %eax, __gc_stack_bottom jne loop +returnn: + movl $0, %eax + popl %edx + popl %ebx + movl %ebp, %esp + popl %ebp ret diff --git a/runtime/runtime.c b/runtime/runtime.c index 530990f8b..e85c1b0a1 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -2,18 +2,18 @@ # include # include -# include # include # include -# include # include +# include +# include -# define STRING_TAG 0x00000000 -# define ARRAY_TAG 0x01000000 -# define SEXP_TAG 0x02000000 +# define STRING_TAG 0x00000001 +# define ARRAY_TAG 0x00000003 +# define SEXP_TAG 0x00000005 -# define LEN(x) (x & 0x00FFFFFF) -# define TAG(x) (x & 0xFF000000) +# define LEN(x) ((x & 0xFFFFFFF8) >> 3) +# define TAG(x) (x & 0x00000007) # define TO_DATA(x) ((data*)((char*)(x)-sizeof(int))) # define TO_SEXP(x) ((sexp*)((char*)(x)-2*sizeof(int))) @@ -32,6 +32,8 @@ typedef struct { data contents; } sexp; +static void* alloc (size_t); + extern int Blength (void *p) { data *a = TO_DATA(p); return BOX(LEN(a->tag)); @@ -153,9 +155,9 @@ extern void* Belem (void *p, int i) { extern void* Bstring (void *p) { int n = strlen (p); - data *r = (data*) malloc (n + 1 + sizeof (int)); + data *r = (data*) alloc (n + 1 + sizeof (int)); - r->tag = n; + r->tag = STRING_TAG | (n << 3); strncpy (r->contents, p, n + 1); return r->contents; @@ -177,9 +179,9 @@ extern void* Bstringval (void *p) { extern void* Barray (int n, ...) { va_list args; int i; - data *r = (data*) malloc (sizeof(int) * (n+1)); + data *r = (data*) alloc (sizeof(int) * (n+1)); - r->tag = ARRAY_TAG | n; + r->tag = ARRAY_TAG | (n << 3); va_start(args, n); @@ -196,10 +198,16 @@ extern void* Barray (int n, ...) { extern void* Bsexp (int n, ...) { va_list args; int i; - sexp *r = (sexp*) malloc (sizeof(int) * (n+2)); - data *d = &(r->contents); + // sexp *r = (sexp*) alloc (sizeof(int) * (n+2)); + // data *d = &(r->contents); + sexp *r; + data *d; - d->tag = SEXP_TAG | (n-1); + printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+2)); + r = (sexp*) alloc (sizeof(int) * (n+2)); + d = &(r->contents); + + d->tag = SEXP_TAG | ((n-1) << 3); va_start(args, n); @@ -303,7 +311,7 @@ extern void* Lstrcat (void *a, void *b) { data *da = TO_DATA(a); data *db = TO_DATA(b); - data *d = (data *) malloc (sizeof(int) + LEN(da->tag) + LEN(db->tag) + 1); + data *d = (data *) alloc (sizeof(int) + LEN(da->tag) + LEN(db->tag) + 1); d->tag = LEN(da->tag) + LEN(db->tag); @@ -355,17 +363,6 @@ extern size_t __gc_stack_bottom, __gc_stack_top; extern void L__gc_init (); -extern void __gc_root_scan_data () { - size_t * p = &__gc_data_start; - - printf ("Start, end: %lx, %lx\n", &__gc_data_start, &__gc_data_end); - - while (p != &__gc_data_end) { - if (!UNBOXED(*p)) printf ("Root: %lx\n", *p); - p++; - } -} - extern void __gc_root_scan_stack (); @@ -385,14 +382,205 @@ extern void __gc_root_scan_stack (); extern char __executable_start; extern char __etext; -extern void Ltest () { - printf("\n"); - printf("STA 0x%lx\n", (unsigned long)&__executable_start); - printf("END 0x%lx\n", (unsigned long)&__etext); - __gc_root_scan_data (); - __gc_root_scan_stack (); +/* extern void Ltest () { */ +/* printf("\n"); */ +/* printf("STA 0x%lx\n", (unsigned long)&__executable_start); */ +/* printf("END 0x%lx\n", (unsigned long)&__etext); */ +/* __gc_root_scan_data (); */ +/* __gc_root_scan_stack (); */ - // printf("STA 0x%lx\n", (unsigned long)&__executable_start); - // printf("END 0x%lx\n", (unsigned long)&__etext); - // printf("RET 0x%lx\n\n", __builtin_return_address(0)); +/* // printf("STA 0x%lx\n", (unsigned long)&__executable_start); */ +/* // printf("END 0x%lx\n", (unsigned long)&__etext); */ +/* // printf("RET 0x%lx\n\n", __builtin_return_address(0)); */ +/* } */ + +/* ======================================== */ +/* Mark-and-copy */ +/* ======================================== */ + +static size_t SPACE_SIZE = 128; +# define POOL_SIZE (2*SPACE_SIZE) + +typedef struct { + size_t * begin; + size_t * end; + size_t * current; + size_t size; +} pool; + +static pool from_space; +static pool to_space; +size_t * current; + +static void swap (size_t ** a, size_t ** b) { + size_t * t = *a; + *a = *b; + *b = t; +} + +static void __gc_swap_spaces (void) { + swap (&from_space.begin, &to_space.begin); + swap (&from_space.end , &to_space.end ); + from_space.current = current; + to_space.current = to_space.begin; +} + +# define IS_VALID_HEAP_POINTER(p)\ + (!UNBOXED(p) && \ + from_space.begin <= p && \ + from_space.end > p) + +# define IN_PASSIVE_SPACE(p) \ + (to_space.begin <= p && \ + to_space.end > p) + +# define IS_FORWARD_PTR(p) \ + (!UNBOXED(p) && IN_PASSIVE_SPACE(p)) + +extern size_t * gc_copy (size_t *obj); + +static void copy_elements (size_t *where, size_t *from, int len) { + int i = 0; + for (i = 0; i < len; i++) { + size_t elem = from[i]; + // if (UNBOXED(elem)) *++where = elem; + if (!IS_VALID_HEAP_POINTER(elem)) *++where = elem; + else *++where = gc_copy ((size_t*) elem); + } +} + +extern size_t * gc_copy (size_t *obj) { + data *d = TO_DATA(obj); + sexp *s = NULL; + size_t *copy = NULL; + int i = 0; + int len1, len2, len3; + void * objj; + void * newobjj = (void*)current; + printf("gc_copy: %x cur = %x starts\n", obj, current); + + if (!IS_VALID_HEAP_POINTER(obj)) { + printf ("gc_copy: invalid ptr: %x\n", obj); + return obj; + } + + if (!IN_PASSIVE_SPACE(current)) { + printf("ERROR: gc_copy: out-of-space %x %x %x\n", current, to_space.begin, to_space.end); + fflush(stdout); + perror("ERROR: gc_copy: out-of-space\n"); + exit (6); + } + + if (IS_FORWARD_PTR(d->tag)) + return (size_t *) d->tag; + + copy = current; + objj = d; + switch (TAG(d->tag)) { + case ARRAY_TAG: + current += (LEN(d->tag) + 1) * sizeof (int); + *copy = d->tag; + copy++; + copy_elements (copy, obj, LEN(d->tag)); + d->tag = (int) copy; + break; + case STRING_TAG: + current += (LEN(d->tag) + 1) * sizeof (int); + *copy = d->tag; + copy++; + d->tag = (int) copy; + strcpy (©[1], (char*) obj); + break; + case SEXP_TAG : + s = TO_SEXP(obj); + objj = s; + len1 = LEN(s->contents.tag); + len2 = LEN(s->tag); + len3 = LEN(d->tag); + printf("len1 = %li, len2=%li, len3 = %li\n",len1,len2,len3); + current += (LEN(s->contents.tag) + 2) * sizeof (int); + *copy = s->tag; + copy++; + *copy = s->contents.tag; + copy++; + len3 = LEN(s->contents.tag); + s->contents.tag = (int) copy; + copy_elements (copy, obj, len3); + break; + default: + printf ("ERROR: gc_copy: weird tag: %x", TAG(d->tag)); + fflush(stdout); + perror ("ERROR: gc_copy: weird tag"); + exit(5); + } + printf("gc_copy: %x -> %x\n", objj, newobjj); + fflush(stdout); + return copy; +} + +extern void __gc_test_and_copy_root (size_t ** root) { + if (IS_VALID_HEAP_POINTER(*root)) + *root = gc_copy (*root); +} + +extern void __gc_root_scan_data (void) { + size_t * p = &__gc_data_start; + while (p != &__gc_data_end) { + __gc_test_and_copy_root (p); + p++; + } +} + +extern void init_pool (void) { + from_space.begin = mmap(NULL, SPACE_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + to_space.begin = mmap(NULL, SPACE_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + if (to_space.begin == MAP_FAILED || + from_space.begin == MAP_FAILED) { + perror("EROOR: init_pool: mmap failed\n"); + exit(1); + } + from_space.current = from_space.begin; + from_space.end = from_space.begin + SPACE_SIZE; + from_space.size = SPACE_SIZE; + to_space.current = to_space.begin; + to_space.end = to_space.begin + SPACE_SIZE; + to_space.size = SPACE_SIZE; +} + +static int free_pool (pool * p) { + return munmap((void *)p->begin, p->size); +} + +static void * gc (size_t size) { + current = to_space.begin; + printf("gc: current: %x; to_space.b = %x; to_space.e = %x; f_space.b = %x; f_space.e = %x\n", current, to_space.begin, to_space.end, from_space.begin, from_space.end); + __gc_root_scan_data (); + __gc_root_scan_stack (); + if (!IN_PASSIVE_SPACE(current)) { + perror ("ASSERT: !IN_PASSIVE_SPACE(current)\n"); + exit(1); + } + + if (current + size >= to_space.end) { + perror ("ERROR: gc: out of memory\n"); + exit(4); + } + + __gc_swap_spaces (); + from_space.current = current + size; + return current; +} + +static void * alloc (size_t size) { + if (from_space.current + size < from_space.end) { + printf("alloc: current: %x %zu", from_space.current, size); + void * p = (void*) from_space.current; + from_space.current += size; + printf(";new current: %x \n", from_space.current); + return p; + } + printf("alloc: call gc: %zu\n", size); + return gc (size); } From 0a056fc7445b62c511d3266a978166e38c0399cf Mon Sep 17 00:00:00 2001 From: danyaberezun Date: Fri, 30 Nov 2018 16:18:12 +0300 Subject: [PATCH 06/19] add #define DEBUG_PRINT --- runtime/runtime.c | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index e85c1b0a1..f1aea04dd 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -8,6 +8,8 @@ # include # include +// # define DEBUG_PRINT 1 + # define STRING_TAG 0x00000001 # define ARRAY_TAG 0x00000003 # define SEXP_TAG 0x00000005 @@ -44,12 +46,16 @@ char* de_hash (int n) { static char buf[6]; char *p = &buf[5]; - /*printf ("tag: %d\n", n);*/ +#ifdef DEBUG_PRINT + printf ("de_hash: tag: %d\n", n); +#endif *p-- = 0; while (n != 0) { - /*printf ("char: %c\n", chars [n & 0x003F]);*/ +#ifdef DEBUG_PRINT + printf ("char: %c\n", chars [n & 0x003F]); +#endif *p-- = chars [n & 0x003F]; n = n >> 6; } @@ -144,8 +150,6 @@ extern void* Belem (void *p, int i) { data *a = TO_DATA(p); i = UNBOX(i); - /* printf ("elem %d = %p\n", i, (void*) ((int*) a->contents)[i]); */ - if (TAG(a->tag) == STRING_TAG) { return (void*) BOX(a->contents[i]); } @@ -203,7 +207,9 @@ extern void* Bsexp (int n, ...) { sexp *r; data *d; +#ifdef DEBUG_PRINT printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+2)); +#endif r = (sexp*) alloc (sizeof(int) * (n+2)); d = &(r->contents); @@ -213,16 +219,12 @@ extern void* Bsexp (int n, ...) { for (i=0; icontents)[i] = ai; } r->tag = va_arg(args, int); va_end(args); - //printf ("tag %d\n", r->tag); - //printf ("returning %p\n", d->contents); - return d->contents; } @@ -454,19 +456,25 @@ extern size_t * gc_copy (size_t *obj) { sexp *s = NULL; size_t *copy = NULL; int i = 0; +#ifdef DEBUG_PRINT int len1, len2, len3; void * objj; void * newobjj = (void*)current; printf("gc_copy: %x cur = %x starts\n", obj, current); +#endif if (!IS_VALID_HEAP_POINTER(obj)) { +#ifdef DEBUG_PRINT printf ("gc_copy: invalid ptr: %x\n", obj); +#endif return obj; } if (!IN_PASSIVE_SPACE(current)) { +#ifdef DEBUG_PRINT printf("ERROR: gc_copy: out-of-space %x %x %x\n", current, to_space.begin, to_space.end); fflush(stdout); +#endif perror("ERROR: gc_copy: out-of-space\n"); exit (6); } @@ -475,7 +483,9 @@ extern size_t * gc_copy (size_t *obj) { return (size_t *) d->tag; copy = current; +#ifdef DEBUG_PRINT objj = d; +#endif switch (TAG(d->tag)) { case ARRAY_TAG: current += (LEN(d->tag) + 1) * sizeof (int); @@ -493,28 +503,34 @@ extern size_t * gc_copy (size_t *obj) { break; case SEXP_TAG : s = TO_SEXP(obj); +#ifdef DEBUG_PRINT objj = s; len1 = LEN(s->contents.tag); len2 = LEN(s->tag); len3 = LEN(d->tag); printf("len1 = %li, len2=%li, len3 = %li\n",len1,len2,len3); +#endif current += (LEN(s->contents.tag) + 2) * sizeof (int); *copy = s->tag; copy++; *copy = s->contents.tag; copy++; - len3 = LEN(s->contents.tag); + i = LEN(s->contents.tag); s->contents.tag = (int) copy; - copy_elements (copy, obj, len3); + copy_elements (copy, obj, i); break; default: +#ifdef DEBUG_PRINT printf ("ERROR: gc_copy: weird tag: %x", TAG(d->tag)); fflush(stdout); +#endif perror ("ERROR: gc_copy: weird tag"); exit(5); } +#ifdef DEBUG_PRINT printf("gc_copy: %x -> %x\n", objj, newobjj); fflush(stdout); +#endif return copy; } @@ -555,7 +571,10 @@ static int free_pool (pool * p) { static void * gc (size_t size) { current = to_space.begin; - printf("gc: current: %x; to_space.b = %x; to_space.e = %x; f_space.b = %x; f_space.e = %x\n", current, to_space.begin, to_space.end, from_space.begin, from_space.end); +#ifdef DEBUG_PRINT + printf("gc: current: %x; to_space.b = %x; to_space.e = %x; f_space.b = %x; f_space.e = %x\n", + current, to_space.begin, to_space.end, from_space.begin, from_space.end); +#endif __gc_root_scan_data (); __gc_root_scan_stack (); if (!IN_PASSIVE_SPACE(current)) { @@ -575,12 +594,18 @@ static void * gc (size_t size) { static void * alloc (size_t size) { if (from_space.current + size < from_space.end) { +#ifdef DEBUG_PRINT printf("alloc: current: %x %zu", from_space.current, size); +#endif void * p = (void*) from_space.current; from_space.current += size; +#ifdef DEBUG_PRINT printf(";new current: %x \n", from_space.current); +#endif return p; } +#ifdef DEBUG_PRINT printf("alloc: call gc: %zu\n", size); +#endif return gc (size); } From 4e3bdbbbb172e3ba25f3e0e5f0f9d3b47dcd7c5e Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Mon, 3 Dec 2018 14:48:23 +0300 Subject: [PATCH 07/19] Fix for a new GT\#ppx --- src/Language.ml | 5 ++--- src/SM.ml | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Language.ml b/src/Language.ml index 33a0fd4ed..5b0a48fdf 100644 --- a/src/Language.ml +++ b/src/Language.ml @@ -318,9 +318,8 @@ module Stmt = | "#" %"sexp" {SexpTag} | "#" %"array" {ArrayTag} ) - - let vars p = fix0 (fun f -> - transform(t) (object inherit [string list, _] @t[foldl] f method c_Named s name p = name :: f s p end)) [] p + + let vars p = transform(t) (fun f -> object inherit [string list, _] @t[foldl] f method c_Named s _ name p = name :: f s p end) [] p end diff --git a/src/SM.ml b/src/SM.ml index 118548281..6e78b7515 100644 --- a/src/SM.ml +++ b/src/SM.ml @@ -186,21 +186,21 @@ let compile (defs, p) = List.flatten (List.rev code), env and bindings p = let bindings = - fix0 (fun fself -> transform(Stmt.Pattern.t) - (object inherit [int list, (string * int list) list, _] @Stmt.Pattern.t - method c_Wildcard path = [] - method c_Named path s p = [s, path] @ fself path p - method c_Sexp path x ps = List.concat @@ List.mapi (fun i p -> fself (path @ [i]) p) ps - method c_UnBoxed _ = [] - method c_StringTag _ = [] - method c_String _ _ = [] - method c_SexpTag _ = [] - method c_Const _ _ = [] - method c_Boxed _ = [] - method c_ArrayTag _ = [] - method c_Array path ps = List.concat @@ List.mapi (fun i p -> fself (path @ [i]) p) ps - end)) + (fun fself -> + object inherit [int list, (string * int list) list, _] @Stmt.Pattern.t + method c_Wildcard path _ = [] + method c_Named path _ s p = [s, path] @ fself path p + method c_Sexp path _ x ps = List.concat @@ List.mapi (fun i p -> fself (path @ [i]) p) ps + method c_UnBoxed _ _ = [] + method c_StringTag _ _ = [] + method c_String _ _ _ = [] + method c_SexpTag _ _ = [] + method c_Const _ _ _ = [] + method c_Boxed _ _ = [] + method c_ArrayTag _ _ = [] + method c_Array path _ ps = List.concat @@ List.mapi (fun i p -> fself (path @ [i]) p) ps + end) [] p in From 49701ce740209e9e4b513731271199da994e8762 Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Mon, 3 Dec 2018 15:10:43 +0300 Subject: [PATCH 08/19] New ppx --- regression/Makefile | 8 ++++---- regression/test039(1).expr | 41 -------------------------------------- 2 files changed, 4 insertions(+), 45 deletions(-) delete mode 100644 regression/test039(1).expr diff --git a/regression/Makefile b/regression/Makefile index bc014ca91..384fefd72 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -12,7 +12,7 @@ $(TESTS): %: %.expr @cat $@.input | $(RC) -s $< > $@.log && diff $@.log orig/$@.log clean: - rm -f test*.log *.s *~ $(TESTS) - pushd expressions && make clean && popd - pushd deep-expressions && make clean && popd - pushd x86only && make clean && popd + $(RM) test*.log *.s *~ $(TESTS) + $(MAKE) clean -C expressions + $(MAKE) clean -C deep-expressions + $(MAKE) clean -C x86only diff --git a/regression/test039(1).expr b/regression/test039(1).expr deleted file mode 100644 index 10f2761ac..000000000 --- a/regression/test039(1).expr +++ /dev/null @@ -1,41 +0,0 @@ -fun insert (t, x) { - case t of - `leaf -> return `node (x, `leaf, `leaf) - | `node (y, l, r) -> if x > y - then return `node (y, insert (l, x), r) - else return `node (y, l, insert (r, x)) - fi - esac -} - -fun find (t, x) { - case t of - `leaf -> return 0 - | `node (y, l, r) -> if x == y then return 1 - elif x > y then return find (l, x) - else return find (r, x) - fi - esac -} - -n := read (); - -write (0); -t := insert (`leaf, 5); -write (2); -t := insert (t, 4); -write (3); -t := insert (t, 6); -write (4); -t := insert (t, 3); -write (5); -write (find (t, 5)); -write (6); -write (find (t, 4)); -write (find (t, 6)); -write (find (t, 3)); -write (find (t, 2)); -write (find (t, 1)); - - -t := insert (insert (insert (insert (`leaf, 5), 4), 6), 3) \ No newline at end of file From de1823922a039581573dea10cce045685c96822b Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Mon, 3 Dec 2018 17:01:32 +0300 Subject: [PATCH 09/19] Minor fixes in runtime (initialization\!) --- runtime/runtime.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index f1aea04dd..4771b6e94 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -8,7 +8,7 @@ # include # include -// # define DEBUG_PRINT 1 +# define DEBUG_PRINT 1 # define STRING_TAG 0x00000001 # define ARRAY_TAG 0x00000003 @@ -200,12 +200,11 @@ extern void* Barray (int n, ...) { } extern void* Bsexp (int n, ...) { - va_list args; - int i; - // sexp *r = (sexp*) alloc (sizeof(int) * (n+2)); - // data *d = &(r->contents); - sexp *r; - data *d; + va_list args = (va_list) BOX(NULL); + int i = BOX(0); + int ai = BOX(0); + sexp *r = (sexp*) BOX(NULL); + data *d = (sexp*) BOX(NULL); #ifdef DEBUG_PRINT printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+2)); @@ -218,7 +217,7 @@ extern void* Bsexp (int n, ...) { va_start(args, n); for (i=0; icontents)[i] = ai; } @@ -593,11 +592,12 @@ static void * gc (size_t size) { } static void * alloc (size_t size) { + void * p = BOX(NULL); if (from_space.current + size < from_space.end) { #ifdef DEBUG_PRINT printf("alloc: current: %x %zu", from_space.current, size); #endif - void * p = (void*) from_space.current; + p = (void*) from_space.current; from_space.current += size; #ifdef DEBUG_PRINT printf(";new current: %x \n", from_space.current); From bff4ae225e6131f42bf207195b222d1739139911 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 5 Dec 2018 18:31:12 +0300 Subject: [PATCH 10/19] still with bug (incorrect stack root) --- regression/test039.expr | 1 - runtime/gc_runtime.s | 20 +++++-- runtime/runtime.c | 115 +++++++++++++++++++++++++++++++++++----- runtime/testgc.expr | 9 ++++ 4 files changed, 128 insertions(+), 17 deletions(-) create mode 100644 runtime/testgc.expr diff --git a/regression/test039.expr b/regression/test039.expr index 1eaff0a70..1075d8de7 100644 --- a/regression/test039.expr +++ b/regression/test039.expr @@ -28,4 +28,3 @@ write (find (t, 6)); write (find (t, 3)); write (find (t, 2)); write (find (t, 1)) - diff --git a/runtime/gc_runtime.s b/runtime/gc_runtime.s index 1dcbe6698..a22e40c68 100644 --- a/runtime/gc_runtime.s +++ b/runtime/gc_runtime.s @@ -6,7 +6,8 @@ printf_format4: .string "EAX: %lx\n" printf_format5: .string "LOL\n" __gc_stack_bottom: .long 0 __gc_stack_top: .long 0 - + + .globl __pre_gc .globl L__gc_init .globl __gc_root_scan_stack .extern init_pool @@ -17,13 +18,26 @@ L__gc_init: movl %esp, __gc_stack_bottom call init_pool ret +__pre_gc: + movl %ebp, __gc_stack_top + ret + __gc_root_scan_stack: pushl %ebp movl %esp, %ebp pushl %ebx pushl %edx - movl %esp, __gc_stack_top - movl %esp, %eax + +// pushl __gc_stack_top +// call Lwrite2 +// addl $4, %esp +// pushl __gc_stack_bottom +// call Lwrite2 +// addl $4, %esp + +// movl %esp, __gc_stack_top +// movl %esp, %eax + movl __gc_stack_top, %eax jmp next loop: diff --git a/runtime/runtime.c b/runtime/runtime.c index 4771b6e94..3bd44ee91 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -182,8 +182,11 @@ extern void* Bstringval (void *p) { extern void* Barray (int n, ...) { va_list args; - int i; - data *r = (data*) alloc (sizeof(int) * (n+1)); + int i = 1; + data *r = NULL; + printf ("Barray: create n = %d\n", n); + fflush(stdout); + r = (data*) alloc (sizeof(int) * (n+1)); r->tag = ARRAY_TAG | (n << 3); @@ -207,9 +210,9 @@ extern void* Bsexp (int n, ...) { data *d = (sexp*) BOX(NULL); #ifdef DEBUG_PRINT - printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+2)); + printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+1)); #endif - r = (sexp*) alloc (sizeof(int) * (n+2)); + r = (sexp*) alloc (sizeof(int) * (n+1)); d = &(r->contents); d->tag = SEXP_TAG | ((n-1) << 3); @@ -357,12 +360,20 @@ extern int Lwrite (int n) { return 0; } +extern int Lwrite2 (size_t* n) { + printf ("%x\n", n); + fflush (stdout); + + return 0; +} + /* GC starts here */ extern const size_t __gc_data_end, __gc_data_start; extern size_t __gc_stack_bottom, __gc_stack_top; extern void L__gc_init (); +extern void __pre_gc (); extern void __gc_root_scan_stack (); @@ -440,16 +451,68 @@ static void __gc_swap_spaces (void) { extern size_t * gc_copy (size_t *obj); +/* static void copy_elements (size_t *where, size_t *from, int len) { */ +/* int i = 0; */ +/* void * p = NULL; */ +/* for (i = 0; i < len; i++) { */ +/* size_t elem = from[i]; */ +/* // if (UNBOXED(elem)) *++where = elem; */ +/* if (!IS_VALID_HEAP_POINTER(elem)) *++where = elem; */ +/* else { */ +/* // *++where = gc_copy ((size_t*) elem); */ +/* p = gc_copy ((size_t*) elem); */ +/* printf ("copy_elements: fix %x --> %x\n", *where, p); */ +/* *where = p; */ +/* where ++; */ +/* } */ +/* } */ +/* } */ + static void copy_elements (size_t *where, size_t *from, int len) { int i = 0; + void * p = NULL; for (i = 0; i < len; i++) { size_t elem = from[i]; // if (UNBOXED(elem)) *++where = elem; - if (!IS_VALID_HEAP_POINTER(elem)) *++where = elem; - else *++where = gc_copy ((size_t*) elem); + if (!IS_VALID_HEAP_POINTER(elem)) { + // *++where = elem; + *where = elem; + where++; + } + else { + // *++where = gc_copy ((size_t*) elem); + p = gc_copy ((size_t*) elem); + *where = p; +#ifdef DEBUG_PRINT + printf ("copy_elements: fix %x: %x\n", from, *where); +#endif + where ++; + } } } +static void extend_spaces (void) { + /* void *from_e = mmap(from_space.end, SPACE_SIZE, PROT_READ | PROT_WRITE, */ + /* MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); */ + /* void *to_e = mmap(to_space.end , SPACE_SIZE, PROT_READ | PROT_WRITE, */ + /* MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); */ + void *p1 = mremap(from_space.begin, SPACE_SIZE, 2*SPACE_SIZE, 0); + void *p2 = mremap(to_space.begin , SPACE_SIZE, 2*SPACE_SIZE, 0); + if (p1 == MAP_FAILED || p2 == MAP_FAILED) { + perror("EROOR: extend_spaces: mmap failed\n"); + exit(7); + } +#ifdef DEBUG_PRINT + printf ("extend: %x %x %x %x\n", p1, p2, from_space.begin, to_space.begin); + printf ("extend: %x %x %x\n", from_space.end, to_space.end, current); +#endif + from_space.end += SPACE_SIZE; + to_space.end += SPACE_SIZE; + SPACE_SIZE += SPACE_SIZE; + from_space.size = SPACE_SIZE; + to_space.size = SPACE_SIZE; +} + extern size_t * gc_copy (size_t *obj) { data *d = TO_DATA(obj); sexp *s = NULL; @@ -476,10 +539,15 @@ extern size_t * gc_copy (size_t *obj) { #endif perror("ERROR: gc_copy: out-of-space\n"); exit (6); + // extend_spaces (); + // assert (IN_PASSIVE_SPACE(current)); } - if (IS_FORWARD_PTR(d->tag)) + if (IS_FORWARD_PTR(d->tag)) { + printf ("gc_copy: IS_FORWARD_PTR: return! %x\n", (size_t *) d->tag); + fflush(stdout); return (size_t *) d->tag; + } copy = current; #ifdef DEBUG_PRINT @@ -487,13 +555,16 @@ extern size_t * gc_copy (size_t *obj) { #endif switch (TAG(d->tag)) { case ARRAY_TAG: + printf ("gc_copy:array_tag; len = %zu\n", LEN(d->tag)); + fflush(stdout); current += (LEN(d->tag) + 1) * sizeof (int); *copy = d->tag; copy++; - copy_elements (copy, obj, LEN(d->tag)); d->tag = (int) copy; + copy_elements (copy, obj, LEN(d->tag)); break; case STRING_TAG: + printf ("gc_copy:string_tag \n"); current += (LEN(d->tag) + 1) * sizeof (int); *copy = d->tag; copy++; @@ -515,7 +586,8 @@ extern size_t * gc_copy (size_t *obj) { *copy = s->contents.tag; copy++; i = LEN(s->contents.tag); - s->contents.tag = (int) copy; + // s->contents.tag = (int) copy; + d->tag = (int) copy; copy_elements (copy, obj, i); break; default: @@ -527,15 +599,19 @@ extern size_t * gc_copy (size_t *obj) { exit(5); } #ifdef DEBUG_PRINT - printf("gc_copy: %x -> %x\n", objj, newobjj); + printf("gc_copy: %x (%x) -> %x (%x)\n", obj, objj, copy, newobjj); fflush(stdout); #endif return copy; } extern void __gc_test_and_copy_root (size_t ** root) { - if (IS_VALID_HEAP_POINTER(*root)) + if (IS_VALID_HEAP_POINTER(*root)) { +#ifdef DEBUG_PRINT + printf ("__gc_test_and_copy_root: root %x %x\n", root, *root); +#endif *root = gc_copy (*root); + } } extern void __gc_root_scan_data (void) { @@ -575,6 +651,9 @@ static void * gc (size_t size) { current, to_space.begin, to_space.end, from_space.begin, from_space.end); #endif __gc_root_scan_data (); +#ifdef DEBUG_PRINT + printf("gc: data is scanned\n"); +#endif __gc_root_scan_stack (); if (!IN_PASSIVE_SPACE(current)) { perror ("ASSERT: !IN_PASSIVE_SPACE(current)\n"); @@ -582,8 +661,17 @@ static void * gc (size_t size) { } if (current + size >= to_space.end) { - perror ("ERROR: gc: out of memory\n"); - exit(4); +#ifdef DEBUG_PRINT + printf ("gc pre-extend_spaces : %x %x %x \n", current, size, to_space.end); +#endif + extend_spaces (); +#ifdef DEBUG_PRINT + printf ("gc post-extend_spaces: %x %x %x \n", current, size, to_space.end); +#endif + assert (IN_PASSIVE_SPACE(current)); + assert (current + size < to_space.end); + // perror ("ERROR: gc: out of memory\n"); + // exit(4); } __gc_swap_spaces (); @@ -607,5 +695,6 @@ static void * alloc (size_t size) { #ifdef DEBUG_PRINT printf("alloc: call gc: %zu\n", size); #endif + __pre_gc () ; return gc (size); } diff --git a/runtime/testgc.expr b/runtime/testgc.expr new file mode 100644 index 000000000..e27c14c46 --- /dev/null +++ b/runtime/testgc.expr @@ -0,0 +1,9 @@ +fun print_list (l) { + case l of + `nil -> skip + | `cons (n, t) -> write (n); print_list (t) + esac +} + +x := `cons (4, `cons(3, `cons(2 , `cons (1, `cons (0, `cons (1, `cons (2, `cons (3, `cons (4, `cons (5, `nil)))))))))); +print_list (x) From b23e870890e683d8014e3f1d5b62cca909ae3bdb Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 5 Dec 2018 19:06:07 +0300 Subject: [PATCH 11/19] fix debug print --- runtime/runtime.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index 3bd44ee91..5f54551c0 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -8,7 +8,7 @@ # include # include -# define DEBUG_PRINT 1 +// # define DEBUG_PRINT 1 # define STRING_TAG 0x00000001 # define ARRAY_TAG 0x00000003 @@ -184,8 +184,10 @@ extern void* Barray (int n, ...) { va_list args; int i = 1; data *r = NULL; +#ifdef DEBUG_PRINT printf ("Barray: create n = %d\n", n); fflush(stdout); +#endif r = (data*) alloc (sizeof(int) * (n+1)); r->tag = ARRAY_TAG | (n << 3); @@ -544,8 +546,10 @@ extern size_t * gc_copy (size_t *obj) { } if (IS_FORWARD_PTR(d->tag)) { +#ifdef DEBUG_PRINT printf ("gc_copy: IS_FORWARD_PTR: return! %x\n", (size_t *) d->tag); fflush(stdout); +#endif return (size_t *) d->tag; } @@ -555,8 +559,10 @@ extern size_t * gc_copy (size_t *obj) { #endif switch (TAG(d->tag)) { case ARRAY_TAG: +#ifdef DEBUG_PRINT printf ("gc_copy:array_tag; len = %zu\n", LEN(d->tag)); fflush(stdout); +#endif current += (LEN(d->tag) + 1) * sizeof (int); *copy = d->tag; copy++; @@ -564,8 +570,10 @@ extern size_t * gc_copy (size_t *obj) { copy_elements (copy, obj, LEN(d->tag)); break; case STRING_TAG: +#ifdef DEBUG_PRINT printf ("gc_copy:string_tag \n"); current += (LEN(d->tag) + 1) * sizeof (int); +#endif *copy = d->tag; copy++; d->tag = (int) copy; From 459fcfb1ab8e1a8ff55acbdaee7aacc1c91682ba Mon Sep 17 00:00:00 2001 From: danyaberezun Date: Thu, 6 Dec 2018 22:53:04 +0300 Subject: [PATCH 12/19] fix Bstring + fix current in gc_copy: string --- runtime/runtime.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index 5f54551c0..9f8ee8f94 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -159,7 +159,8 @@ extern void* Belem (void *p, int i) { extern void* Bstring (void *p) { int n = strlen (p); - data *r = (data*) alloc (n + 1 + sizeof (int)); + data *r = NULL; + r = (data*) alloc (n + 1 + sizeof (int)); r->tag = STRING_TAG | (n << 3); strncpy (r->contents, p, n + 1); @@ -569,17 +570,21 @@ extern size_t * gc_copy (size_t *obj) { d->tag = (int) copy; copy_elements (copy, obj, LEN(d->tag)); break; + case STRING_TAG: #ifdef DEBUG_PRINT - printf ("gc_copy:string_tag \n"); - current += (LEN(d->tag) + 1) * sizeof (int); + printf ("gc_copy:string_tag; len = %d\n", LEN(d->tag) + 1); + fflush(stdout); #endif + // current += (LEN(d->tag) + 1) * sizeof (int); + current += LEN(d->tag) * sizeof(char) + sizeof (int); *copy = d->tag; copy++; d->tag = (int) copy; strcpy (©[1], (char*) obj); break; - case SEXP_TAG : + + case SEXP_TAG : s = TO_SEXP(obj); #ifdef DEBUG_PRINT objj = s; @@ -598,6 +603,7 @@ extern size_t * gc_copy (size_t *obj) { d->tag = (int) copy; copy_elements (copy, obj, i); break; + default: #ifdef DEBUG_PRINT printf ("ERROR: gc_copy: weird tag: %x", TAG(d->tag)); @@ -607,7 +613,7 @@ extern size_t * gc_copy (size_t *obj) { exit(5); } #ifdef DEBUG_PRINT - printf("gc_copy: %x (%x) -> %x (%x)\n", obj, objj, copy, newobjj); + printf("gc_copy: %x (%x) -> %x (%x); new-current = %x\n", obj, objj, copy, newobjj, current); fflush(stdout); #endif return copy; From 985ad50813eb808a1343d260bf8eac3a0d2c2119 Mon Sep 17 00:00:00 2001 From: danyaberezun Date: Thu, 6 Dec 2018 23:04:45 +0300 Subject: [PATCH 13/19] init all locals --- runtime/runtime.c | 79 ++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index 9f8ee8f94..561acd452 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -91,9 +91,10 @@ static void extendStringBuf () { } static void printStringBuf (char *fmt, ...) { - va_list args; - int written, rest; - char *buf; + va_list args = (va_list) BOX(NULL); + int written = 0, + rest = 0; + char *buf = (char*) BOX(NULL); again: va_start (args, fmt); @@ -110,9 +111,11 @@ static void printStringBuf (char *fmt, ...) { } static void printValue (void *p) { + data *a = (data*) BOX(NULL); + int i = BOX(0); if (UNBOXED(p)) printStringBuf ("%d", UNBOX(p)); else { - data *a = TO_DATA(p); + a = TO_DATA(p); switch (TAG(a->tag)) { case STRING_TAG: @@ -121,7 +124,7 @@ static void printValue (void *p) { case ARRAY_TAG: printStringBuf ("["); - for (int i = 0; i < LEN(a->tag); i++) { + for (i = 0; i < LEN(a->tag); i++) { printValue ((void*)((int*) a->contents)[i]); if (i != LEN(a->tag) - 1) printStringBuf (", "); } @@ -132,7 +135,7 @@ static void printValue (void *p) { printStringBuf ("`%s", de_hash (TO_SEXP(p)->tag)); if (LEN(a->tag)) { printStringBuf (" ("); - for (int i = 0; i < LEN(a->tag); i++) { + for (i = 0; i < LEN(a->tag); i++) { printValue ((void*)((int*) a->contents)[i]); if (i != LEN(a->tag) - 1) printStringBuf (", "); } @@ -147,7 +150,8 @@ static void printValue (void *p) { } extern void* Belem (void *p, int i) { - data *a = TO_DATA(p); + data *a = (data *)BOX(NULL); + a = TO_DATA(p); i = UNBOX(i); if (TAG(a->tag) == STRING_TAG) { @@ -158,8 +162,10 @@ extern void* Belem (void *p, int i) { } extern void* Bstring (void *p) { - int n = strlen (p); + int n = BOX(0); data *r = NULL; + + n = strlen (p); r = (data*) alloc (n + 1 + sizeof (int)); r->tag = STRING_TAG | (n << 3); @@ -169,7 +175,7 @@ extern void* Bstring (void *p) { } extern void* Bstringval (void *p) { - void *s; + void *s = BOX(NULL); createStringBuf (); printValue (p); @@ -182,9 +188,10 @@ extern void* Bstringval (void *p) { } extern void* Barray (int n, ...) { - va_list args; - int i = 1; - data *r = NULL; + va_list args = (va_list) BOX (NULL); + int i = BOX(0), + ai = BOX(0); + data *r = (data*) BOX (NULL); #ifdef DEBUG_PRINT printf ("Barray: create n = %d\n", n); fflush(stdout); @@ -195,8 +202,8 @@ extern void* Barray (int n, ...) { va_start(args, n); - for (i=0; icontents)[i] = ai; } @@ -206,11 +213,11 @@ extern void* Barray (int n, ...) { } extern void* Bsexp (int n, ...) { - va_list args = (va_list) BOX(NULL); + va_list args = (va_list) BOX (NULL); int i = BOX(0); int ai = BOX(0); - sexp *r = (sexp*) BOX(NULL); - data *d = (sexp*) BOX(NULL); + sexp *r = (sexp*) BOX (NULL); + data *d = (sexp*) BOX (NULL); #ifdef DEBUG_PRINT printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+1)); @@ -234,22 +241,26 @@ extern void* Bsexp (int n, ...) { } extern int Btag (void *d, int t, int n) { - data *r = TO_DATA(d); + data *r = (data*) BOX (NULL); + r = TO_DATA(d); return BOX(TAG(r->tag) == SEXP_TAG && TO_SEXP(d)->tag == t && LEN(r->tag) == n); } extern int Barray_patt (void *d, int n) { + data *r = BOX(NULL); if (UNBOXED(d)) return BOX(0); else { - data *r = TO_DATA(d); + r = TO_DATA(d); return BOX(TAG(r->tag) == ARRAY_TAG && LEN(r->tag) == n); } } extern int Bstring_patt (void *x, void *y) { + data *rx = (data *) BOX (NULL), + *ry = (data *) BOX (NULL); if (UNBOXED(x)) return BOX(0); else { - data *rx = TO_DATA(x), *ry = TO_DATA(y); + rx = TO_DATA(x); ry = TO_DATA(y); if (TAG(rx->tag) != STRING_TAG) return BOX(0); @@ -284,13 +295,13 @@ extern int Bsexp_tag_patt (void *x) { } extern void Bsta (int n, int v, void *s, ...) { - va_list args; - int i, k; - data *a; + va_list args = (va_list) BOX (NULL); + int i = 0, k = 0; + data *a = (data*) BOX (NULL); va_start(args, s); - for (i=0; i printf (char *, ...) @@ -315,10 +326,14 @@ extern void Lprintf (char *s, ...) { } extern void* Lstrcat (void *a, void *b) { - data *da = TO_DATA(a); - data *db = TO_DATA(b); - - data *d = (data *) alloc (sizeof(int) + LEN(da->tag) + LEN(db->tag) + 1); + data *da = (data*) BOX (NULL); + data *db = (data*) BOX (NULL); + data *d = (data*) BOX (NULL); + + da = TO_DATA(a); + db = TO_DATA(b); + + d = (data *) alloc (sizeof(int) + LEN(da->tag) + LEN(db->tag) + 1); d->tag = LEN(da->tag) + LEN(db->tag); @@ -329,7 +344,7 @@ extern void* Lstrcat (void *a, void *b) { } extern void Lfprintf (FILE *f, char *s, ...) { - va_list args; + va_list args = (va_list) BOX (NULL); va_start (args, s); vfprintf (f, s, args); @@ -346,7 +361,7 @@ extern void Lfclose (FILE *f) { /* Lread is an implementation of the "read" construct */ extern int Lread () { - int result; + int result = BOX(0); printf ("> "); fflush (stdout); @@ -472,7 +487,7 @@ extern size_t * gc_copy (size_t *obj); /* } */ static void copy_elements (size_t *where, size_t *from, int len) { - int i = 0; + int i = 0; void * p = NULL; for (i = 0; i < len; i++) { size_t elem = from[i]; From 94327b792190d981cb168cca0c9061c0bb498dac Mon Sep 17 00:00:00 2001 From: danyaberezun Date: Tue, 11 Dec 2018 10:22:23 +0300 Subject: [PATCH 14/19] cur --- runtime/gc_runtime.s | 110 +++++++++++++++++++++++++++++++++++++++++- runtime/runtime.c | 112 +++++++++++++++++++++++++++++++++---------- 2 files changed, 196 insertions(+), 26 deletions(-) diff --git a/runtime/gc_runtime.s b/runtime/gc_runtime.s index a22e40c68..d9a29ba0c 100644 --- a/runtime/gc_runtime.s +++ b/runtime/gc_runtime.s @@ -7,19 +7,127 @@ printf_format5: .string "LOL\n" __gc_stack_bottom: .long 0 __gc_stack_top: .long 0 + .globl __set_w2 + .globl __alloc_w1 + .globl __alloc_w2 .globl __pre_gc .globl L__gc_init .globl __gc_root_scan_stack .extern init_pool .extern __gc_test_and_copy_root .text + +__set_w2: + pushl %ebp + movl %esp, %ebp + pushl %ecx + pushl %edx + + movl 8(%ebp), %ecx + movl 12(%ebp), %edx + subl $8, %ecx + movl %edx, (%ecx) + + movl $0, %eax + pushl %ecx + pushl %edx + + movl %ebp, %esp + popl %ebp + ret + +__alloc_w2: + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %ecx + pushl %edx + pushl %esi + pushl %edi + + movl 8(%ebp), %edx + + pushl %edx + call alloc + addl $4, %esp + + pushl $1 + pushl $1 + pushl $1 + pushl $1 + pushl $1 + addl $20, %esp + + movl 12(%ebp), %ecx + addl $4, %eax + movl %ecx, (%eax) + addl $4, %eax + + popl %ebx + popl %ecx + popl %edx + popl %esi + popl %edi + + movl %ebp, %esp + popl %ebp + ret + +__alloc_w1: + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %ecx + pushl %edx + pushl %esi + pushl %edi + + movl 4(%ebp), %edx + + pushl %edx + call alloc + + pushl $1 + pushl $1 + pushl $1 + pushl $1 + pushl $1 + addl $20, %esp + + movl 8(%ebp), %ecx + movl %ecx, (%eax) + addl $4, %eax + + popl %ebx + popl %ecx + popl %edx + popl %esi + popl %edi + + movl %ebp, %esp + popl %ebp + ret + L__gc_init: movl %esp, __gc_stack_bottom addl $4, __gc_stack_bottom call init_pool ret __pre_gc: - movl %ebp, __gc_stack_top + // movl %ebp, __gc_stack_top + // ret + + // pushl %eax + // movl (%ebp), %eax + // movl %eax, __gc_stack_top + // popl %eax + + pushl %eax + movl (%ebp), %eax + addl $4, %eax + movl %eax, __gc_stack_top + popl %eax + ret __gc_root_scan_stack: diff --git a/runtime/runtime.c b/runtime/runtime.c index 561acd452..d6c46dc06 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -8,7 +8,7 @@ # include # include -// # define DEBUG_PRINT 1 +# define DEBUG_PRINT 1 # define STRING_TAG 0x00000001 # define ARRAY_TAG 0x00000003 @@ -34,17 +34,20 @@ typedef struct { data contents; } sexp; -static void* alloc (size_t); +extern void* alloc (size_t); extern int Blength (void *p) { - data *a = TO_DATA(p); + data *a = (char*) BOX (NULL); + a = TO_DATA(p); return BOX(LEN(a->tag)); } char* de_hash (int n) { - static char *chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNJPQRSTUVWXYZ"; - static char buf[6]; - char *p = &buf[5]; + static char *chars = (char*) BOX (NULL); + static char buf[6] = {0,0,0,0,0,0}; + char *p = (char*) BOX (NULL); + chars = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNJPQRSTUVWXYZ"; + p = &buf[5]; #ifdef DEBUG_PRINT printf ("de_hash: tag: %d\n", n); @@ -161,10 +164,21 @@ extern void* Belem (void *p, int i) { return (void*) ((int*) a->contents)[i]; } + + + +extern void* __alloc_w1 (size_t size, int tag); +extern void* __alloc_w2 (size_t size, int tag); +extern void* __set_w2 (void *p , int tag); + + + extern void* Bstring (void *p) { int n = BOX(0); data *r = NULL; + __pre_gc () ; + n = strlen (p); r = (data*) alloc (n + 1 + sizeof (int)); @@ -173,6 +187,19 @@ extern void* Bstring (void *p) { return r->contents; } +/* extern void* Bstring (void *p) { */ +/* int n = BOX(0); */ +/* void *r = NULL; */ + +/* printf ("BSTRING!\n"); */ + +/* n = strlen (p); */ +/* r = __alloc_w1 (n + 1 + sizeof (int), STRING_TAG | (n << 3)); */ + +/* strncpy (r, p, n + 1); */ + +/* return r; */ +/* } */ extern void* Bstringval (void *p) { void *s = BOX(NULL); @@ -192,6 +219,9 @@ extern void* Barray (int n, ...) { int i = BOX(0), ai = BOX(0); data *r = (data*) BOX (NULL); + + __pre_gc () ; + #ifdef DEBUG_PRINT printf ("Barray: create n = %d\n", n); fflush(stdout); @@ -212,32 +242,62 @@ extern void* Barray (int n, ...) { return r->contents; } +/* extern void* Bsexp (int n, ...) { */ +/* va_list args = (va_list) BOX (NULL); */ +/* int i = BOX(0); */ +/* int ai = BOX(0); */ +/* sexp *r = (sexp*) BOX (NULL); */ +/* data *d = (sexp*) BOX (NULL); */ + +/* __pre_gc () ; */ + +/* #ifdef DEBUG_PRINT */ +/* printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+1)); */ +/* #endif */ +/* r = (sexp*) alloc (sizeof(int) * (n+1)); */ +/* d = &(r->contents); */ + +/* d->tag = SEXP_TAG | ((n-1) << 3); */ + +/* va_start(args, n); */ + +/* for (i=0; icontents)[i] = ai; */ +/* } */ + +/* r->tag = va_arg(args, int); */ +/* va_end(args); */ + +/* return d->contents; */ +/* } */ extern void* Bsexp (int n, ...) { va_list args = (va_list) BOX (NULL); int i = BOX(0); - int ai = BOX(0); - sexp *r = (sexp*) BOX (NULL); - data *d = (sexp*) BOX (NULL); + int ai = BOX(0), tag = BOX(0); + void *r = (void*) BOX (NULL); + size_t size = sizeof(int) * (n+1); + // printf("Bsexp: allocate %zu!\n", size); -#ifdef DEBUG_PRINT - printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+1)); -#endif - r = (sexp*) alloc (sizeof(int) * (n+1)); - d = &(r->contents); - - d->tag = SEXP_TAG | ((n-1) << 3); + __pre_gc (); + + tag = SEXP_TAG | ((n-1) << 3); + r = __alloc_w2 (size, tag); + // Lwrite(r); + // d = &(r->contents); + // d->tag = SEXP_TAG | ((n-1) << 3); va_start(args, n); - for (i=0; icontents)[i] = ai; + ((int*)r)[i] = ai; } - r->tag = va_arg(args, int); + __set_w2 (r, va_arg(args, int)); va_end(args); - return d->contents; + return r; } extern int Btag (void *d, int t, int n) { @@ -333,6 +393,8 @@ extern void* Lstrcat (void *a, void *b) { da = TO_DATA(a); db = TO_DATA(b); + __pre_gc () ; + d = (data *) alloc (sizeof(int) + LEN(da->tag) + LEN(db->tag) + 1); d->tag = LEN(da->tag) + LEN(db->tag); @@ -550,7 +612,7 @@ extern size_t * gc_copy (size_t *obj) { return obj; } - if (!IN_PASSIVE_SPACE(current)) { + if (!IN_PASSIVE_SPACE(current) && current != to_space.end) { #ifdef DEBUG_PRINT printf("ERROR: gc_copy: out-of-space %x %x %x\n", current, to_space.begin, to_space.end); fflush(stdout); @@ -705,11 +767,11 @@ static void * gc (size_t size) { __gc_swap_spaces (); from_space.current = current + size; - return current; + return (void *) current; } -static void * alloc (size_t size) { - void * p = BOX(NULL); +extern void * alloc (size_t size) { + void * p = (void*)BOX(NULL); if (from_space.current + size < from_space.end) { #ifdef DEBUG_PRINT printf("alloc: current: %x %zu", from_space.current, size); @@ -724,6 +786,6 @@ static void * alloc (size_t size) { #ifdef DEBUG_PRINT printf("alloc: call gc: %zu\n", size); #endif - __pre_gc () ; + // __pre_gc () ; return gc (size); } From 576beac0dc4fdfaa6929ffc40ead4d5082c39474 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 12 Dec 2018 12:42:04 +0300 Subject: [PATCH 15/19] fix: __pre_gc and __post_gc functions; remove extra --- runtime/Makefile | 4 +- runtime/gc_runtime.s | 161 ++++++++-------------------------- runtime/runtime.c | 201 +++++++++++-------------------------------- 3 files changed, 89 insertions(+), 277 deletions(-) diff --git a/runtime/Makefile b/runtime/Makefile index 906aa571d..457906978 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -2,10 +2,10 @@ all: gc_runtime.o runtime.o ar rc runtime.a gc_runtime.o runtime.o gc_runtime.o: gc_runtime.s - gcc -g -m32 -c gc_runtime.s + gcc -g -fstack-protector-all -m32 -c gc_runtime.s runtime.o: runtime.c - gcc -g -m32 -c runtime.c + gcc -g -fstack-protector-all -m32 -c runtime.c clean: rm -f *.a *.o *~ diff --git a/runtime/gc_runtime.s b/runtime/gc_runtime.s index d9a29ba0c..e10fcc71b 100644 --- a/runtime/gc_runtime.s +++ b/runtime/gc_runtime.s @@ -7,144 +7,56 @@ printf_format5: .string "LOL\n" __gc_stack_bottom: .long 0 __gc_stack_top: .long 0 - .globl __set_w2 - .globl __alloc_w1 - .globl __alloc_w2 .globl __pre_gc + .globl __post_gc .globl L__gc_init .globl __gc_root_scan_stack .extern init_pool - .extern __gc_test_and_copy_root + .extern gc_test_and_copy_root .text -__set_w2: - pushl %ebp - movl %esp, %ebp - pushl %ecx - pushl %edx - - movl 8(%ebp), %ecx - movl 12(%ebp), %edx - subl $8, %ecx - movl %edx, (%ecx) - - movl $0, %eax - pushl %ecx - pushl %edx - - movl %ebp, %esp - popl %ebp - ret - -__alloc_w2: - pushl %ebp - movl %esp, %ebp - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi - pushl %edi - - movl 8(%ebp), %edx - - pushl %edx - call alloc - addl $4, %esp - - pushl $1 - pushl $1 - pushl $1 - pushl $1 - pushl $1 - addl $20, %esp - - movl 12(%ebp), %ecx - addl $4, %eax - movl %ecx, (%eax) - addl $4, %eax - - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - - movl %ebp, %esp - popl %ebp - ret - -__alloc_w1: - pushl %ebp - movl %esp, %ebp - pushl %ebx - pushl %ecx - pushl %edx - pushl %esi - pushl %edi - - movl 4(%ebp), %edx - - pushl %edx - call alloc - - pushl $1 - pushl $1 - pushl $1 - pushl $1 - pushl $1 - addl $20, %esp - - movl 8(%ebp), %ecx - movl %ecx, (%eax) - addl $4, %eax - - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - - movl %ebp, %esp - popl %ebp - ret - L__gc_init: movl %esp, __gc_stack_bottom addl $4, __gc_stack_bottom call init_pool ret + // if __gc_stack_top is equal to 0 + // then set __gc_stack_top to %ebp + // else return __pre_gc: - // movl %ebp, __gc_stack_top - // ret - - // pushl %eax - // movl (%ebp), %eax - // movl %eax, __gc_stack_top - // popl %eax + pushl %eax + movl __gc_stack_top, %eax + cmpl $0, %eax + jne __pre_gc_2 + movl %ebp, %eax + // addl $8, %eax + movl %eax, __gc_stack_top +__pre_gc_2: + popl %eax + ret - pushl %eax - movl (%ebp), %eax - addl $4, %eax - movl %eax, __gc_stack_top - popl %eax - - ret + // if __gc_stack_top has been set by the caller + // (i.e. it is equal to its %ebp) + // then set __gc_stack_top to 0 + // else return +__post_gc: + pushl %eax + movl __gc_stack_top, %eax + cmpl %eax, %ebp + jnz __post_gc2 + movl $0, __gc_stack_top +__post_gc2: + popl %eax + ret + // Scan stack for roots + // strting from __gc_stack_top + // till __gc_stack_bottom __gc_root_scan_stack: - pushl %ebp - movl %esp, %ebp - pushl %ebx - pushl %edx - -// pushl __gc_stack_top -// call Lwrite2 -// addl $4, %esp -// pushl __gc_stack_bottom -// call Lwrite2 -// addl $4, %esp - -// movl %esp, __gc_stack_top -// movl %esp, %eax + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %edx movl __gc_stack_top, %eax jmp next @@ -184,9 +96,8 @@ loop2: jnz next gc_run_t: pushl %eax -// pushl (%eax) pushl %eax - call __gc_test_and_copy_root + call gc_test_and_copy_root addl $4, %esp popl %eax diff --git a/runtime/runtime.c b/runtime/runtime.c index d6c46dc06..90cb33ce1 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -8,7 +8,7 @@ # include # include -# define DEBUG_PRINT 1 +// # define DEBUG_PRINT 1 # define STRING_TAG 0x00000001 # define ARRAY_TAG 0x00000003 @@ -164,15 +164,6 @@ extern void* Belem (void *p, int i) { return (void*) ((int*) a->contents)[i]; } - - - -extern void* __alloc_w1 (size_t size, int tag); -extern void* __alloc_w2 (size_t size, int tag); -extern void* __set_w2 (void *p , int tag); - - - extern void* Bstring (void *p) { int n = BOX(0); data *r = NULL; @@ -184,25 +175,16 @@ extern void* Bstring (void *p) { r->tag = STRING_TAG | (n << 3); strncpy (r->contents, p, n + 1); + + __post_gc(); return r->contents; } -/* extern void* Bstring (void *p) { */ -/* int n = BOX(0); */ -/* void *r = NULL; */ - -/* printf ("BSTRING!\n"); */ - -/* n = strlen (p); */ -/* r = __alloc_w1 (n + 1 + sizeof (int), STRING_TAG | (n << 3)); */ - -/* strncpy (r, p, n + 1); */ - -/* return r; */ -/* } */ extern void* Bstringval (void *p) { void *s = BOX(NULL); + + __pre_gc () ; createStringBuf (); printValue (p); @@ -211,6 +193,8 @@ extern void* Bstringval (void *p) { deleteStringBuf (); + __post_gc (); + return s; } @@ -220,8 +204,8 @@ extern void* Barray (int n, ...) { ai = BOX(0); data *r = (data*) BOX (NULL); - __pre_gc () ; - + __pre_gc (); + #ifdef DEBUG_PRINT printf ("Barray: create n = %d\n", n); fflush(stdout); @@ -239,65 +223,42 @@ extern void* Barray (int n, ...) { va_end(args); + __post_gc(); + return r->contents; } -/* extern void* Bsexp (int n, ...) { */ -/* va_list args = (va_list) BOX (NULL); */ -/* int i = BOX(0); */ -/* int ai = BOX(0); */ -/* sexp *r = (sexp*) BOX (NULL); */ -/* data *d = (sexp*) BOX (NULL); */ - -/* __pre_gc () ; */ - -/* #ifdef DEBUG_PRINT */ -/* printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+1)); */ -/* #endif */ -/* r = (sexp*) alloc (sizeof(int) * (n+1)); */ -/* d = &(r->contents); */ - -/* d->tag = SEXP_TAG | ((n-1) << 3); */ - -/* va_start(args, n); */ - -/* for (i=0; icontents)[i] = ai; */ -/* } */ - -/* r->tag = va_arg(args, int); */ -/* va_end(args); */ - -/* return d->contents; */ -/* } */ extern void* Bsexp (int n, ...) { va_list args = (va_list) BOX (NULL); int i = BOX(0); - int ai = BOX(0), tag = BOX(0); - void *r = (void*) BOX (NULL); - size_t size = sizeof(int) * (n+1); - // printf("Bsexp: allocate %zu!\n", size); + int ai = BOX(0); + size_t * p = NULL; + sexp *r = (sexp*) BOX (NULL); + data *d = (sexp*) BOX (NULL); - __pre_gc (); + __pre_gc () ; - tag = SEXP_TAG | ((n-1) << 3); - r = __alloc_w2 (size, tag); - // Lwrite(r); - // d = &(r->contents); - // d->tag = SEXP_TAG | ((n-1) << 3); +#ifdef DEBUG_PRINT + printf("Bsexp: allocate %zu!\n",sizeof(int) * (n+1)); +#endif + r = (sexp*) alloc (sizeof(int) * (n+1)); + d = &(r->contents); + + d->tag = SEXP_TAG | ((n-1) << 3); va_start(args, n); - for (i = 0; i < n-1; i++) { + for (i=0; icontents)[i] = ai; } - __set_w2 (r, va_arg(args, int)); + r->tag = va_arg(args, int); va_end(args); - return r; + __post_gc(); + + return d->contents; } extern int Btag (void *d, int t, int n) { @@ -402,6 +363,8 @@ extern void* Lstrcat (void *a, void *b) { strcpy (d->contents, da->contents); strcat (d->contents, db->contents); + __post_gc(); + return d->contents; } @@ -440,52 +403,16 @@ extern int Lwrite (int n) { return 0; } -extern int Lwrite2 (size_t* n) { - printf ("%x\n", n); - fflush (stdout); - - return 0; -} - /* GC starts here */ extern const size_t __gc_data_end, __gc_data_start; -extern size_t __gc_stack_bottom, __gc_stack_top; extern void L__gc_init (); extern void __pre_gc (); +extern void __post_gc (); extern void __gc_root_scan_stack (); - -/* extern const void * __gc_data_end, * __gc_data_start; */ - -/* extern void __gc_root_scan_data () { */ -/* void * p = &__gc_data_start; */ - -/* printf ("Start, end: %d, %d\n", &__gc_data_start, &__gc_data_end); */ - -/* while (p != &__gc_data_end) { */ -/* if (!UNBOXED(* (size_t *) p)) printf ("Root: %d\n", p); */ -/* p = p + sizeof(size_t); */ -/* } */ -/* } */ - -extern char __executable_start; -extern char __etext; - -/* extern void Ltest () { */ -/* printf("\n"); */ -/* printf("STA 0x%lx\n", (unsigned long)&__executable_start); */ -/* printf("END 0x%lx\n", (unsigned long)&__etext); */ -/* __gc_root_scan_data (); */ -/* __gc_root_scan_stack (); */ - -/* // printf("STA 0x%lx\n", (unsigned long)&__executable_start); */ -/* // printf("END 0x%lx\n", (unsigned long)&__etext); */ -/* // printf("RET 0x%lx\n\n", __builtin_return_address(0)); */ -/* } */ - /* ======================================== */ /* Mark-and-copy */ /* ======================================== */ @@ -510,7 +437,7 @@ static void swap (size_t ** a, size_t ** b) { *b = t; } -static void __gc_swap_spaces (void) { +static void gc_swap_spaces (void) { swap (&from_space.begin, &to_space.begin); swap (&from_space.end , &to_space.end ); from_space.current = current; @@ -531,36 +458,16 @@ static void __gc_swap_spaces (void) { extern size_t * gc_copy (size_t *obj); -/* static void copy_elements (size_t *where, size_t *from, int len) { */ -/* int i = 0; */ -/* void * p = NULL; */ -/* for (i = 0; i < len; i++) { */ -/* size_t elem = from[i]; */ -/* // if (UNBOXED(elem)) *++where = elem; */ -/* if (!IS_VALID_HEAP_POINTER(elem)) *++where = elem; */ -/* else { */ -/* // *++where = gc_copy ((size_t*) elem); */ -/* p = gc_copy ((size_t*) elem); */ -/* printf ("copy_elements: fix %x --> %x\n", *where, p); */ -/* *where = p; */ -/* where ++; */ -/* } */ -/* } */ -/* } */ - static void copy_elements (size_t *where, size_t *from, int len) { int i = 0; void * p = NULL; for (i = 0; i < len; i++) { size_t elem = from[i]; - // if (UNBOXED(elem)) *++where = elem; if (!IS_VALID_HEAP_POINTER(elem)) { - // *++where = elem; *where = elem; where++; } else { - // *++where = gc_copy ((size_t*) elem); p = gc_copy ((size_t*) elem); *where = p; #ifdef DEBUG_PRINT @@ -572,15 +479,11 @@ static void copy_elements (size_t *where, size_t *from, int len) { } static void extend_spaces (void) { - /* void *from_e = mmap(from_space.end, SPACE_SIZE, PROT_READ | PROT_WRITE, */ - /* MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); */ - /* void *to_e = mmap(to_space.end , SPACE_SIZE, PROT_READ | PROT_WRITE, */ - /* MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); */ void *p1 = mremap(from_space.begin, SPACE_SIZE, 2*SPACE_SIZE, 0); void *p2 = mremap(to_space.begin , SPACE_SIZE, 2*SPACE_SIZE, 0); if (p1 == MAP_FAILED || p2 == MAP_FAILED) { perror("EROOR: extend_spaces: mmap failed\n"); - exit(7); + exit (1); } #ifdef DEBUG_PRINT printf ("extend: %x %x %x %x\n", p1, p2, from_space.begin, to_space.begin); @@ -618,9 +521,7 @@ extern size_t * gc_copy (size_t *obj) { fflush(stdout); #endif perror("ERROR: gc_copy: out-of-space\n"); - exit (6); - // extend_spaces (); - // assert (IN_PASSIVE_SPACE(current)); + exit (1); } if (IS_FORWARD_PTR(d->tag)) { @@ -644,8 +545,9 @@ extern size_t * gc_copy (size_t *obj) { current += (LEN(d->tag) + 1) * sizeof (int); *copy = d->tag; copy++; + i = LEN(d->tag); d->tag = (int) copy; - copy_elements (copy, obj, LEN(d->tag)); + copy_elements (copy, obj, i); break; case STRING_TAG: @@ -653,7 +555,6 @@ extern size_t * gc_copy (size_t *obj) { printf ("gc_copy:string_tag; len = %d\n", LEN(d->tag) + 1); fflush(stdout); #endif - // current += (LEN(d->tag) + 1) * sizeof (int); current += LEN(d->tag) * sizeof(char) + sizeof (int); *copy = d->tag; copy++; @@ -676,7 +577,6 @@ extern size_t * gc_copy (size_t *obj) { *copy = s->contents.tag; copy++; i = LEN(s->contents.tag); - // s->contents.tag = (int) copy; d->tag = (int) copy; copy_elements (copy, obj, i); break; @@ -687,7 +587,7 @@ extern size_t * gc_copy (size_t *obj) { fflush(stdout); #endif perror ("ERROR: gc_copy: weird tag"); - exit(5); + exit (1); } #ifdef DEBUG_PRINT printf("gc_copy: %x (%x) -> %x (%x); new-current = %x\n", obj, objj, copy, newobjj, current); @@ -696,19 +596,19 @@ extern size_t * gc_copy (size_t *obj) { return copy; } -extern void __gc_test_and_copy_root (size_t ** root) { +extern void gc_test_and_copy_root (size_t ** root) { if (IS_VALID_HEAP_POINTER(*root)) { #ifdef DEBUG_PRINT - printf ("__gc_test_and_copy_root: root %x %x\n", root, *root); + printf ("gc_test_and_copy_root: root %x %x\n", root, *root); #endif *root = gc_copy (*root); } } -extern void __gc_root_scan_data (void) { +extern void gc_root_scan_data (void) { size_t * p = &__gc_data_start; while (p != &__gc_data_end) { - __gc_test_and_copy_root (p); + gc_test_and_copy_root (p); p++; } } @@ -721,7 +621,7 @@ extern void init_pool (void) { if (to_space.begin == MAP_FAILED || from_space.begin == MAP_FAILED) { perror("EROOR: init_pool: mmap failed\n"); - exit(1); + exit (1); } from_space.current = from_space.begin; from_space.end = from_space.begin + SPACE_SIZE; @@ -738,17 +638,17 @@ static int free_pool (pool * p) { static void * gc (size_t size) { current = to_space.begin; #ifdef DEBUG_PRINT - printf("gc: current: %x; to_space.b = %x; to_space.e = %x; f_space.b = %x; f_space.e = %x\n", + printf("\ngc: current: %x; to_space.b = %x; to_space.e = %x; f_space.b = %x; f_space.e = %x\n", current, to_space.begin, to_space.end, from_space.begin, from_space.end); #endif - __gc_root_scan_data (); + gc_root_scan_data (); #ifdef DEBUG_PRINT printf("gc: data is scanned\n"); #endif __gc_root_scan_stack (); if (!IN_PASSIVE_SPACE(current)) { perror ("ASSERT: !IN_PASSIVE_SPACE(current)\n"); - exit(1); + exit (1); } if (current + size >= to_space.end) { @@ -761,12 +661,14 @@ static void * gc (size_t size) { #endif assert (IN_PASSIVE_SPACE(current)); assert (current + size < to_space.end); - // perror ("ERROR: gc: out of memory\n"); - // exit(4); } - __gc_swap_spaces (); + gc_swap_spaces (); from_space.current = current + size; +#ifdef DEBUG_PRINT + printf ("gc: end: (allocate!) return %x; from_space.current %x; from_space.end \n\n", + current, from_space.current, from_space.end); +#endif return (void *) current; } @@ -786,6 +688,5 @@ extern void * alloc (size_t size) { #ifdef DEBUG_PRINT printf("alloc: call gc: %zu\n", size); #endif - // __pre_gc () ; return gc (size); } From 516a3e190bac4e2fe67bf4722b53287b438d3ec7 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 12 Dec 2018 12:42:38 +0300 Subject: [PATCH 16/19] add locals initialization --- src/X86.ml | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/X86.ml b/src/X86.ml index 4fb198f4f..ec08959f3 100644 --- a/src/X86.ml +++ b/src/X86.ml @@ -54,6 +54,7 @@ type instr = (* arithmetic correction: or 0x0001 *) | Or1 of opnd (* arithmetic correction: shl 1 *) | Sal1 of opnd (* arithmetic correction: shr 1 *) | Sar1 of opnd + | Repmovsl (* Instruction printer *) let show instr = @@ -93,6 +94,7 @@ let show instr = | Or1 s -> Printf.sprintf "\torl\t$0x0001,\t%s" (opnd s) | Sal1 s -> Printf.sprintf "\tsall\t%s" (opnd s) | Sar1 s -> Printf.sprintf "\tsarl\t%s" (opnd s) + | Repmovsl -> Printf.sprintf "\trep movsl\t" (* Opening stack machine to use instructions without fully qualified names *) open SM @@ -290,14 +292,20 @@ let compile env code = | BEGIN (f, a, l) -> let env = env#enter f a l in - env, [Push ebp; Mov (esp, ebp); Binop ("-", M ("$" ^ env#lsize), esp)] + env, [Push ebp; Mov (esp, ebp); Binop ("-", M ("$" ^ env#lsize), esp); + Mov (esp, edi); + Mov (M "$filler", esi); + Mov (M ("$" ^ (env#allocated_size)), ecx); + Repmovsl + ] | END -> - env, [Label env#epilogue; + env#endfunc, [Label env#epilogue; Mov (ebp, esp); Pop ebp; Ret; - Meta (Printf.sprintf "\t.set\t%s,\t%d" env#lsize (env#allocated * word_size)) + Meta (Printf.sprintf "\t.set\t%s,\t%d" env#lsize (env#allocated * word_size)); + Meta (Printf.sprintf "\t.set\t%s,\t%d" env#allocated_size env#allocated) ] | RET b -> @@ -388,6 +396,14 @@ class env = val fname = "" (* function name *) val stackmap = M.empty (* labels to stack map *) val barrier = false (* barrier condition *) + val max_locals_size = 0 + + method max_locals_size = max_locals_size + + method endfunc = + if stack_slots > max_locals_size + then {< max_locals_size = stack_slots >} + else self method show_stack = GT.show(list) (GT.show(opnd)) stack @@ -481,7 +497,9 @@ class env = method strings = M.bindings stringm (* gets a number of stack positions allocated *) - method allocated = stack_slots + method allocated = stack_slots + + method allocated_size = Printf.sprintf "LS%s_SIZE" fname (* enters a function *) method enter f a l = @@ -532,12 +550,14 @@ let genasm (ds, stmt) = ((LABEL "main") :: (BEGIN ("main", [], [])) :: SM.compile (ds, stmt)) in let gc_start, gc_end = "__gc_data_start", "__gc_data_end" in - let data = [Meta "\t.data"; Meta (Printf.sprintf "\t.globl\t%s" gc_start); Meta (Printf.sprintf "\t.globl\t%s" gc_end)] @ + let data = [Meta "\t.data"; + Meta (Printf.sprintf "filler:\t.fill\t%d, 4, 1" env#max_locals_size); + Meta (Printf.sprintf "\t.globl\t%s" gc_start); Meta (Printf.sprintf "\t.globl\t%s" gc_end)] @ [Meta (Printf.sprintf "%s:" gc_start)] @ (List.map (fun s -> Meta (Printf.sprintf "%s:\t.int\t1" s )) env#globals) @ [Meta (Printf.sprintf "%s:" gc_end)] @ (List.map (fun (s, v) -> Meta (Printf.sprintf "%s:\t.string\t\"%s\"" v s)) env#strings) - in + in let asm = Buffer.create 1024 in List.iter (fun i -> Buffer.add_string asm (Printf.sprintf "%s\n" @@ show i)) From aac34c34ea8527e25aa4b38ae40814cd0bb57097 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 12 Dec 2018 19:32:46 +0300 Subject: [PATCH 17/19] fix bug with strings; Now passes all the tests --- runtime/runtime.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index 90cb33ce1..20b7c3a04 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -228,6 +228,10 @@ extern void* Barray (int n, ...) { return r->contents; } +extern int __IS_VALID_HEAP_POINTER(size_t *p); +extern int __IN_PASSIVE_SPACE(size_t * p); +extern int __IS_FORWARD_PTR(size_t * p); + extern void* Bsexp (int n, ...) { va_list args = (va_list) BOX (NULL); int i = BOX(0); @@ -243,6 +247,7 @@ extern void* Bsexp (int n, ...) { #endif r = (sexp*) alloc (sizeof(int) * (n+1)); d = &(r->contents); + r->tag = 0; d->tag = SEXP_TAG | ((n-1) << 3); @@ -250,6 +255,13 @@ extern void* Bsexp (int n, ...) { for (i=0; icontents)[i] = ai; } @@ -456,6 +468,16 @@ static void gc_swap_spaces (void) { # define IS_FORWARD_PTR(p) \ (!UNBOXED(p) && IN_PASSIVE_SPACE(p)) +int __IS_VALID_HEAP_POINTER(size_t *p) { + return IS_VALID_HEAP_POINTER(p); +} +int __IN_PASSIVE_SPACE(size_t * p) { + return IN_PASSIVE_SPACE(p); +} +int __IS_FORWARD_PTR(size_t * p) { + return IS_FORWARD_PTR(p); +} + extern size_t * gc_copy (size_t *obj); static void copy_elements (size_t *where, size_t *from, int len) { @@ -559,7 +581,7 @@ extern size_t * gc_copy (size_t *obj) { *copy = d->tag; copy++; d->tag = (int) copy; - strcpy (©[1], (char*) obj); + strcpy (©[0], (char*) obj); break; case SEXP_TAG : From dde29143db8d947d233cd96e9aa2290eeab28cb1 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 12 Dec 2018 19:35:31 +0300 Subject: [PATCH 18/19] rm extra code --- runtime/runtime.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index 20b7c3a04..8cbf6b5f0 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -228,10 +228,6 @@ extern void* Barray (int n, ...) { return r->contents; } -extern int __IS_VALID_HEAP_POINTER(size_t *p); -extern int __IN_PASSIVE_SPACE(size_t * p); -extern int __IS_FORWARD_PTR(size_t * p); - extern void* Bsexp (int n, ...) { va_list args = (va_list) BOX (NULL); int i = BOX(0); @@ -257,11 +253,6 @@ extern void* Bsexp (int n, ...) { ai = va_arg(args, int); p = (size_t*) ai; - if (!UNBOXED(p) && __IN_PASSIVE_SPACE(p) && __IS_FORWARD_PTR((size_t*)*(p-1))){ - printf ("Bsexp: %p\n", p); - fflush(stdout); - } - ((int*)d->contents)[i] = ai; } @@ -468,16 +459,6 @@ static void gc_swap_spaces (void) { # define IS_FORWARD_PTR(p) \ (!UNBOXED(p) && IN_PASSIVE_SPACE(p)) -int __IS_VALID_HEAP_POINTER(size_t *p) { - return IS_VALID_HEAP_POINTER(p); -} -int __IN_PASSIVE_SPACE(size_t * p) { - return IN_PASSIVE_SPACE(p); -} -int __IS_FORWARD_PTR(size_t * p) { - return IS_FORWARD_PTR(p); -} - extern size_t * gc_copy (size_t *obj); static void copy_elements (size_t *where, size_t *from, int len) { From 1abae31bdfb3195bc1ab88876a282860d3975a12 Mon Sep 17 00:00:00 2001 From: danyabeerzun Date: Wed, 12 Dec 2018 19:39:29 +0300 Subject: [PATCH 19/19] improve space extension --- runtime/runtime.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/runtime.c b/runtime/runtime.c index 8cbf6b5f0..7e379befe 100644 --- a/runtime/runtime.c +++ b/runtime/runtime.c @@ -654,7 +654,7 @@ static void * gc (size_t size) { exit (1); } - if (current + size >= to_space.end) { + while (current + size >= to_space.end) { #ifdef DEBUG_PRINT printf ("gc pre-extend_spaces : %x %x %x \n", current, size, to_space.end); #endif @@ -662,9 +662,9 @@ static void * gc (size_t size) { #ifdef DEBUG_PRINT printf ("gc post-extend_spaces: %x %x %x \n", current, size, to_space.end); #endif - assert (IN_PASSIVE_SPACE(current)); - assert (current + size < to_space.end); } + assert (IN_PASSIVE_SPACE(current)); + assert (current + size < to_space.end); gc_swap_spaces (); from_space.current = current + size;