summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--icompact.s2192
-rw-r--r--icopy.s1024
-rw-r--r--ifileIO3.s744
-rw-r--r--imark.s1880
-rw-r--r--scon.c843
-rw-r--r--scon.h14
-rw-r--r--uwrite_heap.c109
7 files changed, 6806 insertions, 0 deletions
diff --git a/icompact.s b/icompact.s
new file mode 100644
index 0000000..895aa73
--- /dev/null
+++ b/icompact.s
@@ -0,0 +1,2192 @@
+/ mark used nodes and pointers in argument parts and link backward pointers
+
+ movl heap_size_33,d0
+ shl $5,d0
+ movl d0,heap_size_32_33
+
+ movl caf_list,d0
+ test d0,d0
+ je end_mark_cafs
+
+mark_cafs_lp:
+ pushl -4(d0)
+ lea 4(d0),a2
+ movl (d0),d0
+ lea (a2,d0,4),a0
+ movl a0,end_vector
+
+ call mark_stack_nodes
+
+ popl d0
+ test d0,d0
+ jne mark_cafs_lp
+
+end_mark_cafs:
+ movl stack_p,a2
+
+ movl stack_top,a0
+ movl a0,end_vector
+ call mark_stack_nodes
+
+#ifdef MEASURE_GC
+ call add_mark_compact_garbage_collect_time
+#endif
+
+ jmp compact_heap
+
+mark_record:
+ subl $258,a2
+ je mark_record_2
+ jb mark_record_1
+
+mark_record_3:
+ movzwl -2+2(d0),a2
+ subl $1,a2
+ jb mark_record_3_bb
+ je mark_record_3_ab
+ dec a2
+ je mark_record_3_aab
+ jmp mark_hnf_3
+
+mark_record_3_bb:
+ movl 8-4(a0),a1
+ subl $4,a0
+
+ movl neg_heap_p3,d0
+ addl a1,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,a2
+ andl $31*4,d0
+ shrl $7,a2
+ movl bit_set_table(d0),d0
+ orl d0,(a4,a2,4)
+#else
+ shrl $2,d0
+ bts d0,(a4)
+#endif
+
+ cmpl a0,a1
+ ja mark_next_node
+
+#ifdef NO_BIT_INSTRUCTIONS
+ add d0,d0
+ jne bit_in_same_word1
+ inc a2
+ mov $1,d0
+bit_in_same_word1:
+ testl (a4,a2,4),d0
+ je not_yet_linked_bb
+#else
+ inc d0
+ bts d0,(a4)
+ jnc not_yet_linked_bb
+#endif
+ movl neg_heap_p3,d0
+ addl a0,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ addl $2*4,d0
+ movl d0,a2
+ andl $31*4,d0
+ shrl $7,a2
+ movl bit_set_table(d0),d0
+ orl d0,(a4,a2,4)
+#else
+ shrl $2,d0
+ addl $2,d0
+ bts d0,(a4)
+not_yet_linked_bb:
+#endif
+ movl (a1),a2
+ lea 8+2+1(a0),d0
+ movl a2,8(a0)
+ movl d0,(a1)
+ jmp mark_next_node
+
+#ifdef NO_BIT_INSTRUCTIONS
+not_yet_linked_bb:
+ orl d0,(a4,a2,4)
+ movl (a1),a2
+ lea 8+2+1(a0),d0
+ movl a2,8(a0)
+ movl d0,(a1)
+ jmp mark_next_node
+#endif
+
+mark_record_3_ab:
+ movl 4(a0),a1
+
+ movl neg_heap_p3,d0
+ addl a1,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,a2
+ andl $31*4,d0
+ shrl $7,a2
+ movl bit_set_table(d0),d0
+ orl d0,(a4,a2,4)
+#else
+ shr $2,d0
+ bts d0,(a4)
+#endif
+ cmpl a0,a1
+ ja mark_hnf_1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ add d0,d0
+ jne bit_in_same_word2
+ inc a2
+ mov $1,d0
+bit_in_same_word2:
+ testl (a4,a2,4),d0
+ je not_yet_linked_ab
+#else
+ inc d0
+ bts d0,(a4)
+ jnc not_yet_linked_ab
+#endif
+
+ movl neg_heap_p3,d0
+ addl a0,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ addl $4,d0
+ movl d0,a2
+ andl $31*4,d0
+ shrl $7,a2
+ movl bit_set_table(d0),d0
+ orl d0,(a4,a2,4)
+#else
+ shr $2,d0
+ inc d0
+ bts d0,(a4)
+not_yet_linked_ab:
+#endif
+
+ movl (a1),a2
+ lea 4+2+1(a0),d0
+ movl a2,4(a0)
+ movl d0,(a1)
+ jmp mark_hnf_1
+
+#ifdef NO_BIT_INSTRUCTIONS
+not_yet_linked_ab:
+ orl d0,(a4,a2,4)
+ movl (a1),a2
+ lea 4+2+1(a0),d0
+ movl a2,4(a0)
+ movl d0,(a1)
+ jmp mark_hnf_1
+#endif
+
+mark_record_3_aab:
+ movl 4(a0),a1
+
+ movl neg_heap_p3,d0
+ addl a1,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,a2
+ andl $31*4,d0
+ shrl $7,a2
+ movl bit_set_table(d0),d0
+ testl (a4,a2,4),d0
+ jne shared_argument_part
+ orl d0,(a4,a2,4)
+#else
+ shr $2,d0
+ bts d0,(a4)
+ jc shared_argument_part
+#endif
+ addl $2,(a0)
+ movl a3,4(a0)
+ addl $4,a0
+
+ movl (a1),a3
+ movl a0,(a1)
+ movl a3,a0
+ lea 1(a1),a3
+ jmp mark_node
+
+mark_record_2:
+/ movzwl -2+2(d0),a2
+/ cmp $1,a2
+ cmpw $1,-2+2(d0)
+ ja mark_hnf_2
+ je mark_hnf_1
+ subl $4,a0
+ jmp mark_next_node
+
+mark_record_1:
+/ movzwl -2+2(d0),a2
+/ test a2,a2
+ cmpw $0,-2+2(d0)
+ jne mark_hnf_1
+ subl $4,a0
+ jmp mark_next_node
+
+mark_stack_nodes3:
+ pop a2
+
+ movl a0,-4(a2)
+ jmp mark_stack_nodes
+
+mark_stack_nodes2:
+ pop a2
+
+mark_stack_nodes1:
+ movl (a0),d1
+ leal 1-4(a2),d0
+ movl d1,-4(a2)
+ movl d0,(a0)
+
+mark_stack_nodes:
+ cmpl end_vector,a2
+ je end_mark_nodes
+
+ movl (a2),a0
+ addl $4,a2
+
+ movl neg_heap_p3,d0
+ addl a0,d0
+#ifdef SHARE_CHAR_INT
+ cmpl heap_size_32_33,d0
+ jnc mark_stack_nodes
+#endif
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,d1
+ andl $31*4,d0
+
+ shrl $7,d1
+
+ movl bit_set_table(d0),d0
+
+ movl (a4,d1,4),a3
+
+ test d0,a3
+ jne mark_stack_nodes1
+
+ orl d0,a3
+ push a2
+
+ movl a3,(a4,d1,4)
+#else
+ shrl $2,d0
+ bts d0,(a4)
+ jc mark_stack_nodes1
+ push a2
+#endif
+
+ movl $1,a3
+
+mark_arguments:
+ movl (a0),d0
+ testb $2,d0
+ je mark_lazy_node
+
+ movzwl -2(d0),a2
+ test a2,a2
+ je mark_hnf_0
+
+ addl $4,a0
+
+ cmp $256,a2
+ jae mark_record
+
+ subl $2,a2
+ je mark_hnf_2
+
+ jc mark_hnf_1
+
+mark_hnf_3:
+ movl 4(a0),a1
+
+ movl neg_heap_p3,d0
+ addl a1,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,d1
+ andl $31*4,d0
+
+ shrl $7,d1
+
+ movl bit_set_table(d0),d0
+
+ test (a4,d1,4),d0
+ jne shared_argument_part
+
+ orl d0,(a4,d1,4)
+#else
+ shrl $2,d0
+ bts d0,(a4)
+ jc shared_argument_part
+#endif
+
+no_shared_argument_part:
+ orl $2,(a0)
+ movl a3,4(a0)
+ addl $4,a0
+
+ orl $1,(a1)
+ leal (a1,a2,4),a1
+
+ movl (a1),a2
+ movl a0,(a1)
+ movl a1,a3
+ movl a2,a0
+ jmp mark_node
+
+shared_argument_part:
+ cmpl a0,a1
+ ja mark_hnf_1
+
+ movl (a1),d1
+ leal 4+2+1(a0),d0
+ movl d0,(a1)
+ movl d1,4(a0)
+ jmp mark_hnf_1
+
+mark_lazy_node_1:
+/ selectors:
+ jne mark_selector_node_1
+
+mark_hnf_1:
+ movl (a0),a2
+ movl a3,(a0)
+
+ leal 2(a0),a3
+ movl a2,a0
+ jmp mark_node
+
+/ selectors
+mark_indirection_node:
+ movl neg_heap_p3,d1
+ leal -4(a0,d1),d1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d1,d0
+ andl $31*4,d0
+ shrl $7,d1
+ movl bit_clear_table(d0),d0
+ andl d0,(a4,d1,4)
+#else
+ shrl $2,d1
+ btr d1,(a4)
+#endif
+ movl (a0),a0
+ jmp mark_node
+
+mark_selector_node_1:
+ addl $3,a2
+ je mark_indirection_node
+
+ movl (a0),a1
+
+ movl neg_heap_p3,d1
+ addl a1,d1
+ shrl $2,d1
+
+ addl $1,a2
+ jle mark_record_selector_node_1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ push d0
+ movl d1,d0
+
+ shrl $5,d1
+ andl $31,d0
+
+ movl bit_set_table(,d0,4),d0
+ movl (a4,d1,4),d1
+
+ andl d0,d1
+
+ pop d0
+ jne mark_hnf_1
+#else
+ bt d1,(a4)
+ jc mark_hnf_1
+#endif
+ movl (a1),d1
+ testb $2,d1
+ je mark_hnf_1
+
+ cmpw $2,-2(d1)
+ jbe small_tuple_or_record
+
+large_tuple_or_record:
+ movl 8(a1),d1
+ addl neg_heap_p3,d1
+ shrl $2,d1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ push d0
+ movl d1,d0
+
+ shrl $5,d1
+ andl $31,d0
+
+ movl bit_set_table(,d0,4),d0
+ movl (a4,d1,4),d1
+
+ andl d0,d1
+
+ pop d0
+ jne mark_hnf_1
+#else
+ bt d1,(a4)
+ jc mark_hnf_1
+#endif
+small_tuple_or_record:
+ movl neg_heap_p3,d1
+
+ lea -4(a0,d1),d1
+
+ push a0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d1,a0
+ andl $31*4,a0
+ shrl $7,d1
+ movl bit_clear_table(a0),a0
+ andl a0,(a4,d1,4)
+#else
+ shrl $2,d1
+ btr d1,(a4)
+#endif
+
+ movl -8(d0),d0
+
+ movl a1,a0
+ push a2
+ call *4(d0)
+ pop a2
+ pop a1
+
+ movl $__indirection,-4(a1)
+ movl a0,(a1)
+
+ jmp mark_node
+
+mark_record_selector_node_1:
+ je mark_strict_record_selector_node_1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ push d0
+ movl d1,d0
+
+ shrl $5,d1
+ andl $31,d0
+
+ movl bit_set_table(,d0,4),d0
+ movl (a4,d1,4),d1
+
+ andl d0,d1
+
+ pop d0
+ jne mark_hnf_1
+#else
+ bt d1,(a4)
+ jc mark_hnf_1
+#endif
+ movl (a1),d1
+ testb $2,d1
+ je mark_hnf_1
+
+ cmpw $258,-2(d1)
+ jbe small_tuple_or_record
+ jmp large_tuple_or_record
+
+mark_strict_record_selector_node_1:
+#ifdef NO_BIT_INSTRUCTIONS
+ push d0
+ movl d1,d0
+
+ shrl $5,d1
+ andl $31,d0
+
+ movl bit_set_table(,d0,4),d0
+ movl (a4,d1,4),d1
+
+ andl d0,d1
+
+ pop d0
+ jne mark_hnf_1
+#else
+ bt d1,(a4)
+ jc mark_hnf_1
+#endif
+ movl (a1),d1
+ testb $2,d1
+ je mark_hnf_1
+
+ cmpw $258,-2(d1)
+ jbe select_from_small_record
+
+ movl 8(a1),d1
+ addl neg_heap_p3,d1
+#ifdef NO_BIT_INSTRUCTIONS
+ push d0
+ movl d1,d0
+
+ shrl $7,d1
+ andl $31*4,d0
+
+ movl bit_set_table(d0),d0
+ movl (a4,d1,4),d1
+
+ andl d0,d1
+
+ pop d0
+ jne mark_hnf_1
+#else
+ shrl $2,d1
+ bt d1,(a4)
+ jc mark_hnf_1
+#endif
+
+select_from_small_record:
+/ changed 24-1-97
+ movl -8(d0),d0
+ subl $4,a0
+
+ call *4(d0)
+
+ jmp mark_next_node
+
+mark_hnf_2:
+ orl $2,(a0)
+ movl 4(a0),a2
+ movl a3,4(a0)
+ leal 4(a0),a3
+ movl a2,a0
+
+mark_node:
+ movl neg_heap_p3,d0
+
+ addl a0,d0
+
+#ifdef SHARE_CHAR_INT
+ cmpl heap_size_32_33,d0
+ jnc mark_next_node_after_static
+#endif
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,d1
+ andl $31*4,d0
+
+ shrl $7,d1
+
+ movl bit_set_table(d0),d0
+
+ movl (a4,d1,4),a2
+
+ test d0,a2
+ jne mark_next_node
+
+ orl d0,a2
+ movl a2,(a4,d1,4)
+ jmp mark_arguments
+#else
+ shrl $2,d0
+ bts d0,(a4)
+ jnc mark_arguments
+#endif
+
+/ a2,d1: free
+
+mark_next_node:
+ test $3,a3
+ jne mark_parent
+
+ movl -4(a3),a2
+ movl $3,d1
+
+ andl a2,d1
+ subl $4,a3
+
+ cmpl $3,d1
+ je argument_part_cycle1
+
+ movl 4(a3),a1
+ movl a1,K6_0(a3)
+
+c_argument_part_cycle1:
+ cmpl a3,a0
+ ja no_reverse_1
+
+ movl (a0),a1
+ leal 4+1(a3),d0
+ movl a1,4(a3)
+ movl d0,(a0)
+
+ orl d1,a3
+ movl a2,a0
+ xorl d1,a0
+ jmp mark_node
+
+no_reverse_1:
+ movl a0,4(a3)
+ movl a2,a0
+ orl d1,a3
+ xorl d1,a0
+ jmp mark_node
+
+mark_lazy_node:
+ movl -4(d0),a2
+ test a2,a2
+ je mark_next_node
+
+ addl $4,a0
+
+ subl $1,a2
+ jle mark_lazy_node_1
+
+ cmpl $255,a2
+ jge mark_closure_with_unboxed_arguments
+
+mark_closure_with_unboxed_arguments_:
+ orl $2,(a0)
+ leal (a0,a2,4),a0
+
+ movl (a0),a2
+ movl a3,(a0)
+ movl a0,a3
+ movl a2,a0
+ jmp mark_node
+
+mark_closure_with_unboxed_arguments:
+/ (a_size+b_size)+(b_size<<8)
+/ addl $1,a2
+ movl a2,d0
+ andl $255,a2
+ shrl $8,d0
+ subl d0,a2
+/ subl $1,a2
+ jg mark_closure_with_unboxed_arguments_
+ je mark_hnf_1
+ subl $4,a0
+ jmp mark_next_node
+
+mark_hnf_0:
+#ifdef SHARE_CHAR_INT
+ cmpl $INT+2,d0
+ je mark_int_3
+
+ cmpl $CHAR+2,d0
+ je mark_char_3
+
+ jb no_normal_hnf_0
+
+ movl neg_heap_p3,d1
+ addl a0,d1
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d1,a0
+ andl $31*4,a0
+ shrl $7,d1
+ movl bit_clear_table(a0),a0
+ andl a0,(a4,d1,4)
+#else
+ shrl $2,d1
+ btr d1,(a4)
+#endif
+ lea -2+ZERO_ARITY_DESCRIPTOR_OFFSET(d0),a0
+ jmp mark_next_node_after_static
+
+mark_int_3:
+ movl 4(a0),a2
+ cmpl $33,a2
+ jnc mark_next_node
+
+ movl neg_heap_p3,d1
+ addl a0,d1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d1,a0
+ andl $31*4,a0
+ shrl $7,d1
+ movl bit_clear_table(a0),a0
+ andl a0,(a4,d1,4)
+#else
+ shrl $2,d1
+ btr d1,(a4)
+#endif
+ lea small_integers(,a2,8),a0
+ jmp mark_next_node_after_static
+
+mark_char_3:
+ movl neg_heap_p3,d1
+
+ movzbl 4(a0),d0
+ addl a0,d1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d1,a2
+ andl $31*4,a2
+ shrl $7,d1
+ movl bit_clear_table(a2),a2
+ andl a2,(a4,d1,4)
+#else
+ shrl $2,d1
+ btr d1,(a4)
+#endif
+
+ lea static_characters(,d0,8),a0
+ jmp mark_next_node_after_static
+
+no_normal_hnf_0:
+#endif
+
+ cmpl $__ARRAY__+2,d0
+ jne mark_next_node
+
+ movl 8(a0),d0
+ test d0,d0
+ je mark_lazy_array
+
+ movzwl -2+2(d0),d1
+ test d1,d1
+ je mark_b_record_array
+
+ movzwl -2(d0),d0
+ test d0,d0
+ je mark_b_record_array
+
+ subl $256,d0
+ cmpl d0,d1
+ je mark_a_record_array
+
+mark_ab_record_array:
+ movl 4(a0),a1
+ addl $8,a0
+ pushl a0
+
+ imull d0,a1
+ shl $2,a1
+
+ subl d1,d0
+ addl $4,a0
+ addl a0,a1
+ call reorder
+
+ popl a0
+ movl d1,d0
+ imull -4(a0),d0
+ jmp mark_lr_array
+
+mark_b_record_array:
+ movl neg_heap_p3,d0
+ addl a0,d0
+#ifdef NO_BIT_INSTRUCTIONS
+ addl $4,d0
+ movl d0,a2
+ andl $31*4,d0
+ shrl $7,a2
+ movl bit_set_table(d0),d0
+ orl d0,(a4,a2,4)
+#else
+ shrl $2,d0
+ inc d0
+ bts d0,(a4)
+#endif
+ jmp mark_next_node
+
+mark_a_record_array:
+ movl 4(a0),d0
+ addl $8,a0
+ cmpl $2,d1
+ jb mark_lr_array
+
+ imull d1,d0
+ jmp mark_lr_array
+
+mark_lazy_array:
+ movl 4(a0),d0
+ addl $8,a0
+
+mark_lr_array:
+ movl neg_heap_p3,d1
+ addl a0,d1
+ shrl $2,d1
+ addl d0,d1
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d1,a1
+ andl $31,d1
+ shrl $5,a1
+ movl bit_set_table(,d1,4),d1
+ orl d1,(a4,a1,4)
+#else
+ bts d1,(a4)
+#endif
+ cmpl $1,d0
+ jbe mark_array_length_0_1
+
+ movl a0,a1
+ lea (a0,d0,4),a0
+
+ movl (a0),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,(a0)
+
+ movl -4(a0),d0
+ subl $4,a0
+ addl $2,d0
+ movl -4(a1),d1
+ subl $4,a1
+ movl d1,(a0)
+ movl d0,(a1)
+
+ movl -4(a0),d0
+ subl $4,a0
+ movl a3,(a0)
+ movl a0,a3
+ movl d0,a0
+ jmp mark_node
+
+mark_array_length_0_1:
+ lea -8(a0),a0
+ jb mark_next_node
+
+ movl 12(a0),d1
+ movl 8(a0),a2
+ movl a2,12(a0)
+ movl 4(a0),a2
+ movl a2,8(a0)
+ movl d1,4(a0)
+ addl $4,a0
+ jmp mark_hnf_1
+
+/ a2: free
+
+mark_parent:
+ movl a3,d1
+ andl $3,d1
+
+/ xorl d1,a3
+/ test a3,a3
+
+ andl $-4,a3
+ je mark_stack_nodes2
+
+ subl $1,d1
+ je argument_part_parent
+
+ movl K6_0(a3),a2
+
+ cmpl a3,a0
+ ja no_reverse_2
+
+ movl a0,a1
+ leal 1(a3),d0
+ movl (a1),a0
+ movl d0,(a1)
+
+no_reverse_2:
+ movl a0,K6_0(a3)
+ leal -4(a3),a0
+ movl a2,a3
+ jmp mark_next_node
+
+
+argument_part_parent:
+ movl K6_0(a3),a2
+
+ movl a3,a1
+ movl a0,a3
+ movl a1,a0
+
+/ movl (a1),a2
+skip_upward_pointers:
+ movl a2,d0
+ andl $3,d0
+ cmpl $3,d0
+ jne no_upward_pointer
+
+ leal -3(a2),a1
+/ movl (a1),a2
+ movl -3(a2),a2
+ jmp skip_upward_pointers
+
+no_upward_pointer:
+ cmpl a0,a3
+ ja no_reverse_3
+
+ movl a3,d1
+ movl K6_0(a3),a3
+ leal 1(a0),d0
+ movl d0,(d1)
+
+no_reverse_3:
+ movl a3,(a1)
+ lea -4(a2),a3
+
+ andl $-4,a3
+
+ movl a3,a1
+ movl $3,d1
+
+ movl K6_0(a3),a2
+
+ andl a2,d1
+ movl 4(a1),d0
+
+ orl d1,a3
+ movl d0,(a1)
+
+ cmpl a1,a0
+ ja no_reverse_4
+
+ movl (a0),d0
+ movl d0,4(a1)
+ leal 4+2+1(a1),d0
+ movl d0,(a0)
+ movl a2,a0
+ andl $-4,a0
+ jmp mark_node
+
+no_reverse_4:
+ movl a0,4(a1)
+ movl a2,a0
+ andl $-4,a0
+ jmp mark_node
+
+argument_part_cycle1:
+ movl 4(a3),d0
+ push a1
+
+skip_pointer_list1:
+ movl a2,a1
+ andl $-4,a1
+ movl (a1),a2
+ movl $3,d1
+ andl a2,d1
+ cmpl $3,d1
+ je skip_pointer_list1
+
+ movl d0,(a1)
+ pop a1
+ jmp c_argument_part_cycle1
+
+#ifdef SHARE_CHAR_INT
+mark_next_node_after_static:
+ test $3,a3
+ jne mark_parent_after_static
+
+ movl -4(a3),a2
+ movl $3,d1
+
+ andl a2,d1
+ subl $4,a3
+
+ cmpl $3,d1
+ je argument_part_cycle2
+
+ movl 4(a3),d0
+ movl d0,K6_0(a3)
+
+c_argument_part_cycle2:
+ movl a0,4(a3)
+ movl a2,a0
+ orl d1,a3
+ xorl d1,a0
+ jmp mark_node
+
+mark_parent_after_static:
+ movl a3,d1
+ andl $3,d1
+
+/ xorl d1,a3
+/ test a3,a3
+
+ andl $-4,a3
+ je mark_stack_nodes3
+
+ subl $1,d1
+ je argument_part_parent_after_static
+
+ movl K6_0(a3),a2
+ movl a0,K6_0(a3)
+ leal -4(a3),a0
+ movl a2,a3
+ jmp mark_next_node
+
+argument_part_parent_after_static:
+ movl K6_0(a3),a2
+
+ movl a3,a1
+ movl a0,a3
+ movl a1,a0
+
+/ movl (a1),a2
+skip_upward_pointers_2:
+ movl a2,d0
+ andl $3,d0
+ cmpl $3,d0
+ jne no_reverse_3
+
+/ movl a2,a1
+/ andl $-4,a1
+/ movl (a1),a2
+ lea -3(a2),a1
+ movl -3(a2),a2
+ jmp skip_upward_pointers_2
+
+argument_part_cycle2:
+ movl 4(a3),d0
+ push a1
+
+skip_pointer_list2:
+ movl a2,a1
+ andl $-4,a1
+ movl (a1),a2
+ movl $3,d1
+ andl a2,d1
+ cmpl $3,d1
+ je skip_pointer_list2
+
+ movl d0,(a1)
+ pop a1
+ jmp c_argument_part_cycle2
+#endif
+
+end_mark_nodes:
+ ret
+
+/ compact the heap
+
+compact_heap:
+ movl heap_size_33,d0
+ movl d0,d1
+ shl $5,d1
+#ifdef SHARE_CHAR_INT
+ addl heap_p3,d1
+#endif
+ movl d1,end_heap_p3
+
+ addl $3,d0
+ shr $2,d0
+
+ movl heap_vector,a0
+
+ lea 4(a0),d1
+ negl d1
+ movl d1,neg_heap_vector_plus_4
+
+ movl heap_p3,a4
+ xorl a3,a3
+ jmp skip_zeros
+
+move_record:
+ subl $258,d1
+ jb move_record_1
+ je move_record_2
+
+move_record_3:
+ movzwl -2+2(d0),d1
+ subl $1,d1
+ ja move_hnf_3
+
+ movl (a0),a1
+ lea 4(a0),a0
+ jb move_record_3_1b
+
+move_record_3_1a:
+ cmpl a0,a1
+ jb move_record_3_1b
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jae move_record_3_1b
+#endif
+ lea 1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_record_3_1b:
+ movl a1,(a4)
+ addl $4,a4
+
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jb move_record_3_2
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jae move_record_3_2
+#endif
+ movl neg_heap_p3,d0
+#ifdef NO_BIT_INSTRUCTIONS
+ pushl a2
+#endif
+ addl a1,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl heap_vector,d1
+ addl $4,d0
+ movl d0,a2
+ andl $31*4,a2
+ shrl $7,d0
+ movl bit_set_table(a2),a2
+ testl (d1,d0,4),a2
+ je not_linked_record_argument_part_3_b
+#else
+ shr $2,d0
+ inc d0
+
+ movl heap_vector,d1
+ bts d0,(d1)
+ jnc not_linked_record_argument_part_3_b
+#endif
+
+ movl neg_heap_p3,d0
+ addl a4,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,a2
+ andl $31*4,a2
+ shrl $7,d0
+ movl bit_set_table(a2),a2
+ orl a2,(d1,d0,4)
+ popl a2
+#else
+ shr $2,d0
+ bts d0,(d1)
+#endif
+ jmp linked_record_argument_part_3_b
+
+not_linked_record_argument_part_3_b:
+#ifdef NO_BIT_INSTRUCTIONS
+ orl a2,(d1,d0,4)
+#endif
+ movl neg_heap_p3,d0
+ addl a4,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ movl d0,a2
+ andl $31*4,a2
+ shrl $7,d0
+ movl bit_clear_table(a2),a2
+ andl a2,(d1,d0,4)
+ popl a2
+#else
+ shr $2,d0
+ btr d0,(d1)
+#endif
+
+linked_record_argument_part_3_b:
+ movl (a1),d1
+ lea 2+1(a4),d0
+ movl d0,(a1)
+ movl d1,a1
+move_record_3_2:
+ movl a1,(a4)
+ addl $4,a4
+
+ movl neg_heap_p3,d1
+ addl a0,d1
+ shr $2,d1
+ dec d1
+ andl $31,d1
+ cmp $2,d1
+ jb bit_in_next_word
+
+#ifdef NO_BIT_INSTRUCTIONS
+ andl bit_clear_table(,d1,4),a3
+#else
+ btr d1,a3
+#endif
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+bit_in_next_word:
+ movl vector_counter,d0
+ movl vector_p,a0
+ dec d0
+ movl (a0),a3
+ addl $4,a0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ andl bit_clear_table(,d1,4),a3
+#else
+ btr d1,a3
+#endif
+ testl a3,a3
+ je skip_zeros
+ jmp end_skip_zeros
+
+move_record_2:
+ cmpw $1,-2+2(d0)
+ ja move_hnf_2
+ jb move_real_or_file
+
+move_record_2_ab:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jb move_record_2_1
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jae move_record_2_1
+#endif
+ lea 1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_record_2_1:
+ movl a1,(a4)
+ movl (a0),d1
+ addl $4,a0
+ movl d1,4(a4)
+ addl $8,a4
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_record_1:
+ movzwl -2+2(d0),d1
+ test d1,d1
+ jne move_hnf_1
+ jmp move_int_bool_or_char
+
+/ d0,a0,a2: free
+find_non_zero_long:
+ movl vector_counter,d0
+ movl vector_p,a0
+skip_zeros:
+ subl $1,d0
+ jc end_copy
+ movl (a0),a3
+ addl $4,a0
+ testl a3,a3
+ je skip_zeros
+/ a2: free
+end_skip_zeros:
+ movl neg_heap_vector_plus_4,a2
+ movl d0,vector_counter
+
+ addl a0,a2
+ movl a0,vector_p
+
+ shl $5,a2
+ addl heap_p3,a2
+
+#ifdef NO_BIT_INSTRUCTIONS
+bsf_and_copy_nodes:
+ movl a3,d0
+ movl a3,a0
+ andl $0xff,d0
+ jne found_bit1
+ andl $0xff00,a0
+ jne found_bit2
+ movl a3,d0
+ movl a3,a0
+ andl $0xff0000,d0
+ jne found_bit3
+ shrl $24,a0
+ movzbl first_one_bit_table(,a0,1),d1
+ addl $24,d1
+ jmp copy_nodes
+
+found_bit3:
+ shrl $16,d0
+ movzbl first_one_bit_table(,d0,1),d1
+ addl $16,d1
+ jmp copy_nodes
+
+found_bit2:
+ shrl $8,a0
+ movzbl first_one_bit_table(,a0,1),d1
+ addl $8,d1
+ jmp copy_nodes
+
+found_bit1:
+ movzbl first_one_bit_table(,d0,1),d1
+#else
+ bsf a3,d1
+#endif
+
+copy_nodes:
+ movl (a2,d1,4),d0
+#ifdef NO_BIT_INSTRUCTIONS
+ andl bit_clear_table(,d1,4),a3
+#else
+ btr d1,a3
+#endif
+ leal 4(a2,d1,4),a0
+ dec d0
+
+ test $2,d0
+ je begin_update_list_2
+
+ movl -10(d0),d1
+ subl $2,d0
+
+ test $1,d1
+ je end_list_2
+find_descriptor_2:
+ andl $-4,d1
+ movl (d1),d1
+ test $1,d1
+ jne find_descriptor_2
+
+end_list_2:
+ movl d1,a1
+ movzwl -2(d1),d1
+ cmpl $256,d1
+ jb no_record_arguments
+
+ movzwl -2+2(a1),a1
+ subl $2,a1
+ jae copy_record_arguments_aa
+
+ subl $256+3,d1
+
+copy_record_arguments_all_b:
+ pushl d1
+ movl heap_vector,d1
+
+update_up_list_1r:
+ movl d0,a1
+ addl neg_heap_p3,d0
+
+#ifdef NO_BIT_INSTRUCTIONS
+ push a0
+ movl d0,a0
+
+ shrl $7,d0
+ andl $31*4,a0
+
+ movl bit_set_table(,a0,1),a0
+ movl (d1,d0,4),d0
+
+ andl a0,d0
+
+ pop a0
+ je copy_argument_part_1r
+#else
+ shrl $2,d0
+ bt d0,(d1)
+ jnc copy_argument_part_1r
+#endif
+ movl (a1),d0
+ movl a4,(a1)
+ subl $3,d0
+ jmp update_up_list_1r
+
+copy_argument_part_1r:
+ movl (a1),d0
+ movl a4,(a1)
+ movl d0,(a4)
+ addl $4,a4
+
+ movl neg_heap_p3,d0
+ addl a0,d0
+ shr $2,d0
+
+ mov d0,d1
+ andl $31,d1
+ cmp $1,d1
+ jae bit_in_this_word
+
+ movl vector_counter,d0
+ movl vector_p,a1
+ dec d0
+ movl (a1),a3
+ addl $4,a1
+
+ movl neg_heap_vector_plus_4,a2
+ addl a1,a2
+ shl $5,a2
+ addl heap_p3,a2
+
+ movl a1,vector_p
+ movl d0,vector_counter
+
+bit_in_this_word:
+#ifdef NO_BIT_INSTRUCTIONS
+ andl bit_clear_table(,d1,4),a3
+#else
+ btr d1,a3
+#endif
+ popl d1
+
+copy_b_record_argument_part_arguments:
+ movl (a0),d0
+ addl $4,a0
+ movl d0,(a4)
+ addl $4,a4
+ subl $1,d1
+ jnc copy_b_record_argument_part_arguments
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+copy_record_arguments_aa:
+ subl $256+2,d1
+ subl a1,d1
+
+ pushl d1
+ pushl a1
+
+update_up_list_2r:
+ movl d0,a1
+ movl (a1),d0
+ movl $3,d1
+ andl d0,d1
+ subl $3,d1
+ jne copy_argument_part_2r
+
+ movl a4,(a1)
+ subl $3,d0
+ jmp update_up_list_2r
+
+copy_argument_part_2r:
+ movl a4,(a1)
+ cmpl a0,d0
+ jb copy_record_argument_2
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,d0
+ jae copy_record_argument_2
+#endif
+ movl d0,a1
+ movl (a1),d0
+ lea 1(a4),d1
+ movl d1,(a1)
+copy_record_argument_2:
+ movl d0,(a4)
+ addl $4,a4
+
+ popl d1
+ subl $1,d1
+ jc no_pointers_in_record
+
+copy_record_pointers:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jb copy_record_pointers_2
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jae copy_record_pointers_2
+#endif
+ movl (a1),d0
+ inc a4
+ movl a4,(a1)
+ dec a4
+ movl d0,a1
+copy_record_pointers_2:
+ movl a1,(a4)
+ addl $4,a4
+ subl $1,d1
+ jnc copy_record_pointers
+
+no_pointers_in_record:
+ popl d1
+
+ subl $1,d1
+ jc no_non_pointers_in_record
+
+copy_non_pointers_in_record:
+ movl (a0),d0
+ addl $4,a0
+ movl d0,(a4)
+ addl $4,a4
+ subl $1,d1
+ jnc copy_non_pointers_in_record
+
+no_non_pointers_in_record:
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+no_record_arguments:
+ subl $3,d1
+update_up_list_2:
+ movl d0,a1
+ movl (d0),d0
+ inc d0
+ movl a4,(a1)
+ testb $3,d0
+ jne copy_argument_part_2
+
+ subl $4,d0
+ jmp update_up_list_2
+
+copy_argument_part_2:
+ dec d0
+ cmpl a0,d0
+ jc copy_arguments_1
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,d0
+ jnc copy_arguments_1
+#endif
+ movl d0,a1
+ movl (d0),d0
+ inc a4
+ movl a4,(a1)
+ dec a4
+copy_arguments_1:
+ movl d0,(a4)
+ addl $4,a4
+
+copy_argument_part_arguments:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc copy_arguments_2
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc copy_arguments_2
+#endif
+ movl (a1),d0
+ inc a4
+ movl a4,(a1)
+ dec a4
+ movl d0,a1
+copy_arguments_2:
+ movl a1,(a4)
+ addl $4,a4
+ subl $1,d1
+ jnc copy_argument_part_arguments
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+update_list_2_:
+ dec d0
+update_list_2:
+ movl a4,(a1)
+begin_update_list_2:
+ movl d0,a1
+ movl (d0),d0
+update_list__2:
+ test $1,d0
+ jz end_update_list_2
+ test $2,d0
+ jz update_list_2_
+ lea -3(d0),a1
+ movl -3(d0),d0
+ jmp update_list__2
+
+end_update_list_2:
+ movl a4,(a1)
+
+ movl d0,(a4)
+ addl $4,a4
+
+ testb $2,d0
+ je move_lazy_node
+
+ movzwl -2(d0),d1
+ testl d1,d1
+ je move_hnf_0
+
+ cmp $256,d1
+ jae move_record
+
+ subl $2,d1
+ jc move_hnf_1
+ je move_hnf_2
+
+move_hnf_3:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_hnf_3_1
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_hnf_3_1
+#endif
+ lea 1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_hnf_3_1:
+ movl a1,(a4)
+
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_hnf_3_2
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_hnf_3_2
+#endif
+ lea 4+2+1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_hnf_3_2:
+ movl a1,4(a4)
+ addl $8,a4
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_hnf_2:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_hnf_2_1
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_hnf_2_1
+#endif
+ lea 1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_hnf_2_1:
+ movl a1,(a4)
+
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_hnf_2_2
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_hnf_2_2
+#endif
+ lea 4+1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_hnf_2_2:
+ movl a1,4(a4)
+ addl $8,a4
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_hnf_1:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_hnf_1_
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_hnf_1_
+#endif
+ lea 1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_hnf_1_:
+ movl a1,(a4)
+ addl $4,a4
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_real_or_file:
+ movl (a0),d0
+ addl $4,a0
+ movl d0,(a4)
+ addl $4,a4
+move_int_bool_or_char:
+ movl (a0),d0
+ addl $4,a0
+ movl d0,(a4)
+ addl $4,a4
+copy_normal_hnf_0:
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_hnf_0:
+ cmpl $INT+2,d0
+ jb move_real_file_string_or_array
+ cmpl $CHAR+2,d0
+ jbe move_int_bool_or_char
+#ifdef DLL
+move_normal_hnf_0:
+#endif
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_real_file_string_or_array:
+ cmpl $__STRING__+2,d0
+ ja move_real_or_file
+ jne move_array
+
+ movl (a0),d0
+ addl $3,d0
+ shr $2,d0
+
+cp_s_arg_lp3:
+ movl (a0),d1
+ addl $4,a0
+ movl d1,(a4)
+ addl $4,a4
+ subl $1,d0
+ jnc cp_s_arg_lp3
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_array:
+#ifdef DLL
+ cmpl $__ARRAY__+2,d0
+ jb move_normal_hnf_0
+#endif
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_end_array_bit
+#else
+ bsf a3,d1
+ jne end_array_bit
+#endif
+ pushl a0
+
+ movl vector_counter,d0
+ movl vector_p,a0
+
+skip_zeros_a:
+ subl $1,d0
+ movl (a0),a3
+ addl $4,a0
+ testl a3,a3
+ je skip_zeros_a
+
+ movl neg_heap_vector_plus_4,a2
+ addl a0,a2
+ movl d0,vector_counter
+
+ shl $5,a2
+ movl a0,vector_p
+
+ addl heap_p3,a2
+ popl a0
+
+#ifdef NO_BIT_INSTRUCTIONS
+bsf_and_end_array_bit:
+ movl a3,d0
+ movl a3,a1
+ andl $0xff,d0
+ jne a_found_bit1
+ andl $0xff00,a1
+ jne a_found_bit2
+ movl a3,d0
+ movl a3,a1
+ andl $0xff0000,d0
+ jne a_found_bit3
+ shrl $24,a1
+ movzbl first_one_bit_table(,a1,1),d1
+ addl $24,d1
+ jmp end_array_bit
+a_found_bit3:
+ shrl $16,d0
+ movzbl first_one_bit_table(,d0,1),d1
+ addl $16,d1
+ jmp end_array_bit
+a_found_bit2:
+ shrl $8,a1
+ movzbl first_one_bit_table(,a1,1),d1
+ addl $8,d1
+ jmp end_array_bit
+a_found_bit1:
+ movzbl first_one_bit_table(,d0,1),d1
+
+#else
+ bsf a3,d1
+#endif
+
+end_array_bit:
+#ifdef NO_BIT_INSTRUCTIONS
+ andl bit_clear_table(,d1,4),a3
+#else
+ btr d1,a3
+#endif
+ leal (a2,d1,4),d1
+
+ cmpl d1,a0
+ jne move_a_array
+
+move_b_array:
+ movl (a0),a1
+ movl a1,(a4)
+ movl 4(a0),d1
+ addl $4,a0
+ movzwl -2(d1),d0
+ addl $4,a4
+ test d0,d0
+ je move_strict_basic_array
+
+ subl $256,d0
+ imull d0,a1
+ movl a1,d0
+ jmp cp_s_arg_lp3
+
+move_strict_basic_array:
+ movl a1,d0
+ cmpl $INT+2,d1
+ je cp_s_arg_lp3
+
+ cmpl $BOOL+2,d1
+ je move_bool_array
+
+ addl d0,d0
+ jmp cp_s_arg_lp3
+
+move_bool_array:
+ addl $3,d0
+ shr $2,d0
+ jmp cp_s_arg_lp3
+
+move_a_array:
+ movl d1,a1
+ subl a0,d1
+ shr $2,d1
+
+ pushl a3
+
+ subl $1,d1
+ jb end_array
+
+ movl (a0),a3
+ movl -4(a1),d0
+ movl a3,-4(a1)
+ movl d0,(a4)
+ movl (a1),d0
+ movl 4(a0),a3
+ addl $8,a0
+ movl a3,(a1)
+ movl d0,4(a4)
+ addl $8,a4
+ test d0,d0
+ je st_move_array_lp
+
+ movzwl -2+2(d0),a3
+ movzwl -2(d0),d0
+ subl $256,d0
+ cmpl a3,d0
+ je st_move_array_lp
+
+move_array_ab:
+ pushl a0
+
+ movl -8(a4),a1
+ movl a3,d1
+ imull d0,a1
+ shl $2,a1
+
+ subl d1,d0
+ addl a0,a1
+ call reorder
+
+ popl a0
+ subl $1,d1
+ subl $1,d0
+
+ pushl d1
+ pushl d0
+ pushl -8(a4)
+ jmp st_move_array_lp_ab
+
+move_array_ab_lp1:
+ movl 8(sp),d0
+move_array_ab_a_elements:
+ movl (a0),d1
+ addl $4,a0
+ cmpl a0,d1
+ jb move_array_element_ab
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,d1
+ jnc move_array_element_ab
+#endif
+ movl d1,a1
+ movl (a1),d1
+ inc a4
+ movl a4,(a1)
+ dec a4
+move_array_element_ab:
+ movl d1,(a4)
+ addl $4,a4
+ subl $1,d0
+ jnc move_array_ab_a_elements
+
+ movl 4(sp),d0
+move_array_ab_b_elements:
+ movl (a0),d1
+ addl $4,a0
+ movl d1,(a4)
+ addl $4,a4
+ subl $1,d0
+ jnc move_array_ab_b_elements
+
+st_move_array_lp_ab:
+ subl $1,(sp)
+ jnc move_array_ab_lp1
+
+ addl $12,sp
+ jmp end_array
+
+move_array_lp1:
+ movl (a0),d0
+ addl $4,a0
+ addl $4,a4
+ cmpl a0,d0
+ jb move_array_element
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,d0
+ jnc move_array_element
+#endif
+ movl (d0),a3
+ movl d0,a1
+ movl a3,-4(a4)
+ leal -4+1(a4),d0
+ movl d0,(a1)
+
+ subl $1,d1
+ jnc move_array_lp1
+
+ jmp end_array
+
+move_array_element:
+ movl d0,-4(a4)
+st_move_array_lp:
+ subl $1,d1
+ jnc move_array_lp1
+
+end_array:
+ popl a3
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_lazy_node:
+ movl d0,a1
+ movl -4(a1),d1
+ test d1,d1
+ je move_lazy_node_0
+
+ subl $1,d1
+ jle move_lazy_node_1
+
+ cmpl $256,d1
+ jge move_closure_with_unboxed_arguments
+
+move_lazy_node_arguments:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_lazy_node_arguments_
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_lazy_node_arguments_
+#endif
+ movl (a1),d0
+ movl d0,(a4)
+ lea 1(a4),d0
+ addl $4,a4
+ movl d0,(a1)
+ subl $1,d1
+ jnc move_lazy_node_arguments
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_lazy_node_arguments_:
+ movl a1,(a4)
+ addl $4,a4
+ subl $1,d1
+ jnc move_lazy_node_arguments
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_lazy_node_1:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_lazy_node_1_
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_lazy_node_1_
+#endif
+ lea 1(a4),d0
+ movl (a1),d1
+ movl d0,(a1)
+ movl d1,a1
+move_lazy_node_1_:
+ movl a1,(a4)
+ addl $8,a4
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_lazy_node_0:
+ addl $8,a4
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_closure_with_unboxed_arguments:
+ je move_closure_with_unboxed_arguments_1
+ addl $1,d1
+ movl d1,d0
+ andl $255,d1
+ shrl $8,d0
+ subl d0,d1
+ je move_non_pointers_of_closure
+
+ pushl d0
+
+move_closure_with_unboxed_arguments_lp:
+ movl (a0),a1
+ addl $4,a0
+ cmpl a0,a1
+ jc move_closure_with_unboxed_arguments_
+#ifdef SHARE_CHAR_INT
+ cmpl end_heap_p3,a1
+ jnc move_closure_with_unboxed_arguments_
+#endif
+ movl (a1),d0
+ movl d0,(a4)
+ lea 1(a4),d0
+ addl $4,a4
+ movl d0,(a1)
+ subl $1,d1
+ jne move_closure_with_unboxed_arguments_lp
+
+ popl d0
+ jmp move_non_pointers_of_closure
+
+move_closure_with_unboxed_arguments_:
+ movl a1,(a4)
+ addl $4,a4
+ subl $1,d1
+ jne move_closure_with_unboxed_arguments_lp
+
+ popl d0
+
+move_non_pointers_of_closure:
+ movl (a0),d1
+ addl $4,a0
+ movl d1,(a4)
+ addl $4,a4
+ subl $1,d0
+ jne move_non_pointers_of_closure
+
+#ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+#else
+ bsf a3,d1
+ jne copy_nodes
+#endif
+ jmp find_non_zero_long
+
+move_closure_with_unboxed_arguments_1:
+ movl (a0),d0
+ movl d0,(a4)
+ addl $8,a4
+# ifdef NO_BIT_INSTRUCTIONS
+ test a3,a3
+ jne bsf_and_copy_nodes
+# else
+ bsf a3,d1
+ jne copy_nodes
+# endif
+ jmp find_non_zero_long
+
+end_copy:
diff --git a/icopy.s b/icopy.s
new file mode 100644
index 0000000..841fbf1
--- /dev/null
+++ b/icopy.s
@@ -0,0 +1,1024 @@
+
+ push a3
+
+ mov heap_p2,a4
+
+ mov heap_size_129,d0
+ shl $6,d0
+
+ mov d0,semi_space_size
+ lea (a4,d0),a3
+
+#ifdef WRITE_HEAP
+ movl a3,heap2_begin_and_end+4
+#endif
+
+ movl caf_list,d0
+ test d0,d0
+ je end_copy_cafs
+
+copy_cafs_lp:
+ pushl -4(d0)
+
+ lea 4(d0),a2
+ movl (d0),d1
+ subl $1,d1
+ call copy_lp2
+
+ popl d0
+ test d0,d0
+ jne copy_cafs_lp
+
+end_copy_cafs:
+ movl (sp),d1
+ mov stack_p,a2
+ sub a2,d1
+ shr $2,d1
+
+ sub $1,d1
+ jb end_copy0
+ call copy_lp2
+end_copy0:
+ mov heap_p2,a2
+
+ jmp copy_lp1
+/
+/ Copy all referenced nodes to the other semi space
+/
+
+in_hnf_1_2:
+ dec d1
+copy_lp2_lp1:
+ call copy_lp2
+copy_lp1:
+ cmp a4,a2
+ jae end_copy1
+
+ mov (a2),d0
+ add $4,a2
+ testb $2,d0
+ je not_in_hnf_1
+in_hnf_1:
+ movzwl -2(d0),d1
+
+ test d1,d1
+#ifdef NO_COPY_TO_END
+ je skip_hnf_0
+#endif
+ je copy_array_21
+
+ cmp $2,d1
+ jbe in_hnf_1_2
+
+ cmp $256,d1
+ jae copy_record_21
+
+ mov 4(a2),d0
+
+ testb $1,d0
+
+ jne node_without_arguments_part
+
+ push d1
+ xorl d1,d1
+
+ call copy_lp2
+
+ pop d1
+ add $4,a2
+
+ sub $2,d1
+ jmp copy_lp2_lp1
+
+#ifdef NO_COPY_TO_END
+skip_hnf_0:
+ add $4,a2
+ cmp $INT+2,d0
+ jae copy_lp1
+skip_real_file_or_string:
+ add $4,a2
+ jmp copy_lp1
+#endif
+
+node_without_arguments_part:
+ dec d0
+ xorl d1,d1
+
+ mov d0,4(a2)
+ call copy_lp2
+
+ add $4,a2
+ jmp copy_lp1
+
+copy_record_21:
+ subl $258,d1
+ ja copy_record_arguments_3
+
+ movzwl -2+2(d0),d1
+ jb copy_record_arguments_1
+
+ subl $1,d1
+ ja copy_lp2_lp1
+ je copy_node_arity1
+ addl $8,a2
+ jmp copy_lp1
+
+copy_record_arguments_1:
+ dec d1
+ je copy_lp2_lp1
+ addl $4,a2
+ jmp copy_lp1
+
+copy_record_arguments_3:
+ testb $1,4(a2)
+ jne record_node_without_arguments_part
+
+ movzwl -2+2(d0),a1
+ test a1,a1
+ je copy_record_arguments_3b
+ subl $1,a1
+ je copy_record_arguments_3abb
+
+ lea 3*4(a2,d1,4),a0
+ pushl a0
+ pushl a1
+
+ sub d1,d1
+ call copy_lp2
+
+ addl $4,a2
+ popl d1
+ dec d1
+ call copy_lp2
+
+ popl a2
+ jmp copy_lp1
+
+copy_record_arguments_3abb:
+ pushl d1
+ sub d1,d1
+
+ call copy_lp2
+
+ popl d1
+
+ lea 2*4(a2,d1,4),a2
+ jmp copy_lp1
+
+copy_record_arguments_3b:
+ lea 3*4(a2,d1,4),a2
+ jmp copy_lp1
+
+record_node_without_arguments_part:
+ andl $-2,4(a2)
+
+ cmpw $0,-2+2(d0)
+ je record_node_without_arguments_part_3b
+
+ sub d1,d1
+ call copy_lp2
+
+ addl $4,a2
+ jmp copy_lp1
+
+record_node_without_arguments_part_3b:
+ addl $8,a2
+ jmp copy_lp1
+
+not_in_hnf_1:
+ mov -4(d0),d1
+ cmpl $257,d1
+ jge copy_unboxed_closure_arguments
+ sub $1,d1
+ jg copy_lp2_lp1
+
+copy_node_arity1:
+#ifdef NO_COPY_TO_END
+ jb skip_node_arity0
+#endif
+ xorl d1,d1
+ call copy_lp2
+
+ add $4,a2
+ jmp copy_lp1
+
+#ifdef NO_COPY_TO_END
+skip_node_arity0:
+ add $8,a2
+ jmp copy_lp1
+#endif
+
+copy_unboxed_closure_arguments:
+ je copy_unboxed_closure_arguments1
+
+ xorl d0,d0
+ movb d1hb,d0lb
+ andl $255,d1
+ sub d0,d1
+
+ subl $1,d1
+ jl copy_unboxed_closure_arguments_without_pointers
+
+ pushl d0
+ call copy_lp2
+ popl d0
+
+copy_unboxed_closure_arguments_without_pointers:
+ lea (a2,d0,4),a2
+ jmp copy_lp1
+
+copy_unboxed_closure_arguments1:
+ addl $8,a2
+ jmp copy_lp1
+
+copy_array_21:
+ movl 4(a2),d1
+ addl $8,a2
+ test d1,d1
+ je copy_array_21_a
+
+ movzwl -2(d1),d0
+ movzwl -2+2(d1),d1
+ subl $256,d0
+ test d1,d1
+ je copy_array_21_b
+
+ cmpl d0,d1
+ je copy_array_21_r_a
+
+copy_array_21_ab:
+ cmpl $0,-8(a2)
+ je copy_lp1
+
+ subl d1,d0
+ shl $2,d0
+ subl $1,d1
+
+ pushl d1
+ pushl d0
+ movl -8(a2),d1
+ subl $1,d1
+ pushl d1
+
+copy_array_21_lp_ab:
+ movl 8(sp),d1
+ call copy_lp2
+
+ addl 4(sp),a2
+ subl $1,(sp)
+ jnc copy_array_21_lp_ab
+
+ addl $12,sp
+ jmp copy_lp1
+
+copy_array_21_b:
+ movl -8(a2),d1
+ imull d0,d1
+ lea (a2,d1,4),a2
+ jmp copy_lp1
+
+copy_array_21_r_a:
+ movl -8(a2),d1
+ imull d0,d1
+ subl $1,d1
+ jc copy_lp1
+ jmp copy_lp2_lp1
+
+copy_array_21_a:
+ movl -8(a2),d1
+ subl $1,d1
+ jc copy_lp1
+ jmp copy_lp2_lp1
+
+/
+/ Copy nodes to the other semi-space
+/
+
+copy_lp2:
+ movl (a2),a1
+
+/ selectors:
+continue_after_selector_2:
+ movl (a1),a0
+ testb $2,a0
+ je not_in_hnf_2
+
+in_hnf_2:
+ movzwl -2(a0),d0
+ test d0,d0
+ je copy_arity_0_node2
+
+ cmp $256,d0
+ jae copy_record_2
+
+ sub $2,d0
+ mov a4,(a2)
+
+ lea 4(a2),a2
+ ja copy_hnf_node2_3
+
+ mov a0,(a4)
+ jb copy_hnf_node2_1
+
+ inc a4
+ mov 4(a1),a0
+
+ mov a4,(a1)
+ mov 8(a1),d0
+
+ sub $1,d1
+ mov a0,4-1(a4)
+
+ mov d0,8-1(a4)
+ lea 12-1(a4),a4
+
+ jae copy_lp2
+ ret
+
+copy_hnf_node2_1:
+ inc a4
+ mov 4(a1),d0
+
+ sub $1,d1
+ mov a4,(a1)
+
+ mov d0,4-1(a4)
+ lea 8-1(a4),a4
+
+ jae copy_lp2
+ ret
+
+copy_hnf_node2_3:
+ mov a0,(a4)
+ inc a4
+
+ mov a4,(a1)
+ mov 4(a1),a0
+
+ mov a0,4-1(a4)
+ mov 8(a1),a0
+
+ add $12-1,a4
+ mov (a0),a1
+
+ testb $1,a1
+ jne arguments_already_copied_2
+
+ mov a4,-4(a4)
+ add $4,a0
+
+ mov a1,(a4)
+ inc a4
+
+ mov a4,-4(a0)
+ add $4-1,a4
+
+cp_hnf_arg_lp2:
+ mov (a0),a1
+ add $4,a0
+
+ mov a1,(a4)
+ add $4,a4
+
+ dec d0
+ jne cp_hnf_arg_lp2
+
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+arguments_already_copied_2:
+ mov a1,-4(a4)
+
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_arity_0_node2:
+ cmp $INT+2,a0
+ jb copy_real_file_or_string_2
+
+ cmp $CHAR+2,a0
+ ja copy_normal_hnf_0_2
+
+copy_int_bool_or_char_2:
+#ifdef SHARE_CHAR_INT
+ mov 4(a1),d0
+ je copy_char_2
+
+ cmp $INT+2,a0
+ jne no_small_int_or_char_2
+
+copy_int_2:
+ cmp $33,d0
+ jae no_small_int_or_char_2
+
+ shl $3,d0
+ add $4,a2
+
+ add $small_integers,d0
+ sub $1,d1
+
+ mov d0,-4(a2)
+ jae copy_lp2
+
+ ret
+
+copy_char_2:
+ andl $255,d0
+
+ shl $3,d0
+ add $4,a2
+
+ add $static_characters,d0
+ sub $1,d1
+
+ mov d0,-4(a2)
+ jae copy_lp2
+ ret
+
+no_small_int_or_char_2:
+#else
+no_small_int_or_char_2:
+ mov 4(a1),d0
+#endif
+
+#ifdef NO_COPY_TO_END
+ mov a0,(a4)
+ mov d0,4(a4)
+ mov a4,(a2)
+ inc a4
+ mov a4,(a1)
+ add $7,a4
+ add $4,a2
+#else
+ mov a0,-8(a3)
+ add $4,a2
+
+ mov d0,-4(a3)
+ sub $7,a3
+
+ mov a3,(a1)
+ dec a3
+
+ mov a3,-4(a2)
+#endif
+
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_normal_hnf_0_2:
+#ifdef SHARE_CHAR_INT
+ sub $2-ZERO_ARITY_DESCRIPTOR_OFFSET,a0
+ sub $1,d1
+
+ mov a0,(a2)
+ lea 4(a2),a2
+#else
+ mov a0,-4(a3)
+ sub $3,a3
+ mov a3,(a1)
+ dec a3
+ mov a3,(a2)
+ add $4,a2
+ sub $1,d1
+#endif
+ jae copy_lp2
+ ret
+
+copy_real_file_or_string_2:
+ cmpl $__STRING__+2,a0
+ jbe copy_string_or_array_2
+
+copy_real_or_file_2:
+#ifdef NO_COPY_TO_END
+ mov a0,(a4)
+ mov a4,(a2)
+ inc a4
+ mov a4,(a1)
+ mov 4(a1),d0
+ mov 8(a1),a0
+ add $4,a2
+ mov d0,4-1(a4)
+ mov a0,8-1(a4)
+ add $11,a4
+ sub $1,d1
+#else
+ mov a0,-12(a3)
+ sub $12-1,a3
+
+ mov a3,(a1)
+ dec a3
+
+ mov 4(a1),d0
+ mov 8(a1),a0
+
+ mov a3,(a2)
+ add $4,a2
+
+ mov d0,4(a3)
+ sub $1,d1
+
+ mov a0,8(a3)
+#endif
+ jae copy_lp2
+ ret
+
+already_copied_2:
+ dec a0
+ sub $1,d1
+
+ mov a0,(a2)
+ lea 4(a2),a2
+
+ jae copy_lp2
+ ret
+
+copy_record_2:
+ subl $258,d0
+ ja copy_record_node2_3
+
+ movl a4,(a2)
+ movl a0,(a4)
+
+ lea 1(a4),a0
+ movl 4(a1),d0
+
+ movl a0,(a1)
+ jb copy_record_node2_1
+
+ movl d0,4(a4)
+ movl 8(a1),d0
+
+ addl $4,a2
+ movl d0,8(a4)
+
+ addl $12,a4
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_record_node2_1:
+ addl $4,a2
+ movl d0,4(a4)
+
+ addl $8,a4
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_record_node2_3:
+ pushl d0
+ lea 1(a4),d0
+
+ movl d0,(a1)
+ movl 8(a1),d0
+
+ movl a0,(a4)
+ movl 4(a1),a1
+
+ movl d0,a0
+ subl heap_p1,d0
+
+ shr $3,d0
+ movl a1,4(a4)
+
+ mov d0,a1
+ and $31,d0
+
+ shr $3,a1
+ movl a4,(a2)
+
+ andl $-4,a1
+ mov bit_set_table(,d0,4),d0
+
+ addl heap_copied_vector,a1
+ addl $4,a2
+
+ test (a1),d0
+ jne record_arguments_already_copied_2
+
+ or d0,(a1)
+ lea 12(a4),a1
+
+ popl d0
+ movl a1,8(a4)
+
+ addl $13,a4
+ movl (a0),a1
+
+ movl a4,(a0)
+ addl $4,a0
+
+ movl a1,-1(a4)
+ addl $3,a4
+
+cp_record_arg_lp2:
+ movl (a0),a1
+ addl $4,a0
+
+ movl a1,(a4)
+ addl $4,a4
+
+ subl $1,d0
+ jne cp_record_arg_lp2
+
+ subl $1,d1
+ jae copy_lp2
+ ret
+
+record_arguments_already_copied_2:
+ movl (a0),a1
+ popl d0
+
+ movl a1,8(a4)
+ addl $12,a4
+
+ subl $1,d1
+ jae copy_lp2
+ ret
+
+not_in_hnf_2:
+ testb $1,a0
+ jne already_copied_2
+
+ mov -4(a0),d0
+ test d0,d0
+ jle copy_arity_0_node2_
+
+copy_node2_1_:
+ andl $255,d0
+ sub $2,d0
+ jl copy_arity_1_node2
+copy_node2_3:
+ mov a4,(a2)
+ add $4,a2
+ mov a0,(a4)
+ inc a4
+ mov a4,(a1)
+ mov 4(a1),a0
+ add $8,a1
+ mov a0,4-1(a4)
+ add $8-1,a4
+
+cp_arg_lp2:
+ mov (a1),a0
+ add $4,a1
+ mov a0,(a4)
+ add $4,a4
+ sub $1,d0
+ jae cp_arg_lp2
+
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_arity_1_node2:
+copy_arity_1_node2_:
+ mov a4,(a2)
+ inc a4
+
+ add $4,a2
+ mov a4,(a1)
+
+ mov 4(a1),d0
+ mov a0,-1(a4)
+
+ mov d0,4-1(a4)
+ add $12-1,a4
+
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_indirection_2:
+ mov a1,d0
+ mov 4(a1),a1
+
+ mov (a1),a0
+ testb $2,a0
+ jne in_hnf_2
+
+ testb $1,a0
+ jne already_copied_2
+
+ cmp $-2,-4(a0)
+ je skip_indirections_2
+
+ mov -4(a0),d0
+ test d0,d0
+ jle copy_arity_0_node2_
+ jmp copy_node2_1_
+
+skip_indirections_2:
+ mov 4(a1),a1
+
+ mov (a1),a0
+ testb $2,a0
+ jne update_indirection_list_2
+ testb $1,a0
+ jne update_indirection_list_2
+
+ cmp $-2,-4(a0)
+ je skip_indirections_2
+
+update_indirection_list_2:
+ lea 4(d0),a0
+ mov 4(d0),d0
+ mov a1,(a0)
+ cmp d0,a1
+ jne update_indirection_list_2
+
+ jmp continue_after_selector_2
+
+copy_selector_2:
+ add $2,d0
+ je copy_indirection_2
+ jl copy_record_selector_2
+
+ mov 4(a1),d0
+
+ mov (d0),d0
+ testb $2,d0
+ je copy_arity_1_node2_
+
+ cmpw $2,-2(d0)
+ jbe copy_selector_2_
+
+ mov 4(a1),d0
+ mov 8(d0),d0
+ testb $1,(d0)
+ jne copy_arity_1_node2_
+
+copy_selector_2_:
+ mov -8(a0),d0
+
+ mov 4(a1),a0
+ push a1
+ push a2
+ call *4(d0)
+ pop a2
+ pop a1
+
+ movl $__indirection,(a1)
+ mov a0,4(a1)
+
+ mov a0,a1
+ jmp continue_after_selector_2
+
+copy_record_selector_2:
+ addl $1,d0
+ movl 4(a1),d0
+ movl (d0),d0
+ je copy_strict_record_selector_2
+
+ testb $2,d0
+ je copy_arity_1_node2_
+
+ cmpw $258,-2(d0)
+ jbe copy_selector_2_
+
+ movl 4(a1),d0
+ pushl a1
+
+ movl 8(d0),d0
+
+ subl heap_p1,d0
+
+ mov d0,a1
+ and $31*8,d0
+
+ shr $6,a1
+
+ shr $1,d0
+ andl $-4,a1
+
+ addl heap_copied_vector,a1
+
+ mov bit_set_table(d0),d0
+
+ andl (a1),d0
+ popl a1
+
+ jne copy_arity_1_node2_
+
+ jmp copy_selector_2_
+
+copy_strict_record_selector_2:
+ testb $2,d0
+ je copy_arity_1_node2_
+
+ cmpw $258,-2(d0)
+ jbe copy_strict_record_selector_2_
+
+ movl 4(a1),d0
+ pushl a1
+
+ movl 8(d0),d0
+
+ subl heap_p1,d0
+
+ mov d0,a1
+ and $31*8,d0
+
+ shr $6,a1
+
+ shr $1,d0
+ andl $-4,a1
+
+ addl heap_copied_vector,a1
+
+ mov bit_set_table(d0),d0
+
+ and (a1),d0
+ popl a1
+
+ jne copy_arity_1_node2_
+
+copy_strict_record_selector_2_:
+ mov -8(a0),d0
+
+ movl a1,a0
+ movl 4(a1),a1
+
+ push a2
+ call *4(d0)
+ pop a2
+
+ movl a0,a1
+ movl (a0),a0
+ testb $2,a0
+ jne in_hnf_2
+ hlt
+
+copy_arity_0_node2_:
+ jl copy_selector_2
+#ifdef NO_COPY_TO_END
+ mov a0,(a4)
+ mov a4,(a2)
+ lea 1(a4),d0
+ add $12,a4
+#else
+ mov a0,-12(a3)
+ sub $12,a3
+ mov a3,(a2)
+ lea 1(a3),d0
+#endif
+ add $4,a2
+ mov d0,(a1)
+
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+
+copy_string_or_array_2:
+#ifdef NO_COPY_TO_END
+ jmp halt
+#endif
+#ifdef DLL
+ je copy_string_2
+ cmpl $__ARRAY__+2,a0
+ jb copy_normal_hnf_0_2
+ movl a1,a0
+ jmp copy_array_2
+copy_string_2:
+ movl a1,a0
+ mov a1,d0
+#else
+ movl a1,a0
+ jne copy_array_2
+ mov a0,d0
+#endif
+
+ sub heap_p1,d0
+ cmp semi_space_size,d0
+ jae copy_string_constant
+
+ mov 4(a0),a1
+ add $4,a2
+
+ add $3,a1
+ push d1
+
+ mov a1,d0
+ and $-4,a1
+
+ shr $2,d0
+ sub a1,a3
+
+ mov (a0),d1
+ add $4,a0
+
+ mov d1,-8(a3)
+ sub $8,a3
+
+ mov a3,-4(a2)
+ lea 1(a3),a1
+
+ mov a1,-4(a0)
+ lea 4(a3),a1
+
+cp_s_arg_lp2:
+ mov (a0),d1
+ add $4,a0
+
+ mov d1,(a1)
+ add $4,a1
+
+ subl $1,d0
+ jge cp_s_arg_lp2
+
+ pop d1
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_string_constant:
+ movl a1,(a2)
+ add $4,a2
+
+ sub $1,d1
+ jae copy_lp2
+ ret
+
+copy_array_2:
+ push d1
+
+ movl 8(a0),d0
+ test d0,d0
+ je copy_array_a2
+
+ movzwl -2(d0),d1
+
+ test d1,d1
+ je copy_strict_basic_array_2
+
+ subl $256,d1
+ imull 4(a0),d1
+ jmp copy_array_a3
+
+copy_array_a2:
+ movl 4(a0),d1
+copy_array_a3:
+ movl a4,a1
+ lea 12(a4,d1,4),a4
+
+ movl a1,(a2)
+ movl (a0),d0
+
+ addl $4,a2
+ movl d0,(a1)
+
+ lea 1(a1),d0
+ addl $4,a1
+
+ movl d0,(a0)
+ addl $4,a0
+
+ lea 1(d1),d0
+ jmp cp_s_arg_lp2
+
+copy_strict_basic_array_2:
+ movl 4(a0),d1
+ cmpl $INT+2,d0
+ je copy_int_array_2
+
+ cmpl $BOOL+2,d0
+ je copy_bool_array_2
+
+ addl d1,d1
+copy_int_array_2:
+ shl $2,d1
+ lea -12(a3),a1
+
+ subl d1,a1
+ movl (a0),d0
+
+ shr $2,d1
+ movl a1,(a2)
+
+ addl $4,a2
+ movl a1,a3
+
+ movl d0,(a1)
+ lea 1(a1),d0
+
+ addl $4,a1
+ movl d0,(a0)
+
+ addl $4,a0
+ lea 1(d1),d0
+ jmp cp_s_arg_lp2
+
+copy_bool_array_2:
+ lea 3(d1),d0
+ shr $2,d0
+ jmp copy_int_array_2
+
+end_copy1:
+ mov a3,heap_end_after_gc
+ lea -32(a3),a2
+ movl a2,end_heap
+
diff --git a/ifileIO3.s b/ifileIO3.s
new file mode 100644
index 0000000..5ffc0aa
--- /dev/null
+++ b/ifileIO3.s
@@ -0,0 +1,744 @@
+
+#define d0 %eax
+#define d1 %ebx
+#define a0 %ecx
+#define a1 %edx
+#define a2 %ebp
+#define a3 %esi
+#define a4 %edi
+#define a5 %esp
+#define sp %esp
+
+// # saved registers: %ebx %esi %edi %ebp
+// # d1 a3 a4 a2
+
+ .data
+#if defined (DOS) || defined (_WINDOWS_) || defined (ELF)
+ .align 8
+#else
+ .align 3
+#endif
+
+tmp_real: .double 0
+freadstring_error:
+ .ascii "Error in freadsubstring parameters."
+ .byte 10,0
+ .byte 0,0,0
+fwritestring_error:
+ .ascii "Error in fwritesubstring parameters."
+ .byte 10,0
+ .byte 0,0
+ .text
+
+ .globl stdioF
+ .globl stderrF
+ .globl openF
+ .globl closeF
+ .globl reopenF
+ .globl readFC
+ .globl readFI
+ .globl readFR
+ .globl readFS
+#ifndef LINUX
+ .globl readFString
+#endif
+ .globl readLineF
+ .globl writeFC
+ .globl writeFI
+ .globl writeFR
+ .globl writeFS
+#ifndef LINUX
+ .globl writeFString
+#endif
+ .globl endF
+ .globl errorF
+ .globl positionF
+ .globl seekF
+ .globl shareF
+
+ .globl openSF
+ .globl readSFC
+ .globl readSFI
+ .globl readSFR
+ .globl readSFS
+ .globl readLineSF
+ .globl endSF
+ .globl positionSF
+ .globl seekSF
+
+// # imports
+
+ .globl @open_file
+ .globl @open_stdio
+ .globl @open_stderr
+ .globl @re_open_file
+ .globl @close_file
+ .globl @file_read_char
+ .globl @file_read_int
+ .globl @file_read_real
+#ifdef LINUX
+ .globl @file_read_string
+#else
+ .globl @file_read_characters
+#endif
+ .globl @file_read_line
+ .globl @file_write_char
+ .globl @file_write_int
+ .globl @file_write_real
+#ifdef LINUX
+ .globl @file_write_string
+#else
+ .globl @file_write_characters
+#endif
+ .globl @file_end
+ .globl @file_error
+ .globl @file_position
+ .globl @file_seek
+ .globl @file_share
+
+ .globl @open_s_file
+ .globl @file_read_s_char
+ .globl @file_read_s_int
+ .globl @file_read_s_real
+ .globl @file_read_s_string
+ .globl @file_read_s_line
+ .globl @file_s_end
+ .globl @file_s_position
+ .globl @file_s_seek
+
+ .globl collect_0
+ .globl collect_1
+
+ .globl __STRING__
+
+stdioF: call @open_stdio
+ movl d0,d1
+ movl $-1,d0
+ ret
+
+stderrF: call @open_stderr
+ movl d0,d1
+ movl $-1,d0
+ ret
+
+openF: pushl d0
+ addl $4,a0
+ pushl a0
+ call @open_file
+ addl $8,sp
+
+ xorl d1,d1
+ testl d0,d0
+ setns %bl
+ movl (sp),a2
+ movl $-1,(sp)
+ jmp *a2
+
+closeF: pushl d1
+ call @close_file
+ addl $4,sp
+ ret
+
+reopenF:
+// # popl d0
+// # pushl d0
+ pushl d1
+ call @re_open_file
+ addl $8,sp
+
+ xchg d0,d1
+
+ movl (sp),a2
+ movl $-1,(sp)
+ jmp *a2
+
+readFC:
+ pushl d1
+
+ pushl d1
+ call @file_read_char
+ addl $4,sp
+
+ movl 4(sp),a2
+ movl $-1,4(sp)
+
+ cmpl $-1,d0
+ je readFC_eof
+
+ movl $1,d1
+ jmp *a2
+
+readFC_eof:
+ xorl d0,d0
+ xorl d1,d1
+ jmp *a2
+
+readFI:
+ pushl d1
+
+ subl $8,sp
+ lea 4(sp),a2
+ movl a2,(sp)
+ pushl d1
+ call @file_read_int
+ addl $8,sp
+
+ movl d0,d1
+ popl d0
+
+ movl 4(sp),a2
+ movl $-1,4(sp)
+ jmp *a2
+
+readFR:
+ pushl $tmp_real
+ pushl d1
+ finit
+ call @file_read_real
+ addl $8,sp
+
+ fldl tmp_real
+ fstp %st(1)
+
+ xchg d0,d1
+
+ movl (sp),a2
+ movl $-1,(sp)
+ jmp *a2
+
+#ifndef LINUX
+readFString:
+ movl 4(a0),a2
+ cmpl a2,d1
+ jae readFString_error
+
+ subl d1,a2
+ cmpl a2,d0
+ ja readFString_error
+
+ movl (sp),a1
+ pushl a0
+
+ pushl d0
+ movl sp,a2
+ lea 8(a0,d1),a0
+
+ pushl a0
+ pushl a2
+ pushl a1
+ call @file_read_characters
+ addl $12+4,sp
+
+ popl a0
+
+ movl d0,d1
+ popl d0
+
+ addl $4,sp
+ popl a2
+ pushl $-1
+ jmp *a2
+
+readFString_error:
+ movl $freadstring_error,a2
+ jmp print_error
+#endif
+
+readFS: popl a1
+ lea 3(a1),a2
+ andl $-4,a2
+ lea -32+8(a4,a2),a2
+ cmpl end_heap,a2
+ ja readFS_gc
+readFS_r_gc:
+
+#ifdef LINUX
+ movl $__STRING__+2,(a4)
+ addl $4,a4
+
+ pushl a4
+ pushl a1
+ pushl d1
+ call @file_read_string
+ addl $12,sp
+#else
+ movl $__STRING__+2,(a4)
+
+ lea 8(a4),a2
+ addl $4,a4
+
+ pushl a2
+ movl a1,(a4)
+ pushl a4
+ pushl d1
+ call @file_read_characters
+ addl $12,sp
+#endif
+readFS_end:
+ lea -4(a4),a0
+
+ addl $3,d0
+ andl $-4,d0
+ lea 4(a4,d0),a4
+
+ movl $-1,d0
+ ret
+
+readFS_gc: pushl a1
+ call collect_0l
+ popl a1
+ jmp readFS_r_gc
+
+readLineF:
+ lea -32+(4*(32+2))(a4),a2
+ cmpl end_heap,a2
+ ja readLineF_gc
+
+readLineF_r_gc:
+ movl $__STRING__+2,(a4)
+ lea 8(a4),a0
+ addl $4,a4
+
+ pushl a0
+ movl end_heap,a1
+ addl $32-4,a1
+ subl a4,a1
+ pushl a1
+ pushl d1
+ call @file_read_line
+ addl $12,sp
+
+ movl d0,(a4)
+
+ testl d0,d0
+ jns readFS_end
+
+ lea -4(a4),a0
+
+readLineF_again:
+ movl end_heap,a1
+ addl $32,a1
+ lea -8(a1),d0
+ subl a0,d0
+ movl d0,4(a0)
+ movl a1,a4
+
+ lea -32+4*(32+2)(a4,d0),a2
+ call collect_1l
+
+ movl 4(a0),d0
+ lea 8(a0),a1
+
+ pushl a4
+
+ movl $__STRING__+2,(a4)
+
+ lea 3(d0),a0
+ shr $2,a0
+
+ movl d0,4(a4)
+ addl $8,a4
+ jmp st_copy_string1
+
+copy_st_lp1:
+ movl (a1),a2
+ addl $4,a1
+ movl a2,(a4)
+ addl $4,a4
+st_copy_string1:
+ subl $1,a0
+ jnc copy_st_lp1
+
+ pushl a4
+ movl end_heap,a2
+ addl $32,a2
+ subl a4,a2
+ pushl a2
+ pushl d1
+ call @file_read_line
+ addl $12,sp
+
+ popl a0
+
+ testl d0,d0
+ js readLineF_again
+
+ addl d0,4(a0)
+ addl $3,d0
+ andl $-4,d0
+ addl d0,a4
+
+ movl $-1,d0
+ ret
+
+readLineF_gc:
+ call collect_0l
+ jmp readLineF_r_gc
+
+writeFC:
+ movl d0,(sp)
+ pushl d1
+ movl d0,d1
+ call @file_write_char
+ addl $8,sp
+
+ movl $-1,d0
+ ret
+
+writeFI:
+ movl d0,(sp)
+ pushl d1
+ movl d0,d1
+ call @file_write_int
+ addl $8,sp
+
+ movl $-1,d0
+ ret
+
+writeFR:
+ pushl d1
+ subl $8,sp
+ fstpl (sp)
+ finit
+ call @file_write_real
+ addl $12,sp
+
+ movl $-1,d0
+ ret
+
+writeFS:
+ pushl d1
+#ifdef LINUX
+ addl $4,a0
+ pushl a0
+ call @file_write_string
+ addl $8,sp
+#else
+ pushl 4(a0)
+ addl $8,a0
+ pushl a0
+ call @file_write_characters
+ addl $12,sp
+#endif
+ movl $-1,d0
+ ret
+
+#ifndef LINUX
+writeFString:
+ movl 4(a0),a2
+ cmpl a2,d1
+ jae writeFString_error
+
+ subl d1,a2
+ cmpl a2,d0
+ ja writeFString_error
+
+ lea 8(a0,d1),a0
+ movl (sp),d1
+
+ pushl d0
+ pushl a0
+ call @file_write_characters
+ addl $12+4,sp
+
+ movl $-1,d0
+
+ ret
+
+writeFString_error:
+ movl $fwritestring_error,a2
+ jmp print_error
+#endif
+
+endF:
+ pushl d1
+ call @file_end
+ addl $4,sp
+
+ xchg d0,d1
+
+ movl (sp),a2
+ movl $-1,(sp)
+ jmp *a2
+
+errorF:
+ pushl d1
+ call @file_error
+ addl $4,sp
+
+ xchg d0,d1
+
+ movl (sp),a2
+ movl $-1,(sp)
+ jmp *a2
+
+positionF:
+ pushl d1
+ call @file_position
+ addl $4,sp
+
+ xchg d0,d1
+
+ movl (sp),a2
+ movl $-1,(sp)
+ jmp *a2
+
+seekF:
+ pushl d1
+ call @file_seek
+ addl $12,sp
+
+ xchg d0,d1
+
+ movl (sp),a2
+ movl $-1,(sp)
+ jmp *a2
+
+shareF:
+ pushl d1
+ call @file_share
+ addl $4,sp
+
+ movl $-1,d0
+ ret
+
+openSF: pushl d0
+ addl $4,a0
+ pushl a0
+ call @open_s_file
+ addl $8,sp
+
+ xorl d1,d1
+ testl d0,d0
+ setns %bl
+
+ movl (sp),a2
+ movl $0,(sp)
+ jmp *a2
+
+readSFC:
+ pushl d0
+ movl sp,a2
+ pushl a2
+ pushl d1
+ call @file_read_s_char
+ addl $8,sp
+
+ popl a0
+ popl a2
+
+ pushl a0
+ pushl d1
+
+ cmpl $-1,d0
+ je readSFC_eof
+
+ movl $1,d1
+ jmp *a2
+
+readSFC_eof:
+ xorl d0,d0
+ xorl d1,d1
+ jmp *a2
+
+readSFI:
+ pushl d0
+ movl sp,a2
+ subl $4,sp
+ pushl a2
+ subl $4,a2
+ pushl a2
+ pushl d1
+ call @file_read_s_int
+ addl $12,sp
+
+ popl a0
+ popl a1
+ popl a2
+
+ pushl a1
+ pushl d1
+ movl d0,d1
+ movl a0,d0
+ jmp *a2
+
+readSFR:
+ pushl d0
+ movl sp,a2
+ pushl a2
+ pushl $tmp_real
+ pushl d1
+ finit
+ call @file_read_s_real
+ addl $12,sp
+
+ fldl tmp_real
+ xchg d0,d1
+ fstp %st(1)
+
+ popl a0
+ movl (sp),a2
+ movl a0,(sp)
+ jmp *a2
+
+readSFS:
+ popl a1
+ lea 3(a1),a2
+ andl $-4,a2
+ lea -32+8(a4,a2),a2
+ cmpl end_heap,a2
+ ja readSFS_gc
+
+readSFS_r_gc:
+ movl $__STRING__+2,(a4)
+ addl $4,a4
+
+ pushl d0
+ movl sp,a2
+ pushl a2
+ pushl a4
+ pushl a1
+ pushl d1
+ call @file_read_s_string
+ addl $16,sp
+
+readSFS_end:
+ lea -4(a4),a0
+
+ addl $3,d0
+ andl $-4,d0
+ lea 4(a4,d0),a4
+
+ popl d0
+ ret
+
+readSFS_gc: pushl a1
+ call collect_0l
+ popl a1
+ jmp readSFS_r_gc
+
+readLineSF:
+ lea -32+(4*(32+2))(a4),a2
+ cmpl end_heap,a2
+ ja readLineSF_gc
+
+readLineSF_r_gc:
+ movl $__STRING__+2,(a4)
+ lea 8(a4),a0
+ addl $4,a4
+
+ pushl d0
+ movl sp,a2
+ pushl a2
+ pushl a0
+ movl end_heap,a1
+ addl $32-4,a1
+ subl a4,a1
+ pushl a1
+ pushl d1
+ call @file_read_s_line
+ addl $16,sp
+
+ movl d0,(a4)
+
+ testl d0,d0
+ jns readSFS_end
+
+ lea -4(a4),a0
+
+readLineSF_again:
+ movl end_heap,a1
+ addl $32,a1
+ lea -8(a1),d0
+ subl a0,d0
+ movl d0,(a4)
+ movl a1,a4
+
+ lea -32+4*(32+2)(a4,d0),a2
+ call collect_1l
+
+ movl 4(a0),d0
+ lea 8(a0),a1
+
+ pushl a4
+
+ movl $__STRING__+2,(a4)
+
+ lea 3(d0),a0
+ shr $2,a0
+
+ movl d0,4(a4)
+ addl $8,a4
+ jmp st_copy_string2
+
+copy_st_lp2:
+ movl (a1),a2
+ addl $4,a1
+ movl a2,(a4)
+ addl $4,a4
+st_copy_string2:
+ subl $1,a0
+ jnc copy_st_lp2
+
+ lea 4(sp),a2
+ pushl a2
+ pushl a4
+ movl end_heap,a2
+ addl $32,a2
+ subl a4,a2
+ pushl a2
+ pushl d1
+ call @file_read_s_line
+ addl $16,sp
+
+ popl a0
+
+ testl d0,d0
+ js readLineSF_again
+
+ addl d0,4(a0)
+ addl $3,d0
+ andl $-4,d0
+ addl d0,a4
+
+ popl d0
+ ret
+
+readLineSF_gc:
+ call collect_0l
+ jmp readLineSF_r_gc
+
+endSF:
+ pushl d0
+ pushl d1
+ call @file_s_end
+ addl $8,sp
+ ret
+
+positionSF:
+ pushl d0
+ pushl d1
+ call @file_s_position
+ addl $8,sp
+ ret
+
+seekSF:
+ popl a1
+ popl a0
+
+ pushl d0
+ movl sp,a2
+ pushl a2
+ pushl a0
+ pushl a1
+ pushl d1
+ call @file_s_seek
+ addl $16,sp
+
+ popl a0
+
+ xchg d0,d1
+
+ movl (sp),a2
+ movl a0,(sp)
+ jmp *a2
diff --git a/imark.s b/imark.s
new file mode 100644
index 0000000..973a38a
--- /dev/null
+++ b/imark.s
@@ -0,0 +1,1880 @@
+
+#define d0 %eax
+#define d1 %ebx
+#define a0 %ecx
+#define a1 %edx
+#define a2 %ebp
+#define a3 %esi
+#define a4 %edi
+#define sp %esp
+
+#undef COUNT_GARBAGE_COLLECTIONS
+#undef MARK_USING_REVERSAL
+#undef COMPARE_HEAP_AFTER_MARK
+#undef DEBUG_MARK_COLLECT
+
+#ifdef COMPARE_HEAP_AFTER_MARK
+ .data
+heap_copy: .long 0
+ .text
+ pushl d0
+ pushl d1
+ pushl a0
+ pushl a1
+ pushl a2
+ pushl a3
+ pushl a4
+
+ movl heap_size_33,d0
+ shl $5,d0
+ pushl d0
+ call @allocate_memory
+ addl $4,sp
+
+ movl d0,heap_copy
+
+ testl d0,d0
+ je no_copy
+
+ movl heap_p3,a0
+ movl heap_size_33,d1
+ shl $3,d1
+ jmp start_copy
+
+copy_heap_lp:
+ movl (a0),a2
+ addl $4,a0
+ movl a2,(d0)
+ addl $4,d0
+start_copy:
+ subl $1,d1
+ jge copy_heap_lp
+
+no_copy:
+ popl a4
+ popl a3
+ popl a2
+ popl a1
+ popl a0
+ popl d1
+ popl a0
+#endif
+
+ movl heap_size_33,d0
+ xorl d1,d1
+
+ movl d1,n_marked_words
+ shl $5,d0
+
+ movl d0,heap_size_32_33
+ movl d1,lazy_array_list
+
+ lea -2000(sp),a3
+
+ movl caf_list,d0
+
+ movl a3,end_stack
+
+ test d0,d0
+ je _end_mark_cafs
+
+_mark_cafs_lp:
+ movl (d0),d1
+ movl -4(d0),a2
+
+ pushl a2
+ lea 4(d0),a2
+ lea 4(d0,d1,4),d0
+ movl d0,end_vector
+
+ call _mark_stack_nodes
+
+ popl d0
+ test d0,d0
+ jne _mark_cafs_lp
+
+_end_mark_cafs:
+ movl stack_top,a3
+ movl stack_p,a2
+
+ movl a3,end_vector
+ call _mark_stack_nodes
+
+ movl lazy_array_list,a0
+
+ test a0,a0
+ je end_restore_arrays
+
+restore_arrays:
+ movl (a0),d1
+ movl $__ARRAY__+2,(a0)
+
+ cmpl $1,d1
+ je restore_array_size_1
+
+ lea (a0,d1,4),a1
+ movl 8(a1),d0
+ test d0,d0
+ je restore_lazy_array
+
+ movl d0,a2
+ push a1
+
+ xorl a1,a1
+ movl d1,d0
+ movzwl -2+2(a2),d1
+
+ div d1
+ movl d0,d1
+
+ pop a1
+ movl a2,d0
+
+restore_lazy_array:
+ movl 8(a0),a4
+ movl 4(a0),a2
+ movl d1,4(a0)
+ movl 4(a1),a3
+ movl d0,8(a0)
+ movl a2,4(a1)
+ movl a4,8(a1)
+
+ test d0,d0
+ je no_reorder_array
+
+ movzwl -2(d0),a1
+ subl $256,a1
+ movzwl -2+2(d0),a2
+ cmpl a1,a2
+ je no_reorder_array
+
+ addl $12,a0
+ imull a1,d1
+ movl a1,d0
+ lea (a0,d1,4),a1
+ movl a2,d1
+ subl a2,d0
+
+ call reorder
+
+no_reorder_array:
+ movl a3,a0
+ testl a0,a0
+ jne restore_arrays
+
+ jmp end_restore_arrays
+
+restore_array_size_1:
+ movl 4(a0),a2
+ movl 8(a0),a1
+ movl d1,4(a0)
+ movl 12(a0),d0
+ movl a2,12(a0)
+ movl d0,8(a0)
+
+ movl a1,a0
+ testl a0,a0
+ jne restore_arrays
+
+end_restore_arrays:
+ call add_garbage_collect_time
+
+
+#ifdef COMPARE_HEAP_AFTER_MARK
+ pushl d0
+ pushl d1
+ pushl a0
+ pushl a1
+ pushl a2
+ pushl a3
+ pushl a4
+
+ movl heap_copy,d0
+
+ testl d0,d0
+ je no_compare
+
+ movl heap_p3,a0
+ movl heap_size_33,d1
+ shl $3,d1
+ jmp start_compare
+
+compare_heap_lp:
+ movl (a0),a2
+ cmpl a2,(d0)
+ je no_change
+ nop
+no_change:
+ addl $4,a0
+ addl $4,d0
+start_compare:
+ subl $1,d1
+ jge compare_heap_lp
+
+ pushl heap_copy
+ call @free_memory
+ addl $4,sp
+
+no_compare:
+
+ popl a4
+ popl a3
+ popl a2
+ popl a1
+ popl a0
+ popl d1
+ popl a0
+#endif
+
+
+#ifdef ADJUST_HEAP_SIZE
+ movl bit_vector_size,d0
+#else
+ movl heap_size_33,d0
+ shl $3,d0
+#endif
+
+#ifdef ADJUST_HEAP_SIZE
+ movl n_allocated_words,a4
+ addl n_marked_words,a4
+ shl $2,a4
+
+ movl d0,a3
+ shl $2,a3
+
+ push a1
+ push d0
+
+ movl a4,d0
+ mull @heap_size_multiple
+ shrd $8,a1,d0
+ shrl $8,a1
+
+ movl d0,d1
+ testl a1,a1
+
+ pop d0
+ pop a1
+
+ je not_largest_heap
+
+ movl heap_size_33,d1
+ shl $5,d1
+
+not_largest_heap:
+ cmpl a3,d1
+ jbe no_larger_heap
+
+ movl heap_size_33,a3
+ shl $5,a3
+ cmpl a3,d1
+ jbe not_larger_then_heap
+ movl a3,d1
+not_larger_then_heap:
+ movl d1,d0
+ shr $2,d0
+ movl d0,bit_vector_size
+no_larger_heap:
+#endif
+ movl d0,a2
+
+ movl heap_vector,a4
+
+ shrl $5,a2
+
+ testb $31,d0
+ je no_extra_word
+
+ movl $0,(a4,a2,4)
+
+no_extra_word:
+ subl n_marked_words,d0
+ shl $2,d0
+ movl d0,n_last_heap_free_bytes
+
+#ifdef COUNT_GARBAGE_COLLECTIONS
+ addl $1,n_garbage_collections
+#endif
+#ifdef MEASURE_GC
+ movl n_marked_words,d0
+ shl $2,d0
+ addl d0,total_gc_bytes_lo
+ jnc no_total_gc_bytes_carry2
+ incl total_gc_bytes_hi
+no_total_gc_bytes_carry2:
+#endif
+
+ testl $2,@flags
+ je _no_heap_use_message2
+
+ pushl $marked_gc_string_1
+ call @ew_print_string
+ addl $4,sp
+
+ movl n_marked_words,d0
+ shll $2,d0
+ pushl d0
+ call @ew_print_int
+ addl $4,sp
+
+ pushl $heap_use_after_gc_string_2
+ call @ew_print_string
+ addl $4,sp
+
+_no_heap_use_message2:
+ movl n_allocated_words,a3
+ xorl d1,d1
+
+ movl a4,a0
+ movl d1,n_free_words_after_mark
+
+_scan_bits:
+ cmpl (a0),d1
+ je _zero_bits
+ movl d1,(a0)
+ addl $4,a0
+ subl $1,a2
+ jne _scan_bits
+
+ jmp _end_scan
+
+_zero_bits:
+ lea 4(a0),a1
+ addl $4,a0
+ subl $1,a2
+ jne _skip_zero_bits_lp1
+ jmp _end_bits
+
+_skip_zero_bits_lp:
+ test d0,d0
+ jne _end_zero_bits
+_skip_zero_bits_lp1:
+ movl (a0),d0
+ addl $4,a0
+ subl $1,a2
+ jne _skip_zero_bits_lp
+
+ test d0,d0
+ je _end_bits
+ movl a0,d0
+ movl d1,-4(a0)
+ subl a1,d0
+ jmp _end_bits2
+
+_end_zero_bits:
+ movl a0,d0
+ subl a1,d0
+ shl $3,d0
+ addl d0,n_free_words_after_mark
+ movl d1,-4(a0)
+
+ cmpl a3,d0
+ jb _scan_bits
+
+_found_free_memory:
+ movl a2,bit_counter
+ movl a0,bit_vector_p
+
+ lea -4(a1),d1
+ subl a4,d1
+ shl $5,d1
+ movl heap_p3,a4
+ addl d1,a4
+
+ movl stack_top,a3
+
+ lea (a4,d0,4),d1
+ movl d1,heap_end_after_gc
+ subl $32,d1
+ movl d1,end_heap
+
+ pop d1
+ pop d0
+ ret
+
+_end_bits:
+ movl a0,d0
+ subl a1,d0
+ addl $4,d0
+_end_bits2:
+ shl $3,d0
+ addl d0,n_free_words_after_mark
+ cmpl a3,d0
+ jae _found_free_memory
+
+_end_scan:
+ movl a2,bit_counter
+ jmp compact_gc
+
+/ a2: pointer to stack element
+/ a4: heap_vector
+/ d0,d1,a0,a1,a3: free
+
+_mark_stack_nodes:
+ cmpl end_vector,a2
+ je _end_mark_nodes
+_mark_stack_nodes_:
+ movl (a2),a0
+ movl neg_heap_p3,a1
+
+ addl $4,a2
+ addl a0,a1
+#ifdef SHARE_CHAR_INT
+ cmpl heap_size_32_33,a1
+ jnc _mark_stack_nodes
+#endif
+ movl a1,d1
+ andl $31*4,a1
+ shrl $7,d1
+ movl bit_set_table(a1),a3
+
+ testl (a4,d1,4),a3
+ jne _mark_stack_nodes
+
+ pushl a2
+
+#ifdef MARK_USING_REVERSAL
+ movl $1,a3
+ jmp __mark_node
+
+__end_mark_using_reversal:
+ popl a2
+ movl a0,-4(a2)
+ jmp _mark_stack_nodes
+#else
+ pushl $0
+
+ jmp _mark_arguments
+
+_mark_hnf_2:
+ cmpl $0x20000000,a3
+ jbe fits_in_word_6
+ orl $1,4(a4,d1,4)
+fits_in_word_6:
+ addl $3,n_marked_words
+
+_mark_record_2_c:
+ movl 4(a0),d1
+ push d1
+
+ cmpl end_stack,sp
+ jb __mark_using_reversal
+
+_mark_node2:
+_shared_argument_part:
+ movl (a0),a0
+
+_mark_node:
+ movl neg_heap_p3,a1
+# ifdef SHARE_CHAR_INT
+ movl heap_size_32_33,d1
+# endif
+ addl a0,a1
+# ifdef SHARE_CHAR_INT
+ cmpl d1,a1
+ jnc _mark_next_node
+# endif
+ movl a1,d1
+ andl $31*4,a1
+ shrl $7,d1
+ movl bit_set_table(a1),a3
+
+ testl (a4,d1,4),a3
+ jne _mark_next_node
+
+_mark_arguments:
+ movl (a0),d0
+ test $2,d0
+ je _mark_lazy_node
+
+ movzwl -2(d0),a2
+
+ test a2,a2
+ je _mark_hnf_0
+
+ orl a3,(a4,d1,4)
+ addl $4,a0
+
+ cmpl $256,a2
+ jae _mark_record
+
+ subl $2,a2
+ je _mark_hnf_2
+ jb _mark_hnf_1
+
+_mark_hnf_3:
+ movl 4(a0),a1
+
+ cmpl $0x20000000,a3
+ jbe fits_in_word_1
+ orl $1,4(a4,d1,4)
+fits_in_word_1:
+
+ movl neg_heap_p3,d0
+ movl n_marked_words,a3
+ addl a1,d0
+ addl $3,a3
+ movl d0,d1
+ andl $31*4,d0
+
+ shrl $7,d1
+ movl a3,n_marked_words
+
+ movl bit_set_table(d0),a3
+
+ testl (a4,d1,4),a3
+ jne _shared_argument_part
+
+_no_shared_argument_part:
+ orl a3,(a4,d1,4)
+ addl $1,a2
+
+ addl a2,n_marked_words
+ lea (d0,a2,4),d0
+ lea -4(a1,a2,4),a1
+
+ cmpl $32*4,d0
+ jbe fits_in_word_2
+ orl $1,4(a4,d1,4)
+fits_in_word_2:
+
+ movl (a1),d1
+ subl $2,a2
+ pushl d1
+
+_push_hnf_args:
+ movl -4(a1),d1
+ subl $4,a1
+ pushl d1
+ subl $1,a2
+ jge _push_hnf_args
+
+ cmpl end_stack,sp
+ jae _mark_node2
+
+ jmp __mark_using_reversal
+
+_mark_hnf_1:
+ cmpl $0x40000000,a3
+ jbe fits_in_word_4
+ orl $1,4(a4,d1,4)
+fits_in_word_4:
+ addl $2,n_marked_words
+ movl (a0),a0
+ jmp _mark_node
+
+_mark_lazy_node_1:
+ addl $4,a0
+ orl a3,(a4,d1,4)
+ cmpl $0x20000000,a3
+ jbe fits_in_word_3
+ orl $1,4(a4,d1,4)
+fits_in_word_3:
+ addl $3,n_marked_words
+
+ cmpl $1,a2
+ je _mark_node2
+
+_mark_selector_node_1:
+ addl $2,a2
+ movl (a0),a1
+ je _mark_indirection_node
+
+ movl neg_heap_p3,a3
+ addl a1,a3
+ movl a3,d1
+
+ shrl $7,d1
+ andl $31*4,a3
+
+ addl $1,a2
+
+ movl bit_set_table(a3),a3
+ jle _mark_record_selector_node_1
+
+ testl (a4,d1,4),a3
+ jne _mark_node3
+
+ movl (a1),a2
+ testl $2,a2
+ je _mark_node3
+
+ cmpw $2,-2(a2)
+ jbe _small_tuple_or_record
+
+_large_tuple_or_record:
+ movl 8(a1),a2
+ addl neg_heap_p3,a2
+ movl a2,d1
+ andl $31*4,a2
+ shrl $7,d1
+ movl bit_set_table(a2),a2
+ testl (a4,d1,4),a2
+ jne _mark_node3
+
+_small_tuple_or_record:
+ movl -8(d0),d0
+ pushl a0
+ movl a1,a0
+ call *4(d0)
+ popl a1
+
+ movl $__indirection,-4(a1)
+ movl a0,(a1)
+ jmp _mark_node
+
+_mark_record_selector_node_1:
+ je _mark_strict_record_selector_node_1
+
+ testl (a4,d1,4),a3
+ jne _mark_node3
+
+ movl (a1),a2
+ testl $2,a2
+ je _mark_node3
+
+ cmpw $258,-2(a2)
+ jbe _small_tuple_or_record
+ jmp _large_tuple_or_record
+
+_mark_strict_record_selector_node_1:
+ testl (a4,d1,4),a3
+ jne _mark_node3
+
+ movl (a1),a2
+ testl $2,a2
+ je _mark_node3
+
+ cmpw $258,-2(a2)
+ jbe _select_from_small_record
+
+ movl 8(a1),a2
+ addl neg_heap_p3,a2
+ movl a2,d1
+ andl $31*4,a2
+ shrl $7,d1
+ movl bit_set_table(a2),a2
+ testl (a4,d1,4),a2
+ jne _mark_node3
+
+_select_from_small_record:
+ movl -8(d0),d0
+ subl $4,a0
+
+ call *4(d0)
+
+ jmp _mark_next_node
+
+_mark_indirection_node:
+_mark_node3:
+ movl a1,a0
+ jmp _mark_node
+
+_mark_next_node:
+ popl a0
+ test a0,a0
+ jne _mark_node
+
+ popl a2
+ cmpl end_vector,a2
+ jne _mark_stack_nodes_
+
+_end_mark_nodes:
+ ret
+
+_mark_lazy_node:
+ movl -4(d0),a2
+ test a2,a2
+ je _mark_real_or_file
+
+ cmpl $1,a2
+ jle _mark_lazy_node_1
+
+ cmpl $256,a2
+ jge _mark_closure_with_unboxed_arguments
+ incl a2
+ orl a3,(a4,d1,4)
+
+ addl a2,n_marked_words
+ lea (a1,a2,4),a1
+ lea (a0,a2,4),a0
+
+ cmpl $32*4,a1
+ jbe fits_in_word_7
+ orl $1,4(a4,d1,4)
+fits_in_word_7:
+ subl $3,a2
+_push_lazy_args:
+ movl -4(a0),d1
+ subl $4,a0
+ push d1
+ subl $1,a2
+ jge _push_lazy_args
+
+ subl $4,a0
+
+ cmpl end_stack,sp
+ jae _mark_node2
+
+ jmp __mark_using_reversal
+
+_mark_closure_with_unboxed_arguments:
+ movl a2,d0
+ andl $255,a2
+ subl $1,a2
+ je _mark_real_or_file
+
+ shrl $8,d0
+ addl $2,a2
+
+ orl a3,(a4,d1,4)
+ addl a2,n_marked_words
+ lea (a1,a2,4),a1
+
+ subl d0,a2
+
+ cmpl $32*4,a1
+ jbe fits_in_word_7_
+ orl $1,4(a4,d1,4)
+fits_in_word_7_:
+ subl $2,a2
+ jl _mark_next_node
+
+ lea 8(a0,a2,4),a0
+ jne _push_lazy_args
+
+_mark_closure_with_one_boxed_argument:
+ movl -4(a0),a0
+ jmp _mark_node
+
+_mark_hnf_0:
+ cmpl $INT+2,d0
+ jb _mark_real_file_or_string
+
+ orl a3,(a4,d1,4)
+
+ cmpl $CHAR+2,d0
+ ja _mark_normal_hnf_0
+
+_mark_bool:
+ addl $2,n_marked_words
+
+ cmpl $0x40000000,a3
+ jbe _mark_next_node
+
+ orl $1,4(a4,d1,4)
+ jmp _mark_next_node
+
+_mark_normal_hnf_0:
+ incl n_marked_words
+ jmp _mark_next_node
+
+_mark_real_file_or_string:
+ cmpl $__STRING__+2,d0
+ jbe _mark_string_or_array
+
+_mark_real_or_file:
+ orl a3,(a4,d1,4)
+ addl $3,n_marked_words
+
+ cmpl $0x20000000,a3
+ jbe _mark_next_node
+
+ orl $1,4(a4,d1,4)
+ jmp _mark_next_node
+
+_mark_record:
+ subl $258,a2
+ je _mark_record_2
+ jl _mark_record_1
+
+_mark_record_3:
+ addl $3,n_marked_words
+
+ cmpl $0x20000000,a3
+ jbe fits_in_word_13
+ orl $1,4(a4,d1,4)
+fits_in_word_13:
+ movl 4(a0),a1
+ movl neg_heap_p3,a3
+
+ movzwl -2+2(d0),d1
+ addl a1,a3
+
+ movl a3,d0
+ andl $31*4,a3
+
+ shrl $7,d0
+ subl $1,d1
+
+ movl bit_set_table(a3),a1
+ jb _mark_record_3_bb
+
+ testl (a4,d0,4),a1
+ jne _mark_node2
+
+ addl $1,a2
+ orl a1,(a4,d0,4)
+ addl a2,n_marked_words
+ lea (a3,a2,4),a3
+
+ cmpl $32*4,a3
+ jbe _push_record_arguments
+ orl $1,4(a4,d0,4)
+_push_record_arguments:
+ movl 4(a0),a1
+ movl d1,a2
+ shl $2,d1
+ addl d1,a1
+ subl $1,a2
+ jge _push_hnf_args
+
+ jmp _mark_node2
+
+_mark_record_3_bb:
+ testl (a4,d0,4),a1
+ jne _mark_next_node
+
+ addl $1,a2
+ orl a1,(a4,d0,4)
+ addl a2,n_marked_words
+ lea (a3,a2,4),a3
+
+ cmpl $32*4,a3
+ jbe _mark_next_node
+
+ orl $1,4(a4,d0,4)
+ jmp _mark_next_node
+
+_mark_record_2:
+ cmpl $0x20000000,a3
+ jbe fits_in_word_12
+ orl $1,4(a4,d1,4)
+fits_in_word_12:
+ addl $3,n_marked_words
+
+ cmpw $1,-2+2(d0)
+ ja _mark_record_2_c
+ je _mark_node2
+ jmp _mark_next_node
+
+_mark_record_1:
+ cmpw $0,-2+2(d0)
+ jne _mark_hnf_1
+
+ jmp _mark_bool
+
+_mark_string_or_array:
+ je _mark_string_
+
+_mark_array:
+ movl 8(a0),a2
+ test a2,a2
+ je _mark_lazy_array
+
+ movzwl -2(a2),d0
+
+ testl d0,d0
+ je _mark_strict_basic_array
+
+ movzwl -2+2(a2),a2
+ testl a2,a2
+ je _mark_b_record_array
+
+ cmpl end_stack,sp
+ jb _mark_array_using_reversal
+
+ subl $256,d0
+ cmpl a2,d0
+ je _mark_a_record_array
+
+_mark_ab_record_array:
+ orl a3,(a4,d1,4)
+ movl 4(a0),a2
+
+ imull a2,d0
+ addl $3,d0
+
+ addl d0,n_marked_words
+ lea -4(a0,d0,4),d0
+
+ addl neg_heap_p3,d0
+ shrl $7,d0
+
+ cmpl d0,d1
+ jae _end_set_ab_array_bits
+
+ incl d1
+ movl $1,a2
+ cmpl d0,d1
+ jae _last_ab_array_bits
+
+_mark_ab_array_lp:
+ orl a2,(a4,d1,4)
+ incl d1
+ cmpl d0,d1
+ jb _mark_ab_array_lp
+
+_last_ab_array_bits:
+ orl a2,(a4,d1,4)
+
+_end_set_ab_array_bits:
+ movl 4(a0),d0
+ movl 8(a0),a1
+ movzwl -2+2(a1),d1
+ movzwl -2(a1),a1
+ shll $2,d1
+ lea -1024(,a1,4),a1
+ pushl d1
+ pushl a1
+ lea 12(a0),a2
+ pushl end_vector
+ jmp _mark_ab_array_begin
+
+_mark_ab_array:
+ movl 8(sp),d1
+ pushl d0
+ pushl a2
+ lea (a2,d1),d0
+
+ movl d0,end_vector
+ call _mark_stack_nodes
+
+ movl 4+8(sp),d1
+ popl a2
+ popl d0
+ addl d1,a2
+_mark_ab_array_begin:
+ subl $1,d0
+ jnc _mark_ab_array
+
+ popl end_vector
+ addl $8,sp
+ jmp _mark_next_node
+
+_mark_a_record_array:
+ orl a3,(a4,d1,4)
+ movl 4(a0),a2
+
+ imull a2,d0
+ pushl d0
+
+ addl $3,d0
+
+ addl d0,n_marked_words
+ lea -4(a0,d0,4),d0
+
+ addl neg_heap_p3,d0
+ shrl $7,d0
+
+ cmpl d0,d1
+ jae _end_set_a_array_bits
+
+ incl d1
+ movl $1,a2
+ cmpl d0,d1
+ jae _last_a_array_bits
+
+_mark_a_array_lp:
+ orl a2,(a4,d1,4)
+ incl d1
+ cmpl d0,d1
+ jb _mark_a_array_lp
+
+_last_a_array_bits:
+ orl a2,(a4,d1,4)
+
+_end_set_a_array_bits:
+ popl d0
+ lea 12(a0),a2
+
+ pushl end_vector
+ lea 12(a0,d0,4),d0
+
+ movl d0,end_vector
+ call _mark_stack_nodes
+
+ popl end_vector
+ jmp _mark_next_node
+
+_mark_lazy_array:
+ cmpl end_stack,sp
+ jb _mark_array_using_reversal
+
+ orl a3,(a4,d1,4)
+ movl 4(a0),d0
+
+ addl $3,d0
+
+ addl d0,n_marked_words
+ lea -4(a0,d0,4),d0
+
+ addl neg_heap_p3,d0
+ shrl $7,d0
+
+ cmpl d0,d1
+ jae _end_set_lazy_array_bits
+
+ incl d1
+ movl $1,a2
+ cmpl d0,d1
+ jae _last_lazy_array_bits
+
+_mark_lazy_array_lp:
+ orl a2,(a4,d1,4)
+ incl d1
+ cmpl d0,d1
+ jb _mark_lazy_array_lp
+
+_last_lazy_array_bits:
+ orl a2,(a4,d1,4)
+
+_end_set_lazy_array_bits:
+ movl 4(a0),d0
+ lea 12(a0),a2
+
+ pushl end_vector
+ lea 12(a0,d0,4),d0
+
+ movl d0,end_vector
+ call _mark_stack_nodes
+
+ popl end_vector
+ jmp _mark_next_node
+
+_mark_array_using_reversal:
+ pushl $0
+ movl $1,a3
+ jmp __mark_node
+
+_mark_strict_basic_array:
+ movl 4(a0),d0
+ cmpl $INT+2,a2
+ je _mark_strict_int_array
+ cmpl $BOOL+2,a2
+ je _mark_strict_bool_array
+_mark_strict_real_array:
+ addl d0,d0
+_mark_strict_int_array:
+ addl $3,d0
+ jmp _mark_basic_array_
+_mark_strict_bool_array:
+ addl $12+3,d0
+ shrl $2,d0
+ jmp _mark_basic_array_
+
+_mark_b_record_array:
+ movl 4(a0),a2
+ subl $256,d0
+ imull a2,d0
+ addl $3,d0
+ jmp _mark_basic_array_
+
+_mark_string_:
+ movl 4(a0),d0
+ addl $8+3,d0
+ shrl $2,d0
+
+_mark_basic_array_:
+ orl a3,(a4,d1,4)
+
+ addl d0,n_marked_words
+ lea -4(a0,d0,4),d0
+
+ addl neg_heap_p3,d0
+ shrl $7,d0
+
+ cmpl d0,d1
+ jae _mark_next_node
+
+ incl d1
+ movl $1,a2
+ cmpl d0,d1
+ jae _last_string_bits
+
+_mark_string_lp:
+ orl a2,(a4,d1,4)
+ incl d1
+ cmpl d0,d1
+ jb _mark_string_lp
+
+_last_string_bits:
+ orl a2,(a4,d1,4)
+ jmp _mark_next_node
+
+__end_mark_using_reversal:
+ popl a1
+ test a1,a1
+ je _mark_next_node
+ movl a0,(a1)
+ jmp _mark_next_node
+#endif
+
+__mark_using_reversal:
+ pushl a0
+ movl $1,a3
+ movl (a0),a0
+ jmp __mark_node
+
+__mark_arguments:
+ movl (a0),d0
+ testb $2,d0
+ je __mark_lazy_node
+
+ movzwl -2(d0),a2
+ testl a2,a2
+ je __mark_hnf_0
+
+ addl $4,a0
+
+ cmpl $256,a2
+ jae __mark__record
+
+ subl $2,a2
+ je __mark_hnf_2
+ jb __mark_hnf_1
+
+__mark_hnf_3:
+ movl bit_set_table(a1),a1
+ addl $3,n_marked_words
+
+ orl a1,(a4,d1,4)
+
+ cmpl $0x20000000,a1
+
+ movl neg_heap_p3,d0
+
+ jbe fits__in__word__1
+ orl $1,4(a4,d1,4)
+fits__in__word__1:
+ addl 4(a0),d0
+
+ movl d0,d1
+ andl $31*4,d0
+
+ shrl $7,d1
+
+ movl bit_set_table(d0),a1
+ testl (a4,d1,4),a1
+ jne __shared_argument_part
+
+__no_shared_argument_part:
+ orl a1,(a4,d1,4)
+ movl 4(a0),a1
+
+ addl $1,a2
+ movl a3,4(a0)
+
+ addl a2,n_marked_words
+ addl $4,a0
+
+ shl $2,a2
+ orl $1,(a1)
+
+ addl a2,d0
+ addl a2,a1
+
+ cmpl $32*4,d0
+ jbe fits__in__word__2
+ orl $1,4(a4,d1,4)
+fits__in__word__2:
+
+ movl -4(a1),a2
+ movl a0,-4(a1)
+ lea -4(a1),a3
+ movl a2,a0
+ jmp __mark_node
+
+__mark_hnf_1:
+ movl bit_set_table(a1),a1
+ addl $2,n_marked_words
+ orl a1,(a4,d1,4)
+ cmpl $0x40000000,a1
+ jbe __shared_argument_part
+ orl $1,4(a4,d1,4)
+__shared_argument_part:
+ movl (a0),a2
+ movl a3,(a0)
+ lea 2(a0),a3
+ movl a2,a0
+ jmp __mark_node
+
+__mark_no_selector_2:
+ popl d1
+__mark_no_selector_1:
+ movl bit_set_table(a1),a1
+ addl $3,n_marked_words
+ orl a1,(a4,d1,4)
+ cmpl $0x20000000,a1
+ jbe __shared_argument_part
+
+ orl $1,4(a4,d1,4)
+ jmp __shared_argument_part
+
+__mark_lazy_node_1:
+#ifdef COMPARE_HEAP_AFTER_MARK
+ jmp __mark_no_selector_1
+#endif
+ je __mark_no_selector_1
+
+__mark_selector_node_1:
+ addl $2,a2
+ je __mark_indirection_node
+
+ addl $1,a2
+
+ pushl d1
+ movl (a0),a2
+ pushl d0
+ movl neg_heap_p3,d0
+
+ jle __mark_record_selector_node_1
+
+ addl a2,d0
+ movl d0,d1
+ andl $31*4,d0
+ shrl $7,d1
+ movl bit_set_table(d0),d0
+ testl (a4,d1,4),d0
+ popl d0
+ jne __mark_no_selector_2
+
+ movl (a2),d1
+ testb $2,d1
+ je __mark_no_selector_2
+
+ cmpw $2,-2(d1)
+ jbe __small_tuple_or_record
+
+__large_tuple_or_record:
+ movl 8(a2),a2
+ movl neg_heap_p3,d1
+ addl d1,a2
+ movl a2,d1
+ andl $31*4,a2
+ shrl $7,d1
+ movl bit_set_table(a2),a2
+ testl (a4,d1,4),a2
+ jne __mark_no_selector_2
+
+__small_tuple_or_record:
+ movl -8(d0),d0
+ popl d1
+
+ pushl a0
+ movl (a0),a0
+ call *4(d0)
+ popl a1
+
+ movl $__indirection,-4(a1)
+ movl a0,(a1)
+ jmp __mark_node
+
+__mark_record_selector_node_1:
+ je __mark_strict_record_selector_node_1
+
+ addl a2,d0
+ movl d0,d1
+ andl $31*4,d0
+ shrl $7,d1
+ movl bit_set_table(d0),d0
+ testl (a4,d1,4),d0
+ popl d0
+ jne __mark_no_selector_2
+
+ movl (a2),d1
+ testb $2,d1
+ je __mark_no_selector_2
+
+ cmpw $258,-2(d1)
+ jbe __small_tuple_or_record
+ jmp __large_tuple_or_record
+
+__mark_strict_record_selector_node_1:
+ addl a2,d0
+ movl d0,d1
+ andl $31*4,d0
+ shrl $7,d1
+ movl bit_set_table(d0),d0
+ testl (a4,d1,4),d0
+ popl d0
+ jne __mark_no_selector_2
+
+ movl (a2),d1
+ testb $2,d1
+ je __mark_no_selector_2
+
+ cmpw $258,-2(d1)
+ jle __select_from_small_record
+
+ movl 8(a2),a2
+ movl neg_heap_p3,d1
+ addl d1,a2
+ movl a2,d1
+ andl $31*4,a2
+ shrl $7,d1
+ movl bit_set_table(a2),a2
+ testl (a4,d1,4),a2
+ jne __mark_no_selector_2
+
+__select_from_small_record:
+ movl -8(d0),d0
+ popl d1
+ movl (a0),a1
+ subl $4,a0
+ call *4(d0)
+ jmp __mark_node
+
+__mark_indirection_node:
+ movl (a0),a0
+ jmp __mark_node
+
+__mark_hnf_2:
+ movl bit_set_table(a1),a1
+ addl $3,n_marked_words
+ orl a1,(a4,d1,4)
+ cmpl $0x20000000,a1
+ jbe fits__in__word__6
+ orl $1,4(a4,d1,4)
+fits__in__word__6:
+
+__mark_record_2_c:
+ movl (a0),d0
+ movl 4(a0),a2
+ orl $2,d0
+ movl a3,4(a0)
+ movl d0,(a0)
+ lea 4(a0),a3
+ movl a2,a0
+
+__mark_node:
+#ifdef DEBUG_MARK_COLLECT
+ testl $3,a0
+ je no_error_in_gc1
+ call error_in_gc
+no_error_in_gc1:
+#endif
+
+ movl neg_heap_p3,a1
+#ifdef SHARE_CHAR_INT
+ movl heap_size_32_33,d1
+#endif
+ addl a0,a1
+#ifdef SHARE_CHAR_INT
+ cmpl d1,a1
+ jae __mark_next_node
+#endif
+ movl a1,d1
+ andl $31*4,a1
+ shrl $7,d1
+ movl bit_set_table(a1),a2
+ testl (a4,d1,4),a2
+ je __mark_arguments
+
+__mark_next_node:
+ testl $3,a3
+ jne __mark_parent
+
+ movl -4(a3),a2
+ movl K6_0(a3),a1
+ movl a0,K6_0(a3)
+ movl a1,-4(a3)
+ subl $4,a3
+
+ movl a2,a0
+ andl $3,a2
+ andl $-4,a0
+ orl a2,a3
+ jmp __mark_node
+
+__mark_parent:
+ movl a3,d1
+ andl $-4,a3
+ je __end_mark_using_reversal
+
+ andl $3,d1
+ movl K6_0(a3),a2
+ movl a0,K6_0(a3)
+
+ subl $1,d1
+ je __argument_part_parent
+
+#ifdef DEBUG_MARK_COLLECT
+ cmpl $1,d1
+ je no_error_in_gc2
+ call error_in_gc
+no_error_in_gc2:
+#endif
+
+ lea -4(a3),a0
+ movl a2,a3
+ jmp __mark_next_node
+
+__argument_part_parent:
+ andl $-4,a2
+ movl a3,a1
+ movl -4(a2),a0
+ movl (a2),d1
+ movl d1,-4(a2)
+ movl a1,(a2)
+ lea (-4)+2(a2),a3
+ jmp __mark_node
+
+__mark_lazy_node:
+ movl -4(d0),a2
+ testl a2,a2
+ je __mark_real_or_file
+
+ addl $4,a0
+ cmpl $1,a2
+ jle __mark_lazy_node_1
+ cmpl $256,a2
+ jge __mark_closure_with_unboxed_arguments
+
+ addl $1,a2
+ movl a1,d0
+ movl bit_set_table(a1),a1
+ addl a2,n_marked_words
+
+ lea (d0,a2,4),d0
+ subl $2,a2
+
+ orl a1,(a4,d1,4)
+
+ cmpl $32*4,d0
+ jbe fits__in__word__7
+ orl $1,4(a4,d1,4)
+fits__in__word__7:
+__mark_closure_with_unboxed_arguments__2:
+ lea (a0,a2,4),a1
+ movl (a0),d0
+ orl $2,d0
+ movl d0,(a0)
+ movl (a1),a0
+ movl a3,(a1)
+ movl a1,a3
+ jmp __mark_node
+
+__mark_closure_with_unboxed_arguments:
+ movl a2,d0
+ andl $255,a2
+
+ subl $1,a2
+ je __mark_closure_1_with_unboxed_argument
+ addl $2,a2
+
+ shrl $8,d0
+ addl a2,n_marked_words
+
+ pushl a0
+ lea (a1,a2,4),a0
+
+ movl bit_set_table(a1),a1
+ subl d0,a2
+
+ orl a1,(a4,d1,4)
+ cmpl $32*4,a0
+ jbe fits__in_word_7_
+ orl $1,4(a4,d1,4)
+fits__in_word_7_:
+ popl a0
+ subl $2,a2
+ jg __mark_closure_with_unboxed_arguments__2
+ je __shared_argument_part
+ subl $4,a0
+ jmp __mark_next_node
+
+__mark_closure_1_with_unboxed_argument:
+ subl $4,a0
+ jmp __mark_real_or_file
+
+__mark_hnf_0:
+ cmpl $INT+2,d0
+ jne __no_int_3
+
+ movl 4(a0),a2
+ cmpl $33,a2
+#ifdef COMPARE_HEAP_AFTER_MARK
+ jmp __mark_bool_or_small_string
+#endif
+ jb ____small_int
+
+__mark_bool_or_small_string:
+ movl bit_set_table(a1),a1
+ addl $2,n_marked_words
+ orl a1,(a4,d1,4)
+ cmpl $0x40000000,a1
+ jbe __mark_next_node
+ orl $1,4(a4,d1,4)
+ jmp __mark_next_node
+
+____small_int:
+ lea small_integers(,a2,8),a0
+ jmp __mark_next_node
+
+__no_int_3:
+ jb __mark_real_file_or_string
+
+ cmpl $CHAR+2,d0
+ jne __no_char_3
+#ifdef COMPARE_HEAP_AFTER_MARK
+ jmp __mark_bool_or_small_string
+#endif
+ movzbl 4(a0),a2
+ lea static_characters(,a2,8),a0
+ jmp __mark_next_node
+
+__no_char_3:
+ jb __mark_bool_or_small_string
+
+#ifdef COMPARE_HEAP_AFTER_MARK
+ movl bit_set_table(a1),a1
+ incl n_marked_words
+ orl a1,(a4,d1,4)
+ jmp __mark_next_node
+#endif
+
+ lea -2+ZERO_ARITY_DESCRIPTOR_OFFSET(d0),a0
+ jmp __mark_next_node
+
+__mark_real_file_or_string:
+ cmpl $__STRING__+2,d0
+ jbe __mark_string_or_array
+
+__mark_real_or_file:
+ movl bit_set_table(a1),a1
+ addl $3,n_marked_words
+
+ orl a1,(a4,d1,4)
+
+ cmpl $0x20000000,a1
+ jbe __mark_next_node
+
+ orl $1,4(a4,d1,4)
+ jmp __mark_next_node
+
+__mark__record:
+ subl $258,a2
+ je __mark_record_2
+ jl __mark_record_1
+
+__mark_record_3:
+ movl bit_set_table(a1),a1
+ addl $3,n_marked_words
+ orl a1,(a4,d1,4)
+ cmpl $0x20000000,a1
+ jbe fits__in__word__13
+ orl $1,4(a4,d1,4)
+fits__in__word__13:
+ movzwl -2+2(d0),d1
+
+ movl neg_heap_p3,d0
+ movl 4(a0),a1
+ addl d0,a1
+ movl a1,d0
+ andl $31*4,a1
+ shrl $7,d0
+
+ pushl a3
+
+ movl bit_set_table(a1),a3
+ testl (a4,d0,4),a3
+ jne __shared_record_argument_part
+
+ addl $1,a2
+ orl a3,(a4,d0,4)
+
+ lea (a1,a2,4),a1
+ addl a2,n_marked_words
+
+ popl a3
+
+ cmpl $32*4,a1
+ jbe fits__in__word__14
+ orl $1,4(a4,d0,4)
+fits__in__word__14:
+ subl $1,d1
+ movl 4(a0),a1
+ jl __mark_record_3_bb
+ je __shared_argument_part
+
+ movl a3,4(a0)
+ addl $4,a0
+
+ subl $1,d1
+ je __mark_record_3_aab
+
+ lea (a1,d1,4),a3
+ movl (a1),d0
+ orl $1,d0
+ movl K6_0(a3),a2
+ movl d0,(a1)
+ movl a0,K6_0(a3)
+ movl a2,a0
+ jmp __mark_node
+
+__mark_record_3_bb:
+ subl $4,a0
+ jmp __mark_next_node
+
+__mark_record_3_aab:
+ movl (a1),a2
+ movl a0,(a1)
+ lea 1(a1),a3
+ movl a2,a0
+ jmp __mark_node
+
+__shared_record_argument_part:
+ movl 4(a0),a1
+
+ popl a3
+
+ test d1,d1
+ jne __shared_argument_part
+ subl $4,a0
+ jmp __mark_next_node
+
+__mark_record_2:
+ movl bit_set_table(a1),a1
+ addl $3,n_marked_words
+ orl a1,(a4,d1,4)
+ cmpl $0x20000000,a1
+ jbe fits__in__word_12
+ orl $1,4(a4,d1,4)
+fits__in__word_12:
+ cmpw $1,-2+2(d0)
+ ja __mark_record_2_c
+ je __shared_argument_part
+ subl $4,a0
+ jmp __mark_next_node
+
+__mark_record_1:
+ cmpw $0,-2+2(d0)
+ jne __mark_hnf_1
+ subl $4,a0
+ jmp __mark_bool_or_small_string
+
+__mark_string_or_array:
+ je __mark_string_
+
+__mark_array:
+ movl 8(a0),a2
+ test a2,a2
+ je __mark_lazy_array
+
+ movzwl -2(a2),d0
+ test d0,d0
+ je __mark_strict_basic_array
+
+ movzwl -2+2(a2),a2
+ test a2,a2
+ je __mark_b_record_array
+
+ subl $256,d0
+ cmpl a2,d0
+ je __mark_a_record_array
+
+__mark__ab__record__array:
+ pushl a1
+ pushl d1
+ movl a2,d1
+
+ movl 4(a0),a2
+ addl $8,a0
+ pushl a0
+
+ shl $2,a2
+ movl d0,a1
+ imull a2,a1
+
+ subl d1,d0
+ addl $4,a0
+ addl a0,a1
+
+ call reorder
+
+ popl a0
+
+ xchg d1,d0
+ movl -4(a0),a2
+ imull a2,d0
+ imull a2,d1
+ addl d1,n_marked_words
+ addl d0,d1
+
+ movl neg_heap_p3,a2
+ shl $2,d1
+ addl a0,a2
+ addl d1,a2
+
+ popl d1
+ popl a1
+
+ movl bit_set_table(a1),a1
+ orl a1,(a4,d1,4)
+
+ lea (a0,d0,4),a1
+ jmp __mark_r_array
+
+__mark_a_record_array:
+ imull 4(a0),d0
+ addl $8,a0
+ jmp __mark_lr_array
+
+__mark_lazy_array:
+ movl 4(a0),d0
+ addl $8,a0
+
+__mark_lr_array:
+ movl bit_set_table(a1),a1
+ movl neg_heap_p3,a2
+ orl a1,(a4,d1,4)
+ lea (a0,d0,4),a1
+ addl a1,a2
+__mark_r_array:
+ shrl $7,a2
+
+ cmpl a2,d1
+ jae __skip_mark_lazy_array_bits
+
+ inc d1
+
+__mark_lazy_array_bits:
+ orl $1,(a4,d1,4)
+ inc d1
+ cmpl a2,d1
+ jbe __mark_lazy_array_bits
+
+__skip_mark_lazy_array_bits:
+ movl n_marked_words,a2
+ addl $3,a2
+ addl d0,a2
+
+ cmpl $1,d0
+ movl a2,n_marked_words
+ jbe __mark_array_length_0_1
+
+ movl (a1),a2
+ movl (a0),d1
+ movl d1,(a1)
+ movl a2,(a0)
+
+ movl -4(a1),a2
+ subl $4,a1
+ movl lazy_array_list,d1
+ addl $2,a2
+ movl d1,(a1)
+ movl a2,-4(a0)
+ movl d0,-8(a0)
+ subl $8,a0
+ movl a0,lazy_array_list
+
+ movl -4(a1),a0
+ movl a3,-4(a1)
+ lea -4(a1),a3
+ jmp __mark_node
+
+__mark_array_length_0_1:
+ lea -8(a0),a0
+ jb __mark_next_node
+
+ movl 12(a0),d1
+ movl 8(a0),a2
+ movl lazy_array_list,a1
+ movl a2,12(a0)
+ movl a1,8(a0)
+ movl d0,(a0)
+ movl a0,lazy_array_list
+ movl d1,4(a0)
+ addl $4,a0
+
+ movl (a0),a2
+ movl a3,(a0)
+ lea 2(a0),a3
+ movl a2,a0
+ jmp __mark_node
+
+__mark_b_record_array:
+ movl 4(a0),a2
+ subl $256,d0
+ imull a2,d0
+ addl $3,d0
+ jmp __mark_basic_array
+
+__mark_strict_basic_array:
+ movl 4(a0),d0
+ cmpl $INT+2,a2
+ je __mark__strict__int__array
+ cmpl $BOOL+2,a2
+ je __mark__strict__bool__array
+__mark__strict__real__array:
+ addl d0,d0
+__mark__strict__int__array:
+ addl $3,d0
+ jmp __mark_basic_array
+__mark__strict__bool__array:
+ addl $12+3,d0
+ shrl $2,d0
+ jmp __mark_basic_array
+
+__mark_string_:
+ movl 4(a0),d0
+ addl $8+3,d0
+ shr $2,d0
+
+__mark_basic_array:
+ movl bit_set_table(a1),a1
+ addl d0,n_marked_words
+
+#ifdef DEBUG_MARK_COLLECT
+ cmpl $100000,d0
+ jc no_error_in_gc4
+ call error_in_gc
+no_error_in_gc4:
+#endif
+
+ orl a1,(a4,d1,4)
+ lea -4(a0,d0,4),d0
+
+ addl neg_heap_p3,d0
+ shrl $7,d0
+
+ cmpl d0,d1
+ jae __mark_next_node
+
+ incl d1
+ movl $1,a2
+
+ cmpl d0,d1
+ jae __last__string__bits
+
+__mark_string_lp:
+ orl a2,(a4,d1,4)
+ incl d1
+ cmpl d0,d1
+ jb __mark_string_lp
+
+__last__string__bits:
+ orl a2,(a4,d1,4)
+ jmp __mark_next_node
+
+#ifdef DEBUG_MARK_COLLECT
+error_in_gc:
+ pushl d0
+ pushl d1
+ pushl a0
+ pushl a1
+ pushl $error_in_gc_string
+ call @ew_print_string
+ addl $4,sp
+ popl a1
+ popl a0
+ popl d1
+ popl d0
+ ret
+
+error_in_gc_string:
+ .ascii "Error in marking gc"
+ .byte 0
+
+#endif
diff --git a/scon.c b/scon.c
new file mode 100644
index 0000000..15a9e4b
--- /dev/null
+++ b/scon.c
@@ -0,0 +1,843 @@
+/*
+ File: scon.c
+ Author: John van Groningen
+ At: University of Nijmegen
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#ifdef SOLARIS
+# include <unistd.h>
+#endif
+
+#define GC_FLAGS
+#ifndef SOLARIS
+# define MARKING_GC
+#endif
+#define STACK_OVERFLOW_EXCEPTION_HANDLER
+#define USE_CR2
+
+#ifdef STACK_OVERFLOW_EXCEPTION_HANDLER
+# include <signal.h>
+# ifdef LINUX
+# include <sys/resource.h>
+# endif
+# ifdef SOLARIS
+# include <ucontext.h>
+# include <procfs.h>
+# endif
+# include <fcntl.h>
+# include <sys/mman.h>
+#endif
+
+long min_write_heap_size;
+
+#define MY_PATH_MAX 1025
+
+char appl_path[MY_PATH_MAX];
+char home_path[MY_PATH_MAX];
+
+void set_home_and_appl_path (char *command)
+{
+ char *p;
+ int r;
+
+ realpath (getenv ("HOME"),home_path);
+
+#if 1
+# ifdef SOLARIS
+ p=getexecname();
+ if (p!=NULL){
+ realpath (p,appl_path);
+ *strrchr (appl_path,'/')='\0';
+ } else
+ appl_path[0]='\0';
+# else
+ r=readlink ("/proc/self/exe",appl_path,MY_PATH_MAX-1);
+ if (r>=0){
+ appl_path[r]='\0';
+
+ p=strrchr (appl_path,'/');
+ if (p!=NULL)
+ *p='\0';
+ } else
+ appl_path[0]='\0';
+# endif
+#else
+ p=strchr (command,'/');
+
+ if (p!=NULL){
+ realpath (command,appl_path);
+ *strrchr (appl_path,'/')='\0';
+ } else {
+ char *path,*file_found_p;
+ int colon_i;
+
+ path=(char *)getenv("PATH");
+
+ file_found_p=NULL;
+
+ while (path!=NULL && file_found_p==NULL){
+ char *next,try_path[MY_PATH_MAX];
+
+ next=strchr (path,':');
+ if (next==NULL)
+ colon_i=strlen(path);
+ else
+ colon_i=next-path;
+
+ strncpy (try_path,path,colon_i);
+ try_path[colon_i]='\0';
+
+ strcat (try_path,"/");
+ strcat (try_path,command);
+
+ file_found_p=(char *)realpath (try_path,appl_path);
+
+ path=next;
+ if (path!=NULL)
+ ++path;
+ }
+
+ if (file_found_p==NULL)
+ *appl_path='\0';
+ else
+ *strrchr(appl_path,'/')='\0';
+ }
+#endif
+}
+
+#if defined (SOLARIS) || defined (I486)
+extern long ab_stack_size,heap_size,flags;
+#else
+extern long stack_size,heap_size,flags;
+#endif
+
+/*
+extern long ab_stack_size=512*1024,heap_size=2048*1024,flags=8;
+*/
+#ifdef MARKING_GC
+extern long heap_size_multiple,initial_heap_size;
+#endif
+
+#ifdef STACK_OVERFLOW_EXCEPTION_HANDLER
+struct sigaction old_sa;
+
+extern int stack_overflow (void);
+extern int *halt_sp;
+
+# ifdef LINUX
+extern int *a_stack_guard_page;
+int *below_stack_page;
+
+void *allocate_memory_with_guard_page_at_end (int size)
+{
+ int alloc_size;
+ char *p,*end_p;
+
+ alloc_size=(size+4096+4095) & -4096;
+
+ p=malloc (alloc_size);
+ if (p==NULL)
+ return p;
+
+ end_p=(char*)(((int)p+size+4095) & -4096);
+ mprotect (end_p,4096,PROT_NONE);
+
+ return p;
+}
+
+# ifdef USE_CR2
+static void clean_exception_handler (int s,struct sigcontext sigcontext)
+{
+ if (
+ (((int)sigcontext.cr2 ^ (int)below_stack_page) & -4096)==0 ||
+ (((int)sigcontext.cr2 ^ (int)a_stack_guard_page) & -4096)==0)
+ {
+ sigcontext.eip=(int)&stack_overflow;
+ sigcontext.esp=(int)halt_sp;
+ } else {
+ sigaction (SIGSEGV,&old_sa,NULL);
+ /*
+ if (old_sa.sa_handler==SIG_DFL || old_sa.sa_handler==SIG_IGN)
+ sigaction (SIGSEGV,&old_sa,NULL);
+ else
+ old_sa.sa_sigaction (s,sigcontext);
+ */
+ }
+}
+# else
+static void clean_exception_handler_info (int s,struct siginfo *siginfo_p,void *p);
+
+static void clean_exception_handler_context (int s,struct sigcontext sigcontext)
+{
+ struct sigaction sa;
+
+ sigcontext.eip=(int)&stack_overflow;
+ sigcontext.esp=(int)halt_sp;
+
+ sigemptyset (&sa.sa_mask);
+ sa.sa_sigaction=&clean_exception_handler_info;
+ sa.sa_flags= SA_ONSTACK | SA_RESTART | SA_SIGINFO;
+
+ sigaction (SIGSEGV,&sa,NULL);
+}
+
+static void clean_exception_handler_info (int s,struct siginfo *siginfo_p,void *p)
+{
+ struct sigaction sa;
+
+ if (
+ (((int)siginfo_p->si_addr ^ (int)below_stack_page) & -4096)==0 ||
+ (((int)siginfo_p->si_addr ^ (int)a_stack_guard_page) & -4096)==0)
+ {
+ struct sigaction sa;
+
+ sigemptyset (&sa.sa_mask);
+ sa.sa_handler=&clean_exception_handler_context;
+ sa.sa_flags= SA_ONSTACK | SA_RESTART;
+
+ sigaction (SIGSEGV,&sa,NULL);
+ } else {
+ if (old_sa.sa_handler==SIG_DFL || old_sa.sa_handler==SIG_IGN)
+ sigaction (SIGSEGV,&old_sa,NULL);
+ else
+ old_sa.sa_sigaction (s,siginfo_p,p);
+ }
+}
+# endif
+
+static void install_clean_exception_handler (void)
+{
+ char proc_map_file_name[64];
+ int proc_map_fd,a;
+ struct sigaction sa;
+ stack_t sig_s;
+ int *sig_stack;
+
+ sprintf (proc_map_file_name,"/proc/%d/maps",getpid());
+
+ proc_map_fd=open (proc_map_file_name,O_RDONLY);
+
+ if (proc_map_fd<0)
+ return;
+
+ for (;;){
+ static char m[17];
+ unsigned int b,e;
+
+ if (read (proc_map_fd,m,17)==17 && m[8]=='-'){
+ int i;
+
+ b=0;
+ e=0;
+ for (i=0; i<8; ++i){
+ int c;
+
+ c=m[i];
+ b=b<<4;
+ if ((unsigned)(c-'0')<10)
+ b+=c-'0';
+ else if ((unsigned)((c & ~32)-'A')<26)
+ b+=(c & ~32)-('A'-10);
+ else
+ break;
+
+ c=m[9+i];
+ e=e<<4;
+ if ((unsigned)(c-'0')<10)
+ e+=c-'0';
+ else if ((unsigned)((c & ~32)-'A')<26)
+ e+=(c & ~32)-('A'-10);
+ else
+ break;
+ }
+
+ if (i==8){
+ if ((unsigned)&a - (unsigned)b < (unsigned)(e-b)){
+ struct rlimit rlimit;
+
+ if (getrlimit (RLIMIT_STACK,&rlimit)==0){
+ below_stack_page=(int*)((int)e-rlimit.rlim_cur-4096);
+ break;
+ }
+ }
+ continue;
+ }
+ }
+
+ {
+ char c;
+
+ c='\0';
+ while (read (proc_map_fd,&c,1)==1 && c!='\n')
+ ;
+
+ if (c=='\n')
+ continue;
+ }
+
+ close (proc_map_fd);
+ return;
+ }
+
+ close (proc_map_fd);
+
+ sig_stack=malloc (MINSIGSTKSZ);
+
+ if (sig_stack==NULL)
+ return;
+
+ sig_s.ss_flags=0;
+ sig_s.ss_size=MINSIGSTKSZ;
+ sig_s.ss_sp=sig_stack;
+
+ sigaltstack (&sig_s,NULL);
+
+ sigemptyset (&sa.sa_mask);
+# ifdef USE_CR2
+ sa.sa_sigaction=&clean_exception_handler;
+ sa.sa_flags= SA_ONSTACK | SA_RESTART;
+# else
+ sa.sa_sigaction=&clean_exception_handler_info;
+ sa.sa_flags= SA_ONSTACK | SA_RESTART | SA_SIGINFO;
+# endif
+
+ sigaction (SIGSEGV,&sa,&old_sa);
+}
+# else
+# ifdef DETECT_SYSTEM_STACK_OVERFLOW
+int *below_stack_page;
+# endif
+int *stack_guard_page;
+
+void *allocate_stack (int size)
+{
+ int alloc_size,size_a8192;
+ char *p,*end_p;
+
+ size=(size+3) & -4;
+ size_a8192=(size+8191) & -8192;
+ alloc_size=8192+(size_a8192<<1)+8192;
+
+ p=malloc (alloc_size);
+ if (p==NULL)
+ return NULL;
+
+ end_p=(char*)(((int)p+size+8191) & -8192);
+
+ mprotect (end_p,8192,PROT_NONE);
+
+ stack_guard_page=(int*)end_p;
+
+ return (void*)stack_guard_page;
+}
+
+void clean_exception_handler (int s,struct siginfo *siginfo_p,ucontext_t *ucontext_p)
+{
+ struct sigaction sa;
+ mcontext_t *mcontext_p;
+
+ if (
+# ifdef DETECT_SYSTEM_STACK_OVERFLOW
+ (((int)siginfo_p->si_addr ^ (int)below_stack_page) & -8192)==0 ||
+# endif
+ (((int)siginfo_p->si_addr ^ (int)stack_guard_page) & -8192)==0)
+ {
+ mcontext_p=&ucontext_p->uc_mcontext;
+# ifdef DETECT_SYSTEM_STACK_OVERFLOW
+ if (mcontext_p->gwins!=NULL){
+ int wi,wo,n_windows;
+
+ n_windows=mcontext_p->gwins->wbcnt;
+ wo=0;
+ for (wi=0; wi<n_windows; ++wi){
+ int *register_window_p;
+
+ register_window_p=mcontext_p->gwins->spbuf[wi];
+ if (((((int)register_window_p ^ (int)below_stack_page)) & -8192) != 0){
+ /*
+ struct rwindow *rwindow_p;
+ int i;
+
+ rwindow_p=&mcontext_p->gwins->wbuf[wi];
+ for (i=0; i<8; ++i){
+ register_window_p[i]=rwindow_p->rw_local[i];
+ register_window_p[8+i]=rwindow_p->rw_in[i];
+ }
+ */
+ if (wi!=wo)
+ mcontext_p->gwins->wbuf[wo]=mcontext_p->gwins->wbuf[wi];
+ ++wo;
+ }
+ }
+ mcontext_p->gwins->wbcnt=wo;
+ }
+# endif
+
+ mcontext_p->gregs[REG_PC]=(int)&stack_overflow;
+ mcontext_p->gregs[REG_nPC]=(int)&stack_overflow+4;
+ mcontext_p->gregs[REG_G5]=(int)halt_sp;
+ } else {
+ if (old_sa.sa_sigaction==SIG_DFL || old_sa.sa_sigaction==SIG_IGN)
+ sigaction (SIGSEGV,&old_sa,NULL);
+ else
+ old_sa.sa_sigaction (s,siginfo_p,ucontext_p);
+ }
+}
+
+static void install_clean_exception_handler (void)
+{
+ struct sigaction sa;
+# ifdef DETECT_SYSTEM_STACK_OVERFLOW
+ char proc_map_file_name[64];
+ struct prmap prmap;
+ stack_t sig_s;
+ int proc_map_fd,a,*sig_stack;
+
+ sprintf (proc_map_file_name,"/proc/%d/rmap",getpid());
+
+ proc_map_fd=open (proc_map_file_name,O_RDONLY);
+
+ if (proc_map_fd<0)
+ return;
+
+ do {
+ if (read (proc_map_fd,&prmap,sizeof (prmap))!=sizeof (prmap)){
+ close (proc_map_fd);
+ return;
+ }
+ } while (! ((unsigned)&a - (unsigned)prmap.pr_vaddr < (unsigned)prmap.pr_size));
+
+ close (proc_map_fd);
+
+ below_stack_page=(int*)((int)prmap.pr_vaddr-8192);
+
+ sig_stack=malloc (MINSIGSTKSZ);
+
+ if (sig_stack==NULL)
+ return;
+
+ sig_s.ss_flags=0;
+ sig_s.ss_size=MINSIGSTKSZ;
+ sig_s.ss_sp=sig_stack;
+
+ sigaltstack (&sig_s,NULL);
+# endif
+
+ sigemptyset (&sa.sa_mask);
+ sa.sa_sigaction=&clean_exception_handler;
+# ifdef DETECT_SYSTEM_STACK_OVERFLOW
+ sa.sa_flags= SA_ONSTACK | SA_RESTART | SA_SIGINFO;
+# else
+ sa.sa_flags= SA_RESTART | SA_SIGINFO;
+# endif
+
+ sigaction (SIGSEGV,&sa,&old_sa);
+}
+# endif
+#endif
+
+void w_print_char (char c)
+{
+ putchar (c);
+}
+
+void w_print_text (register char *s,unsigned long length)
+{
+ register int l;
+
+ l=length;
+ if (l)
+ do {
+ putchar (*s);
+ ++s;
+ } while (--l);
+}
+
+void ew_print_char (char c)
+{
+ putc (c,stderr);
+}
+
+void ew_print_text (register char *s,unsigned long length)
+{
+ register int l;
+
+ l=length;
+ if (l)
+ do {
+ putc (*s,stderr);
+ ++s;
+ } while (--l);
+}
+
+int w_get_char()
+{
+ return getchar();
+}
+
+#define is_digit(n) ((unsigned)((n)-'0')<(unsigned)10)
+
+int w_get_int (int *i_p)
+{
+ int c,negative;
+ unsigned int i;
+
+ c=getchar();
+ while (c==' ' || c=='\t' || c=='\n')
+ c=getchar();
+
+ negative=0;
+ if (c=='+')
+ c=getchar();
+ else
+ if (c=='-'){
+ c=getchar();
+ negative=1;
+ }
+
+ if (!is_digit (c)){
+ if (c!=EOF)
+ ungetc (c,stdin);
+
+ *i_p=0;
+ return 0;
+ }
+
+ i=c-'0';
+ while (c=getchar(),is_digit (c)){
+ i+=i<<2;
+ i+=i;
+ i+=c-'0';
+ };
+
+ if (negative)
+ i=-i;
+
+ if (c!=EOF)
+ ungetc (c,stdin);
+
+ *i_p=i;
+ return -1;
+}
+
+int w_get_real (double *r_p)
+{
+ char s[256+1];
+ int c,dot,digits,result,n;
+
+ n=0;
+
+ c=getchar();
+ while (c==' ' || c=='\t' || c=='\n')
+ c=getchar();
+
+ if (c=='+')
+ c=getchar();
+ else
+ if (c=='-'){
+ s[n++]=c;
+ c=getchar();
+ }
+
+ dot=0;
+ digits=0;
+
+ while (is_digit (c) || c=='.'){
+ if (c=='.'){
+ if (dot){
+ dot=2;
+ break;
+ }
+ dot=1;
+ } else
+ digits=-1;
+ if (n<256)
+ s[n++]=c;
+ c=getchar();
+ }
+
+ result=0;
+ if (digits)
+ if (dot==2 || ! (c=='e' || c=='E'))
+ result=-1;
+ else {
+ if (n<256)
+ s[n++]=c;
+ c=getchar();
+
+ if (c=='+')
+ c=getchar();
+ else
+ if (c=='-'){
+ if (n<256)
+ s[n++]=c;
+ c=getchar();
+ }
+
+ if (is_digit (c)){
+ do {
+ if (n<256)
+ s[n++]=c;
+ c=getchar();
+ } while (is_digit (c));
+
+ result=-1;
+ }
+ }
+
+ if (n>=256)
+ result=0;
+
+ if (c!=EOF)
+ ungetc (c,stdin);
+
+ *r_p=0.0;
+
+ if (result){
+ s[n]='\0';
+ if (sscanf (s,"%lg",r_p)!=1)
+ result=0;
+ }
+
+ return result;
+}
+
+unsigned long w_get_text (register char *string,unsigned long max_length)
+{
+ register int length;
+
+ fgets (string,(int)max_length,stdin);
+
+ for (length=0; length<max_length; ++length)
+ if (string[length]=='\0')
+ break;
+
+ return length;
+}
+
+void w_print_string (char *s)
+{
+ fputs (s,stdout);
+}
+
+void ew_print_string (char *s)
+{
+ fputs (s,stderr);
+}
+
+void w_print_int (int n)
+{
+ printf ("%d",n);
+}
+
+void ew_print_int (int n)
+{
+ fprintf (stderr,"%d",n);
+}
+
+void w_print_real (double r)
+{
+ printf ("%.15g",r);
+}
+
+void ew_print_real (double r)
+{
+ fprintf (stderr,"%.15g",r);
+}
+
+static long parse_size (register char *s)
+{
+ register int c;
+ register long n;
+
+ c=*s++;
+ if (c<'0' || c>'9'){
+ printf ("Digit expected in argument\n");
+ exit (-1);
+ }
+
+ n=c-'0';
+
+ while (c=*s++,c>='0' && c<='9')
+ n=n*10+(c-'0');
+
+ if (c=='k' || c=='K'){
+ c=*s++;
+ n<<=10;
+ } else if (c=='m' || c=='M'){
+ c=*s++;
+ n<<=20;
+ }
+
+ if (c!='\0'){
+ printf ("Error in argument\n");
+ exit (-1);
+ }
+
+ return n;
+}
+
+#ifdef MARKING_GC
+static long parse_integer (register char *s)
+{
+ register int c;
+ register long n;
+
+ c=*s++;
+ if (c<'0' || c>'9'){
+ printf ("Digit expected in argument\n");
+ exit (-1);
+ }
+
+ n=c-'0';
+
+ while (c=*s++,c>='0' && c<='9')
+ n=n*10+(c-'0');
+
+ if (c!='\0'){
+ printf ("Error in integer");
+ exit (-1);
+ }
+
+ return n;
+}
+#endif
+
+int global_argc;
+char **global_argv;
+
+#ifdef TIME_PROFILE
+char time_profile_file_name_suffix[]=" Time Profile.pcl";
+
+void create_profile_file_name (unsigned char *profile_file_name_string)
+{
+ char *profile_file_name;
+ int r;
+
+ profile_file_name=&profile_file_name_string[8];
+
+ r=readlink ("/proc/self/exe",profile_file_name,MY_PATH_MAX-1);
+ if (r>=0){
+ int length_file_name,size_time_profile_file_name_suffix;
+
+ profile_file_name[r]='\0';
+
+ size_time_profile_file_name_suffix=sizeof (time_profile_file_name_suffix);
+ length_file_name=0;
+ while (profile_file_name[length_file_name]!='\0')
+ ++length_file_name;
+
+ if (length_file_name+size_time_profile_file_name_suffix>MY_PATH_MAX)
+ length_file_name=MY_PATH_MAX-size_time_profile_file_name_suffix;
+
+ strcat (&profile_file_name[length_file_name],time_profile_file_name_suffix);
+ *(unsigned int*)&profile_file_name_string[4] = length_file_name+size_time_profile_file_name_suffix-1;
+ } else {
+ strcpy (profile_file_name,&time_profile_file_name_suffix[1]);
+ *(unsigned int*)&profile_file_name_string[4] = sizeof (time_profile_file_name_suffix)-1;
+ }
+}
+#endif
+
+int execution_aborted;
+int return_code;
+
+int main (int argc,char **argv)
+{
+ int arg_n;
+
+ execution_aborted=0;
+ return_code=0;
+
+#ifdef STACK_OVERFLOW_EXCEPTION_HANDLER
+ install_clean_exception_handler();
+#endif
+
+ set_home_and_appl_path (argv[0]);
+
+ for (arg_n=1; arg_n<argc; ++arg_n){
+ char *s;
+
+ s=argv[arg_n];
+ if (*s!='-')
+ break;
+
+ ++s;
+ if (!strcmp (s,"h")){
+ ++arg_n;
+ if (arg_n>=argc){
+ printf ("Heapsize missing\n");
+ return -1;
+ }
+ heap_size=parse_size (argv[arg_n]);
+ } else if (!strcmp (s,"s")){
+ ++arg_n;
+ if (arg_n>=argc){
+ printf ("Stacksize missing\n");
+ return -1;
+ }
+#if defined (SOLARIS) || defined (I486)
+ ab_stack_size=parse_size (argv[arg_n]);
+#else
+ stack_size=parse_size (argv[arg_n]);
+#endif
+ } else if (!strcmp (s,"b"))
+ flags |= 1;
+ else if (!strcmp (s,"sc"))
+ flags &= ~1;
+ else if (!strcmp (s,"t"))
+ flags |= 8;
+ else if (!strcmp (s,"nt"))
+ flags &= ~8;
+ else if (!strcmp (s,"gc"))
+ flags |= 2;
+ else if (!strcmp (s,"ngc"))
+ flags &= ~2;
+ else if (!strcmp (s,"st"))
+ flags |= 4;
+ else if (!strcmp (s,"nst"))
+ flags &= ~4;
+ else if (!strcmp (s,"nr"))
+ flags |= 16;
+#ifdef MARKING_GC
+ else if (!strcmp (s,"gcm"))
+ flags |= 64;
+ else if (!strcmp (s,"gcc"))
+ flags &= ~64;
+ else if (!strcmp (s,"gci")){
+ ++arg_n;
+ if (arg_n>=argc){
+ printf ("Initial heap size missing\n");
+ exit (-1);
+ }
+ initial_heap_size=parse_size (argv[arg_n]);
+ } else if (!strcmp (s,"gcf")){
+ ++arg_n;
+ if (arg_n>=argc){
+ printf ("Next heap size factor missing\n");
+ exit (-1);
+ }
+ heap_size_multiple=parse_integer (argv[arg_n])<<8;
+ }
+#endif
+ else
+ break;
+ }
+
+ --arg_n;
+ argv[arg_n]=argv[0];
+ global_argv=&argv[arg_n];
+ global_argc=argc-arg_n;
+
+ abc_main();
+
+ if (return_code==0 && execution_aborted!=0)
+ return_code= -1;
+
+ return return_code;
+}
diff --git a/scon.h b/scon.h
new file mode 100644
index 0000000..570ab32
--- /dev/null
+++ b/scon.h
@@ -0,0 +1,14 @@
+extern int w_get_char();
+extern int w_get_int (int *i_p);
+extern int w_get_real (double *r_p);
+extern unsigned long w_get_text (char *string,unsigned long max_length);
+extern void w_print_char (char c);
+extern void w_print_int (int i);
+extern void w_print_real (double r);
+extern void w_print_string (char *s);
+extern void w_print_text (char *s,unsigned long length);
+extern void ew_print_char (char c);
+extern void ew_print_int (int i);
+extern void ew_print_real (double r);
+extern void ew_print_string (char *s);
+extern void ew_print_text (char *s,unsigned long length);
diff --git a/uwrite_heap.c b/uwrite_heap.c
new file mode 100644
index 0000000..9055515
--- /dev/null
+++ b/uwrite_heap.c
@@ -0,0 +1,109 @@
+
+#include <stdio.h>
+
+struct heap_info {
+ int *heap1_begin;
+ int *heap1_end;
+ int *heap2_begin;
+ int *heap2_end;
+ int *stack_begin;
+ int *stack_end;
+ int *text_begin;
+ int *data_begin;
+ int *small_integers;
+ int *characters;
+ int int_descriptor;
+ int char_descriptor;
+ int real_descriptor;
+ int bool_descriptor;
+ int string_descriptor;
+ int array_descriptor;
+};
+
+static int heap_written_count=0;
+
+#define MAX_N_HEAPS 10
+
+#define MAX_PATH_LENGTH 256
+
+void write_heap (struct heap_info *h)
+{
+ static char heap_profile_file_name_suffix[]=" Heap Profile0.hcl";
+ char heap_profile_file_name[MAX_PATH_LENGTH+1];
+ FILE *heap_file;
+ int length_application_name,file_ok;
+
+ if (heap_written_count >= MAX_N_HEAPS)
+ return;
+
+ length_application_name=readlink ("/proc/self/exe",heap_profile_file_name,MAX_PATH_LENGTH);
+ if (length_application_name>=0){
+ int length_file_name,size_heap_profile_file_name_suffix;
+
+ heap_profile_file_name[length_application_name]='\0';
+
+ size_heap_profile_file_name_suffix=sizeof (heap_profile_file_name_suffix);
+ length_file_name=0;
+ while (heap_profile_file_name[length_file_name]!='\0')
+ ++length_file_name;
+
+ if (length_file_name+size_heap_profile_file_name_suffix>MAX_PATH_LENGTH){
+ ++heap_written_count;
+ ew_print_string( "Heap file could not be created because the file name is too long.\n" );
+ return;
+ }
+
+ strcat (&heap_profile_file_name[length_file_name],heap_profile_file_name_suffix);
+
+ heap_profile_file_name[length_file_name+size_heap_profile_file_name_suffix-6]='0'+heap_written_count;
+ } else {
+ ++heap_written_count;
+ ew_print_string( "Heap file could not be created because /proc/self/exe could not be read\n");
+ return;
+ }
+
+ ++heap_written_count;
+
+ heap_file = fopen (heap_profile_file_name,"w");
+ if (heap_file==NULL){
+ heap_written_count = MAX_N_HEAPS;
+
+ ew_print_string ("Heap file '");
+ ew_print_string (heap_profile_file_name);
+ ew_print_string ("' could not be created.\n");
+
+ return;
+ }
+
+ /* save application name */
+ file_ok = fwrite (&length_application_name,sizeof (int),1,heap_file)==1;
+ if (file_ok)
+ file_ok = fwrite (heap_profile_file_name,1,length_application_name,heap_file)==length_application_name;
+
+ /* write heap_info-structure */
+ if (file_ok)
+ file_ok = fwrite (h,sizeof (struct heap_info),1,heap_file)==1;
+
+ /* write stack */
+ if (file_ok)
+ file_ok = fwrite (h->stack_begin,(int)(h->stack_end) - (int)(h->stack_begin),1,heap_file)==1;
+
+ /* write heap1 */
+ if (file_ok)
+ file_ok = fwrite (h->heap1_begin,(int)(h->heap1_end) - (int)(h->heap1_begin),1,heap_file)==1;
+
+ /* write heap2 */
+ if (file_ok)
+ file_ok = fwrite (h->heap2_begin,(int)(h->heap2_end) - (int)(h->heap2_begin),1,heap_file)==1;
+
+ if (!file_ok){
+ heap_written_count = MAX_N_HEAPS;
+
+ ew_print_string ("Heap file '");
+ ew_print_string (heap_profile_file_name);
+ ew_print_string ("' could not be written.\n");
+ }
+
+ fclose (heap_file);
+}
+