#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
#ifdef MODULE_NAMES
movl -4(a0),a1
#endif
add $4,a0
#ifdef MODULE_NAMES
pushl (a1)
addl $4,a1
pushl a1
#endif
push a0
call @ew_print_string
add $4,sp
#ifdef MODULE_NAMES
pushl $module_string
call @ew_print_string
add $4,sp
call @ew_print_text
addl $8,sp
pushl $']'
call @ew_print_char
add $4,sp
#endif
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
#ifdef MODULE_NAMES
module_string:
.asciz " [module: "
#endif
align (2)