summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--iprofile.s791
-rw-r--r--istartup.s23
-rw-r--r--itrace.s419
3 files changed, 1221 insertions, 12 deletions
diff --git a/iprofile.s b/iprofile.s
new file mode 100644
index 0000000..94c174e
--- /dev/null
+++ b/iprofile.s
@@ -0,0 +1,791 @@
+
+#undef DEBUG_PROFILER
+
+#define ALLOCATION_PROFILE
+#define MODULE_NAMES
+
+#define d0 %eax
+#define d1 %ebx
+#define a0 %ecx
+#define a1 %edx
+#define a2 %ebp
+#define a3 %esi
+#define a4 %edi
+#define sp %esp
+
+#if defined(_WINDOWS_)
+# define align(n) .align (1<<n)
+#else
+# define align(n) .align n
+#endif
+
+ .global init_profiler
+ .global profile_r
+ .global profile_l
+ .global profile_l2
+ .global profile_n
+ .global profile_n2
+ .global profile_s
+ .global profile_s2
+ .global profile_t
+ .global write_profile_information
+ .global write_profile_stack
+
+ .global @allocate_memory
+ .global __STRING__
+ .global openF
+ .global closeF
+ .global writeFC
+ .global writeFI
+ .global print_error
+ .global @ab_stack_size
+ .global @ew_print_string
+ .global @ew_print_char
+ .global @create_profile_file_name
+ .global @stack_trace_depth
+
+#define next 0
+#define time_hi 4
+#define time_lo 8
+#define n_profiler_calls 12
+#define n_strict_calls 16
+#define n_lazy_calls 20
+#define n_curried_calls 24
+#define n_bytes_allocated 28
+#define name 32
+#define FunctionProfile 36
+
+ .text
+profile_t:
+ push d0
+ push a1
+ rdtsc
+
+ push a0
+ mov profile_stack_pointer,a0
+
+ push d1
+ mov -4(a0),d1
+
+ sub $4,a0
+ mov d1,global_last_tail_call
+
+ mov a0,profile_stack_pointer
+
+ sub global_time_lo,d0
+ sbb global_time_hi,a1
+
+ add d0,time_lo(d1)
+ adc a1,time_hi(d1)
+
+ incl n_profiler_calls(d1)
+
+#ifdef ALLOCATION_PROFILE
+ mov end_heap,a0
+ sub a4,a0
+ mov global_n_bytes_free,d0
+ add $32,a0
+ sub a0,d0
+ mov a0,global_n_bytes_free
+ add d0,n_bytes_allocated(d1)
+#endif
+
+ pop d1
+ pop a0
+
+ rdtsc
+ mov a1,global_time_hi
+ pop a1
+ mov d0,global_time_lo
+ pop d0
+ ret
+
+profile_r:
+ push d0
+ push a1
+ rdtsc
+
+ push a0
+ mov profile_stack_pointer,a0
+
+ push d1
+ mov -4(a0),d1
+
+ sub $4,a0
+ movl $0,global_last_tail_call
+
+ mov a0,profile_stack_pointer
+
+ sub global_time_lo,d0
+ sbb global_time_hi,a1
+
+ add d0,time_lo(d1)
+ adc a1,time_hi(d1)
+
+ incl n_profiler_calls(d1)
+
+#ifdef ALLOCATION_PROFILE
+ mov end_heap,a0
+ sub a4,a0
+ mov global_n_bytes_free,d0
+ add $32,a0
+ sub a0,d0
+ mov a0,global_n_bytes_free
+ add d0,n_bytes_allocated(d1)
+#endif
+
+ pop d1
+ pop a0
+
+ rdtsc
+ mov a1,global_time_hi
+ pop a1
+ mov d0,global_time_lo
+ pop d0
+ ret
+
+profile_l:
+ push d0
+ push a1
+ rdtsc
+
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_l
+allocate_function_profile_record_lr:
+ push a0
+
+ mov global_last_tail_call,a2
+ mov profile_stack_pointer,a0
+
+ test a2,a2
+ jne use_tail_calling_function_l
+
+ mov -4(a0),a2
+use_tail_calling_function_lr:
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ add $4,a0
+
+ incl n_curried_calls(d1)
+ jmp profile_n_
+
+allocate_function_profile_record_l:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_lr
+
+use_tail_calling_function_l:
+ movl $0,global_last_tail_call
+ jmp use_tail_calling_function_lr
+
+profile_l2:
+ push d0
+ push a1
+ rdtsc
+
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_l2
+allocate_function_profile_record_l2r:
+ push a0
+
+ mov global_last_tail_call,a2
+ mov profile_stack_pointer,a0
+
+ test a2,a2
+ jne use_tail_calling_function_l2
+
+ mov -4(a0),a2
+use_tail_calling_function_l2r:
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ mov d1,4(a0)
+ add $8,a0
+
+ incl n_curried_calls(d1)
+ jmp profile_n_
+
+allocate_function_profile_record_l2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_l2r
+
+use_tail_calling_function_l2:
+ movl $0,global_last_tail_call
+ jmp use_tail_calling_function_l2r
+
+profile_n:
+ push d0
+ push a1
+ rdtsc
+
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_n
+allocate_function_profile_record_nr:
+ push a0
+
+ mov global_last_tail_call,a2
+ mov profile_stack_pointer,a0
+
+ test a2,a2
+ jne use_tail_calling_function_n
+
+ mov -4(a0),a2
+use_tail_calling_function_nr:
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ add $4,a0
+
+ incl n_lazy_calls(d1)
+ jmp profile_n_
+
+allocate_function_profile_record_n:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_nr
+
+use_tail_calling_function_n:
+ movl $0,global_last_tail_call
+ jmp use_tail_calling_function_nr
+
+profile_n2:
+ push d0
+ push a1
+ rdtsc
+
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_n2
+allocate_function_profile_record_n2r:
+ push a0
+
+ mov global_last_tail_call,a2
+ mov profile_stack_pointer,a0
+
+ test a2,a2
+ jne use_tail_calling_function_n2
+
+ mov -4(a0),a2
+use_tail_calling_function_n2r:
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ mov d1,4(a0)
+ add $8,a0
+
+ incl n_lazy_calls(d1)
+ jmp profile_n_
+
+allocate_function_profile_record_n2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_n2r
+
+use_tail_calling_function_n2:
+ movl $0,global_last_tail_call
+ jmp use_tail_calling_function_n2r
+
+profile_s2:
+ push d0
+ push a1
+ rdtsc
+
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_s2
+allocate_function_profile_record_s2r:
+ push a0
+
+ mov global_last_tail_call,a2
+ mov profile_stack_pointer,a0
+
+ test a2,a2
+ jne use_tail_calling_function_s2
+
+ mov -4(a0),a2
+use_tail_calling_function_s2r:
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ movl d1,(a0)
+ movl d1,4(a0)
+ add $8,a0
+ jmp profile_s_
+
+allocate_function_profile_record_s2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_s2r
+
+use_tail_calling_function_s2:
+ movl $0,global_last_tail_call
+ jmp use_tail_calling_function_s2r
+
+profile_s:
+ push d0
+ push a1
+ rdtsc
+
+ push d1
+ movl (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_s
+allocate_function_profile_record_sr:
+ push a0
+
+ mov global_last_tail_call,a2
+ mov profile_stack_pointer,a0
+
+ test a2,a2
+ jne use_tail_calling_function_s
+
+ mov -4(a0),a2
+use_tail_calling_function_sr:
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ movl d1,(a0)
+ add $4,a0
+
+profile_s_:
+ incl n_strict_calls(d1)
+
+profile_n_:
+ mov a0,profile_stack_pointer
+
+ sub global_time_lo,d0
+ sbb global_time_hi,a1
+
+ add d0,time_lo(a2)
+ adc a1,time_hi(a2)
+
+ incl n_profiler_calls(d1)
+
+#ifdef ALLOCATION_PROFILE
+ mov end_heap,a0
+ sub a4,a0
+ mov global_n_bytes_free,d0
+ add $32,a0
+ sub a0,d0
+ mov a0,global_n_bytes_free
+ add d0,n_bytes_allocated(a2)
+#endif
+
+ pop a0
+ pop d1
+
+ rdtsc
+ mov a1,global_time_hi
+ pop a1
+ mov d0,global_time_lo
+ pop d0
+ ret
+
+allocate_function_profile_record_s:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_sr
+
+use_tail_calling_function_s:
+ movl $0,global_last_tail_call
+ jmp use_tail_calling_function_sr
+
+
+/ argument: a2: function name adress-4
+/ result: d1: function profile record adress
+
+allocate_function_profile_record:
+ push d0
+ mov global_n_free_records_in_block,d0
+ mov global_last_allocated_block,d1
+
+ test d0,d0
+ jne no_alloc
+
+ push d1
+ push a0
+ push a1
+
+ pushl $128*FunctionProfile
+ call @allocate_memory
+ add $4,sp
+
+ test d0,d0
+
+ pop a1
+ pop a0
+ pop d1
+
+ je no_memory
+
+ mov d0,d1
+ mov $128,d0
+ mov d1,global_last_allocated_block
+
+no_alloc:
+ dec d0
+ mov d0,global_n_free_records_in_block
+ lea FunctionProfile(d1),d0
+ mov d0,global_last_allocated_block
+
+ xor d0,d0
+ mov d0,time_hi(d1)
+ mov d0,time_lo(d1)
+ mov d0,n_profiler_calls(d1)
+ mov d0,n_strict_calls(d1)
+ mov d0,n_lazy_calls(d1)
+ mov d0,n_curried_calls(d1)
+ mov d0,n_bytes_allocated(d1)
+
+ mov global_profile_records,d0
+ mov a2,name(d1)
+
+ mov d0,next(d1)
+ mov d1,global_profile_records
+
+ mov d1,(a2)
+ pop d0
+ ret
+
+no_memory:
+ movl $not_enough_memory_for_profiler,a2
+ pop d0
+ jmp print_error
+
+write_profile_information:
+ pushl $profile_file_name
+ call @create_profile_file_name
+ addl $4,sp
+
+ mov $1,d0
+ mov $profile_file_name,a0
+ call openF
+
+ pop a0
+ test d1,d1
+ je cannot_open
+
+ mov global_profile_records,a2
+
+write_profile_lp:
+ test a2,a2
+ je end_list
+
+ mov name(a2),a1
+ push a2
+
+#ifdef MODULE_NAMES
+ push a1
+
+ movl -4(a1),a1
+ movl (a1),d1
+ addl $4,a1
+
+write_module_name_lp:
+ subl $1,d1
+ jc end_module_name
+
+ pushl d1
+ movzbl (a1),d1
+ pushl a1
+
+ pushl $l0
+ pushl a0
+ jmp writeFC
+l0:
+ popl a1
+ movl d0,a0
+ movl d1,d0
+ popl d1
+ addl $1,a1
+ jmp write_module_name_lp
+
+end_module_name:
+ mov $' ',d1
+ push $l00
+ push a0
+ jmp writeFC
+l00: mov d0,a0
+ mov d1,d0
+
+ pop a1
+#endif
+
+ add $3,a1
+
+write_function_name_lp:
+ movzbl 1(a1),d1
+ add $1,a1
+
+ test d1,d1
+ je end_function_name
+
+ push a1
+
+ push $l1
+ push a0
+ jmp writeFC
+l1: mov d0,a0
+ mov d1,d0
+
+ pop a1
+ jmp write_function_name_lp
+
+end_function_name:
+ mov $' ',d1
+ push $l2
+ push a0
+ jmp writeFC
+l2: mov d0,a0
+ mov d1,d0
+
+ mov (sp),d1
+ mov n_strict_calls(d1),d1
+ call writeFI_space
+
+ mov (sp),d1
+ mov n_lazy_calls(d1),d1
+ call writeFI_space
+
+ mov (sp),d1
+ mov n_curried_calls(d1),d1
+ call writeFI_space
+
+ mov (sp),d1
+ mov n_profiler_calls(d1),d1
+ call writeFI_space
+
+ mov (sp),d1
+ mov n_bytes_allocated(d1),d1
+ call writeFI_space
+
+ mov (sp),d1
+ mov time_hi(d1),d1
+ call writeFI_space
+
+ mov (sp),d1
+ mov time_lo(d1),d1
+
+ pushl $l3
+ push a0
+ jmp writeFI
+l3: mov d0,a0
+ mov d1,d0
+
+ mov $10,d1
+ pushl $l4
+ push a0
+ jmp writeFC
+l4: mov d0,a0
+ mov d1,d0
+
+ pop a2
+ mov next(a2),a2
+ jmp write_profile_lp
+
+writeFI_space:
+ pushl $l5
+ push a0
+ jmp writeFI
+l5: mov d0,a0
+ mov d1,d0
+
+ push $l6
+ push a0
+ mov $' ',d1
+ jmp writeFC
+l6: mov d0,a0
+ mov d1,d0
+ ret
+
+end_list:
+ mov d0,d1
+ call closeF
+
+cannot_open:
+ ret
+
+write_profile_stack:
+ mov profile_stack_pointer,d0
+
+ test d0,d0
+ je stack_not_initialised
+
+ push d0
+
+ push $stack_trace_string
+ call @ew_print_string
+ add $4,sp
+
+ pop d0
+
+/ mov $12,a2
+ movl @stack_trace_depth,a2
+write_functions_on_stack:
+ mov -4(d0),d1
+ sub $4,d0
+
+ test d1,d1
+ je end_profile_stack
+
+ push d0
+ mov name(d1),a0
+
+ push a2
+ add $4,a0
+
+ push a0
+ call @ew_print_string
+ add $4,sp
+
+ pushl $10
+ call @ew_print_char
+ add $4,sp
+
+ pop a2
+ pop d0
+
+ sub $1,a2
+ jne write_functions_on_stack
+
+end_profile_stack:
+stack_not_initialised:
+ ret
+
+init_profiler:
+ pushfl
+ movl $0x200000,%eax
+ pop %ebx
+ xor %ebx,%eax
+ push %eax
+ popfl
+ pushfl
+ pop %eax
+ xor %ebx,%eax
+ jz no_tsc_error
+
+ movl $1,%eax
+ cpuid
+ andl $16,%edx
+ jz no_tsc_error
+
+ pushl @ab_stack_size
+ call @allocate_memory
+ add $4,sp
+
+ test d0,d0
+ je init_profiler_error
+
+ push d0
+
+ mov $start_string,a2
+ call allocate_function_profile_record
+
+ pop a1
+
+ mov d1,4(a1)
+ movl $0,(a1)
+ add $8,a1
+ mov a1,profile_stack_pointer
+ movl $0,global_last_tail_call
+
+ mov end_heap,a1
+ sub a4,a1
+ add $32,a1
+ mov a1,global_n_bytes_free
+
+ rdtsc
+ mov a1,global_time_hi
+ mov d0,global_time_lo
+ ret
+
+no_tsc_error:
+ movl $0,profile_stack_pointer
+ movl $no_tsc_error_string,a2
+ jmp print_error
+
+init_profiler_error:
+ movl $0,profile_stack_pointer
+ movl $not_enough_memory_for_profile_stack,a2
+ jmp print_error
+
+ .data
+ align (2)
+
+global_n_free_records_in_block: .long 0
+/ 0 n free records in block
+global_last_allocated_block: .long 0
+/ 4 latest allocated block
+global_profile_records: .long 0
+/ 8 profile record list
+global_time_hi: .long 0
+/ 12 clock
+global_time_lo: .long 0
+global_last_tail_call: .long 0
+/ last tail calling function
+global_n_bytes_free: .long 0
+
+profile_file_name:
+ .long __STRING__+2
+ .long 0
+ .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ .long 0
+@stack_trace_depth:
+ .long 12
+ align (2)
+#ifdef MODULE_NAMES
+# if 0
+/ m_system also defined in cgistartup.s
+m_system:
+ .long 6
+ .ascii "System"
+ .byte 0
+ .byte 0
+# endif
+ .long m_system
+#endif
+start_string:
+ .long 0
+ .asciz "start"
+ align (2)
+no_tsc_error_string:
+ .ascii "cannot profile because this processor does not have a time stamp counter"
+ .byte 10
+ .byte 0
+not_enough_memory_for_profile_stack:
+ .ascii "not enough memory for profile stack"
+ .byte 10
+ .byte 0
+not_enough_memory_for_profiler:
+ .ascii "not enough memory for profiler"
+ .byte 10
+ .byte 0
+stack_trace_string:
+ .ascii "Stack trace:"
+ .byte 10
+ .byte 0
+
+ align (2)
diff --git a/istartup.s b/istartup.s
index c2d6220..83b8e38 100644
--- a/istartup.s
+++ b/istartup.s
@@ -3,12 +3,6 @@
/ Author: John van Groningen
/ Machine: Intel 386
-#ifdef _WINDOWS_
-# define WRITE_HEAP
-#else
-# undef WRITE_HEAP
-#endif
-
#define K6_0 0
#define d0 %eax
@@ -41,6 +35,8 @@
#define SHARE_CHAR_INT
#define MY_ITOS
#define FINALIZERS
+#define STACK_OVERFLOW_EXCEPTION_HANDLER
+#define WRITE_HEAP
#undef MEASURE_GC
#undef DEBUG
#undef PREFETCH2
@@ -161,12 +157,15 @@
.comm heap_end_write_heap,4
.comm d3_flag_write_heap,4
.comm heap2_begin_and_end,8
-#endif
+#endif
-#if 1
+#ifdef STACK_OVERFLOW_EXCEPTION_HANDLER
.comm a_stack_guard_page,4
#endif
+ .globl profile_stack_pointer
+ .comm profile_stack_pointer,4
+
.data
align (2)
@@ -495,7 +494,7 @@ start_address:
.globl write_profile_information,write_profile_stack
#endif
.globl __driver
-
+
/ from system.abc:
.global INT
.global CHAR
@@ -730,7 +729,7 @@ init_clean:
#ifdef USE_CLIB
call @malloc
#else
-# if 0
+# ifndef STACK_OVERFLOW_EXCEPTION_HANDLER
call @allocate_memory
# else
call @allocate_memory_with_guard_page_at_end
@@ -742,7 +741,7 @@ init_clean:
je no_memory_3
mov d0,stack_mbp
-#if 1
+#ifdef STACK_OVERFLOW_EXCEPTION_HANDLER
addl @ab_stack_size,d0
addl $3+4095,d0
andl $-4096,d0
@@ -2794,7 +2793,7 @@ no_total_compact_gc_bytes_carry:
lea (d0,d1,4),d0
jmp end_garbage_collect
-#if 1
+#ifdef STACK_OVERFLOW_EXCEPTION_HANDLER
.globl _clean_exception_handler?4
_clean_exception_handler?4:
movl 4(%esp),%eax
diff --git a/itrace.s b/itrace.s
new file mode 100644
index 0000000..80b53b7
--- /dev/null
+++ b/itrace.s
@@ -0,0 +1,419 @@
+
+#undef DEBUG_PROFILER
+
+#define MODULE_NAMES
+
+#define d0 %eax
+#define d1 %ebx
+#define a0 %ecx
+#define a1 %edx
+#define a2 %ebp
+#define a3 %esi
+#define a4 %edi
+#define sp %esp
+
+#if defined(_WINDOWS_)
+# define align(n) .align (1<<n)
+#else
+# define align(n) .align n
+#endif
+
+ .global init_profiler
+ .global profile_r
+ .global profile_l
+ .global profile_l2
+ .global profile_n
+ .global profile_n2
+ .global profile_s
+ .global profile_s2
+ .global profile_t
+ .global write_profile_information
+ .global write_profile_stack
+
+ .global @allocate_memory
+ .global __STRING__
+ .global writeFC
+ .global writeFI
+ .global print_error
+ .global @ab_stack_size
+ .global @ew_print_string
+ .global @ew_print_char
+ .global @stack_trace_depth
+
+#define next 0
+#define name 4
+#define FunctionProfile 8
+
+ .text
+profile_t:
+ push a0
+ mov profile_stack_pointer,a0
+
+ push d1
+ mov -4(a0),d1
+
+ sub $4,a0
+
+ mov a0,profile_stack_pointer
+
+ pop d1
+ pop a0
+ ret
+
+profile_r:
+ push a0
+ mov profile_stack_pointer,a0
+
+ push d1
+ mov -4(a0),d1
+
+ sub $4,a0
+
+ mov a0,profile_stack_pointer
+
+ pop d1
+ pop a0
+ ret
+
+profile_l:
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_l
+allocate_function_profile_record_lr:
+ push a0
+
+ mov profile_stack_pointer,a0
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ add $4,a0
+
+ mov a0,profile_stack_pointer
+
+ pop a0
+ pop d1
+ ret
+
+allocate_function_profile_record_l:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_lr
+
+profile_l2:
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_l2
+allocate_function_profile_record_l2r:
+ push a0
+
+ mov profile_stack_pointer,a0
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ mov d1,4(a0)
+ add $8,a0
+
+ mov a0,profile_stack_pointer
+
+ pop a0
+ pop d1
+ ret
+
+allocate_function_profile_record_l2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_l2r
+
+profile_n:
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_n
+allocate_function_profile_record_nr:
+ push a0
+
+ mov profile_stack_pointer,a0
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ add $4,a0
+
+ mov a0,profile_stack_pointer
+
+ pop a0
+ pop d1
+ ret
+
+allocate_function_profile_record_n:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_nr
+
+profile_n2:
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_n2
+allocate_function_profile_record_n2r:
+ push a0
+
+ mov profile_stack_pointer,a0
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ mov d1,(a0)
+ mov d1,4(a0)
+ add $8,a0
+
+ mov a0,profile_stack_pointer
+
+ pop a0
+ pop d1
+ ret
+
+allocate_function_profile_record_n2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_n2r
+
+profile_s2:
+ push d1
+ mov (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_s2
+allocate_function_profile_record_s2r:
+ push a0
+
+ mov profile_stack_pointer,a0
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ movl d1,(a0)
+ movl d1,4(a0)
+ add $8,a0
+ mov a0,profile_stack_pointer
+
+ pop a0
+ pop d1
+ ret
+
+allocate_function_profile_record_s2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_s2r
+
+profile_s:
+ push d1
+ movl (a2),d1
+
+ test d1,d1
+ je allocate_function_profile_record_s
+allocate_function_profile_record_sr:
+ push a0
+
+ mov profile_stack_pointer,a0
+
+#ifdef DEBUG_PROFILER
+ testl (d1),d1
+#endif
+ movl d1,(a0)
+ add $4,a0
+
+ mov a0,profile_stack_pointer
+
+ pop a0
+ pop d1
+ ret
+
+allocate_function_profile_record_s:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_sr
+
+
+/ argument: a2: function name adress-4
+/ result: d1: function profile record adress
+
+allocate_function_profile_record:
+ push d0
+ mov global_n_free_records_in_block,d0
+ mov global_last_allocated_block,d1
+
+ test d0,d0
+ jne no_alloc
+
+ push d1
+ push a0
+ push a1
+
+ pushl $512*FunctionProfile
+ call @allocate_memory
+ add $4,sp
+
+ test d0,d0
+
+ pop a1
+ pop a0
+ pop d1
+
+ je no_memory
+
+ mov d0,d1
+ mov $512,d0
+ mov d1,global_last_allocated_block
+
+no_alloc:
+ dec d0
+ mov d0,global_n_free_records_in_block
+ lea FunctionProfile(d1),d0
+ mov d0,global_last_allocated_block
+
+ mov global_profile_records,d0
+ mov a2,name(d1)
+
+ mov d0,next(d1)
+ mov d1,global_profile_records
+
+ mov d1,(a2)
+ pop d0
+ ret
+
+no_memory:
+ movl $not_enough_memory_for_profiler,a2
+ pop d0
+ jmp print_error
+
+write_profile_information:
+ ret
+
+write_profile_stack:
+ mov profile_stack_pointer,d0
+
+ test d0,d0
+ je stack_not_initialised
+
+ push d0
+
+ push $stack_trace_string
+ call @ew_print_string
+ add $4,sp
+
+ pop d0
+
+/ mov $12,a2
+ movl @stack_trace_depth,a2
+write_functions_on_stack:
+ mov -4(d0),d1
+ sub $4,d0
+
+ test d1,d1
+ je end_profile_stack
+
+ push d0
+ mov name(d1),a0
+
+ push a2
+ add $4,a0
+
+ push a0
+ call @ew_print_string
+ add $4,sp
+
+ pushl $10
+ call @ew_print_char
+ add $4,sp
+
+ pop a2
+ pop d0
+
+ sub $1,a2
+ jne write_functions_on_stack
+
+end_profile_stack:
+stack_not_initialised:
+ ret
+
+init_profiler:
+ pushl @ab_stack_size
+ call @allocate_memory
+ add $4,sp
+
+ test d0,d0
+ je init_profiler_error
+
+ push d0
+
+ mov $start_string,a2
+ call allocate_function_profile_record
+
+ pop a1
+
+ mov d1,4(a1)
+ movl $0,(a1)
+ add $8,a1
+ mov a1,profile_stack_pointer
+
+ mov end_heap,a1
+ sub a4,a1
+ add $32,a1
+ mov a1,global_n_bytes_free
+ ret
+
+init_profiler_error:
+ movl $0,profile_stack_pointer
+ movl $not_enough_memory_for_profile_stack,a2
+ jmp print_error
+
+ .data
+ align (2)
+
+global_n_free_records_in_block: .long 0
+/ 0 n free records in block
+global_last_allocated_block: .long 0
+/ 4 latest allocated block
+global_profile_records: .long 0
+/ 8 profile record list
+profile_stack_pointer: .long 0
+global_n_bytes_free: .long 0
+
+ align (2)
+@stack_trace_depth:
+ .long 12
+#ifdef MODULE_NAMES
+# if 0
+/ m_system also defined in cgistartup.s
+m_system:
+ .long 6
+ .ascii "System"
+ .byte 0
+ .byte 0
+# endif
+ .long m_system
+#endif
+start_string:
+ .long 0
+ .asciz "start"
+ align (2)
+not_enough_memory_for_profile_stack:
+ .ascii "not enough memory for profile stack"
+ .byte 10
+ .byte 0
+not_enough_memory_for_profiler:
+ .ascii "not enough memory for profiler"
+ .byte 10
+ .byte 0
+stack_trace_string:
+ .ascii "Stack trace:"
+ .byte 10
+ .byte 0
+
+ align (2)