string asis
macro
lea &r,&a
lwz &r,&a{TC}(RTOC)
endm
; MACOSX set 1
; POWER601 set 1
ALLOCATION_PROFILE set 1
USE_TEMPORARY_MEMORY set 1
CHECK_STACK_OVERFLOWS set 0
MODULE_NAMES set 1
if POWER601
macro
time_hi &r
dialect Power
mfrtcu &r
dialect PowerPC
endm
macro
time_lo &r
dialect Power
mfrtcl &r
dialect PowerPC
endm
else
macro
time_hi &r
mftbu &r
endm
macro
time_lo &r
mftb &r
endm
endif
d0: set r24
d1: set r25
d2: set r26
d3: set r27
d4: set r28
d5: set r29
d6: set r30
d7: set r31
a0: set r23
a1: set r22
a2: set r21
a3: set r20
a4: set r19
a5: set r18
a6: set r17
o0: set r3
o1: set r4
o2: set r5
o3: set r6
o4: set r7
o5: set r8
g2: set r9
g3: set r10
g0: set r11
g1: set r12
int_reg set r16
char_reg set r15
real_reg set r14
bool_reg set r13
if POWER601
lo1e9 set 1000000000 % 65536
hi1e9 set (1000000000 / 65536)+1
endif
export init_profiler
export profile_r
export profile_l
export profile_l2
export profile_n
export profile_n2
export profile_s
export profile_s2
export profile_t
export profile_ti
export write_profile_information
export write_profile_stack
if USE_TEMPORARY_MEMORY
import .TempNewHandle
import .TempHLock
import .TempHUnlock
import .TempDisposeHandle
else
import .NewPtr
endif
import .Gestalt
import __STRING__
import openF
import closeF
import writeFC
import writeFI
import print_error
import new_file_creator
import stack_size
import .er_print_string
import .er_print_char
import .create_profile_file_name
if CHECK_STACK_OVERFLOWS
import .Debugger
endif
FunctionProfile: record
next: ds.l 1
time_hi: ds.l 1
time_lo: ds.l 1
n_profiler_calls: ds.l 1
n_strict_calls: ds.l 1
n_lazy_calls: ds.l 1
n_curried_calls: ds.l 1
n_words_allocated: ds.l 1
name: ds.l 1
endr
csect .profile_t
profile_ti:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
lea r5,profile_globals
b profile_t_
profile_t:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
mflr r12
lea r5,profile_globals
mtctr r12
mtlr r0
profile_t_:
lwz r6,Globals.stack_pointer(r5)
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
lwzu r4,-4(r6)
stw r6,Globals.stack_pointer(r5)
stw r4,Globals.last_tail_call(r5)
if POWER601
sub. r10,r10,r8
sub r9,r9,r7
bge+ @no_borrow
addis r10,r10,hi1e9
addi r10,r10,lo1e9
subi r9,r9,1
@no_borrow:
else
subc r10,r10,r8
subfe r9,r7,r9
endif
lwz r8,FunctionProfile.time_lo(r4)
lwz r7,FunctionProfile.time_hi(r4)
if POWER601
add r8,r8,r10
add r7,r7,r9
subis r9,r8,hi1e9
cmpwi 0,r9,lo1e9
lwz r6,FunctionProfile.n_profiler_calls(r4)
blt+ @no_carry
subi r8,r9,lo1e9
addi r7,r7,1
@no_carry:
else
addc r8,r8,r10
lwz r6,FunctionProfile.n_profiler_calls(r4)
adde r7,r7,r9
endif
addi r6,r6,1
stw r7,FunctionProfile.time_hi(r4)
stw r8,FunctionProfile.time_lo(r4)
stw r6,FunctionProfile.n_profiler_calls(r4)
if ALLOCATION_PROFILE
lwz r11,Globals.n_words_free(r5)
stw d7,Globals.n_words_free(r5)
lwz r12,FunctionProfile.n_words_allocated(r4)
sub r11,r11,d7
add r12,r12,r11
stw r12,FunctionProfile.n_words_allocated(r4)
endif
@store_clock:
time_hi r9
stw r9,Globals.time_hi(r5)
time_lo r10
time_hi r4
stw r10,Globals.time_lo(r5)
cmpw 0,r4,r9
beqctr+
b @store_clock
csect .profile_r
profile_r:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
lea r5,profile_globals
lwz r6,Globals.stack_pointer(r5)
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
lwzu r4,-4(r6)
li r3,0
stw r6,Globals.stack_pointer(r5)
stw r3,Globals.last_tail_call(r5)
if POWER601
sub. r10,r10,r8
sub r9,r9,r7
bge+ @no_borrow
addis r10,r10,hi1e9
addi r10,r10,lo1e9
subi r9,r9,1
@no_borrow:
else
subc r10,r10,r8
subfe r9,r7,r9
endif
lwz r8,FunctionProfile.time_lo(r4)
lwz r7,FunctionProfile.time_hi(r4)
if POWER601
add r8,r8,r10
add r7,r7,r9
subis r9,r8,hi1e9
cmpwi 0,r9,lo1e9
lwz r6,FunctionProfile.n_profiler_calls(r4)
blt+ @no_carry
subi r8,r9,lo1e9
addi r7,r7,1
@no_carry:
else
addc r8,r8,r10
lwz r6,FunctionProfile.n_profiler_calls(r4)
adde r7,r7,r9
endif
addi r6,r6,1
stw r7,FunctionProfile.time_hi(r4)
stw r8,FunctionProfile.time_lo(r4)
stw r6,FunctionProfile.n_profiler_calls(r4)
if ALLOCATION_PROFILE
lwz r11,Globals.n_words_free(r5)
stw d7,Globals.n_words_free(r5)
lwz r12,FunctionProfile.n_words_allocated(r4)
sub r11,r11,d7
add r12,r12,r11
stw r12,FunctionProfile.n_words_allocated(r4)
endif
@store_clock:
time_hi r9
stw r9,Globals.time_hi(r5)
time_lo r10
time_hi r4
stw r10,Globals.time_lo(r5)
cmpw 0,r4,r9
beqlr+
b @store_clock
csect .profile_l
profile_l:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
mflr r12
lea r5,profile_globals
lwz r4,0(r3)
mtctr r12
cmpwi 0,r4,0
beql allocate_function_profile_record
lwz r3,Globals.last_tail_call(r5)
lwz r6,Globals.stack_pointer(r5)
cmpwi 0,r3,0
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
bne @use_tail_calling_function
lwz r3,-4(r6)
@c_use_tail_calling_function:
stw r4,0(r6)
addi r6,r6,4
if CHECK_STACK_OVERFLOWS
lwz r12,Globals.end_profile_stack(r5)
endif
stw r6,Globals.stack_pointer(r5)
if CHECK_STACK_OVERFLOWS
cmpw r6,r12
bge profile_stack_overflow
endif
lwz r6,FunctionProfile.n_curried_calls(r4)
mtlr r0
addi r6,r6,1
stw r6,FunctionProfile.n_curried_calls(r4)
b profile_n_
@use_tail_calling_function:
li r12,0
stw r12,Globals.last_tail_call(r5)
b @c_use_tail_calling_function
csect .profile_l2
profile_l2:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
mflr r12
lea r5,profile_globals
lwz r4,0(r3)
mtctr r12
cmpwi 0,r4,0
beql allocate_function_profile_record
lwz r3,Globals.last_tail_call(r5)
lwz r6,Globals.stack_pointer(r5)
cmpwi 0,r3,0
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
bne @use_tail_calling_function
lwz r3,-4(r6)
@c_use_tail_calling_function:
stw r4,0(r6)
stw r4,4(r6)
addi r6,r6,8
if CHECK_STACK_OVERFLOWS
lwz r12,Globals.end_profile_stack(r5)
endif
stw r6,Globals.stack_pointer(r5)
if CHECK_STACK_OVERFLOWS
cmpw r6,r12
bge profile_stack_overflow
endif
lwz r6,FunctionProfile.n_curried_calls(r4)
mtlr r0
addi r6,r6,1
stw r6,FunctionProfile.n_curried_calls(r4)
b profile_n_
@use_tail_calling_function:
li r12,0
stw r12,Globals.last_tail_call(r5)
b @c_use_tail_calling_function
csect .profile_n
profile_n:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
mflr r12
lea r5,profile_globals
lwz r4,0(r3)
mtctr r12
cmpwi 0,r4,0
beql allocate_function_profile_record
lwz r3,Globals.last_tail_call(r5)
lwz r6,Globals.stack_pointer(r5)
cmpwi 0,r3,0
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
bne @use_tail_calling_function
lwz r3,-4(r6)
@c_use_tail_calling_function:
stw r4,0(r6)
addi r6,r6,4
if CHECK_STACK_OVERFLOWS
lwz r12,Globals.end_profile_stack(r5)
endif
stw r6,Globals.stack_pointer(r5)
if CHECK_STACK_OVERFLOWS
cmpw r6,r12
bge profile_stack_overflow
endif
lwz r6,FunctionProfile.n_lazy_calls(r4)
mtlr r0
addi r6,r6,1
stw r6,FunctionProfile.n_lazy_calls(r4)
b profile_n_
@use_tail_calling_function:
li r12,0
stw r12,Globals.last_tail_call(r5)
b @c_use_tail_calling_function
csect .profile_n2
profile_n2:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
mflr r12
lea r5,profile_globals
lwz r4,0(r3)
mtctr r12
cmpwi 0,r4,0
beql allocate_function_profile_record
lwz r3,Globals.last_tail_call(r5)
lwz r6,Globals.stack_pointer(r5)
cmpwi 0,r3,0
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
bne @use_tail_calling_function
lwz r3,-4(r6)
@c_use_tail_calling_function:
stw r4,0(r6)
stw r4,4(r6)
addi r6,r6,8
if CHECK_STACK_OVERFLOWS
lwz r12,Globals.end_profile_stack(r5)
endif
stw r6,Globals.stack_pointer(r5)
if CHECK_STACK_OVERFLOWS
cmpw r6,r12
bge profile_stack_overflow
endif
lwz r6,FunctionProfile.n_lazy_calls(r4)
mtlr r0
addi r6,r6,1
stw r6,FunctionProfile.n_lazy_calls(r4)
b profile_n_
@use_tail_calling_function:
li r12,0
stw r12,Globals.last_tail_call(r5)
b @c_use_tail_calling_function
csect .profile_s2
profile_s2:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
mflr r12
lea r5,profile_globals
lwz r4,0(r3)
mtctr r12
cmpwi 0,r4,0
beql allocate_function_profile_record
lwz r3,Globals.last_tail_call(r5)
lwz r6,Globals.stack_pointer(r5)
cmpwi 0,r3,0
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
bne @use_tail_calling_function
lwz r3,-4(r6)
@c_use_tail_calling_function:
stw r4,0(r6)
stw r4,4(r6)
addi r6,r6,8
if CHECK_STACK_OVERFLOWS
lwz r12,Globals.end_profile_stack(r5)
endif
stw r6,Globals.stack_pointer(r5)
if CHECK_STACK_OVERFLOWS
cmpw r6,r12
bge profile_stack_overflow
endif
b profile_s_
@use_tail_calling_function:
li r12,0
stw r12,Globals.last_tail_call(r5)
b @c_use_tail_calling_function
csect .profile_s
profile_s:
@read_clock:
time_hi r9
time_lo r10
time_hi r4
cmpw 0,r4,r9
bne- @read_clock
mflr r12
lea r5,profile_globals
lwz r4,0(r3)
mtctr r12
cmpwi 0,r4,0
beql allocate_function_profile_record
lwz r3,Globals.last_tail_call(r5)
lwz r6,Globals.stack_pointer(r5)
cmpwi 0,r3,0
lwz r7,Globals.time_hi(r5)
lwz r8,Globals.time_lo(r5)
bne use_tail_calling_function0
lwz r3,-4(r6)
c_use_tail_calling_function0:
stw r4,0(r6)
addi r6,r6,4
if CHECK_STACK_OVERFLOWS
lwz r12,Globals.end_profile_stack(r5)
endif
stw r6,Globals.stack_pointer(r5)
if CHECK_STACK_OVERFLOWS
cmpw r6,r12
bge profile_stack_overflow
endif
profile_s_:
lwz r6,FunctionProfile.n_strict_calls(r4)
mtlr r0
addi r6,r6,1
stw r6,FunctionProfile.n_strict_calls(r4)
profile_n_:
if POWER601
sub. r10,r10,r8
sub r9,r9,r7
bge+ @no_borrow
addis r10,r10,hi1e9
addi r10,r10,lo1e9
subi r9,r9,1
@no_borrow:
else
subc r10,r10,r8
subfe r9,r7,r9
endif
lwz r8,FunctionProfile.time_lo(r3)
lwz r7,FunctionProfile.time_hi(r3)
if POWER601
add r8,r8,r10
add r7,r7,r9
subis r9,r8,hi1e9
cmpwi 0,r9,lo1e9
lwz r6,FunctionProfile.n_profiler_calls(r3)
blt+ @no_carry
subi r8,r9,lo1e9
addi r7,r7,1
@no_carry:
else
addc r8,r8,r10
lwz r6,FunctionProfile.n_profiler_calls(r3)
adde r7,r7,r9
endif
addi r6,r6,1
stw r7,FunctionProfile.time_hi(r3)
stw r8,FunctionProfile.time_lo(r3)
stw r6,FunctionProfile.n_profiler_calls(r3)
if ALLOCATION_PROFILE
lwz r11,Globals.n_words_free(r5)
stw d7,Globals.n_words_free(r5)
lwz r12,FunctionProfile.n_words_allocated(r3)
sub r11,r11,d7
add r12,r12,r11
stw r12,FunctionProfile.n_words_allocated(r3)
endif
@store_clock:
time_hi r9
stw r9,Globals.time_hi(r5)
time_lo r10
time_hi r4
stw r10,Globals.time_lo(r5)
cmpw 0,r4,r9
beqctr+
b @store_clock
use_tail_calling_function0:
li r12,0
stw r12,Globals.last_tail_call(r5)
b c_use_tail_calling_function0
allocate_function_profile_record:
lwz r6,Globals.n_free_records_in_block(r5)
lwz r4,Globals.last_allocated_block(r5)
cmpwi 0,r6,0
bne+ no_alloc
stw r0,-4(sp)
stw r3,-8(sp)
stw r9,-12(sp)
stw r10,-16(sp)
mfctr r11
stw r11,-20(sp)
mflr r12
stw r12,-24(sp)
if USE_TEMPORARY_MEMORY
li r3,(128*FunctionProfile)+4
else
li r3,128*FunctionProfile
endif
if MACOSX
mr g0,sp
ori sp,sp,28
stwu g0,-(64+32+28)(sp)
else
stwu sp,-(64+32)(sp)
endif
if USE_TEMPORARY_MEMORY
bl allocate_temp_memory_handle
else
bl .NewPtr
nop
endif
if MACOSX
lwz sp,0(sp)
else
addi sp,sp,64+32
endif
and. r4,r3,r3
lwz r12,-24(sp)
lwz r11,-20(sp)
mtlr r12
lwz r10,-16(sp)
mtctr r11
lwz r9,-12(sp)
lwz r3,-8(sp)
lwz r0,-4(sp)
lea r5,profile_globals
beq profiler_memory_error
if USE_TEMPORARY_MEMORY
lwz r6,Globals.temp_handle_list(r5)
stw r4,Globals.temp_handle_list(r5)
lwz r4,0(r4)
stw r6,0(r4)
addi r4,r4,4
endif
li r6,128
stw r4,Globals.last_allocated_block(r5)
no_alloc:
subi r6,r6,1
stw r6,Globals.n_free_records_in_block(r5)
addi r7,r4,FunctionProfile
stw r7,Globals.last_allocated_block(r5)
lwz r6,Globals.profile_records(r5)
li r8,0
stw r8,FunctionProfile.time_hi(r4)
stw r8,FunctionProfile.time_lo(r4)
stw r8,FunctionProfile.n_profiler_calls(r4)
stw r8,FunctionProfile.n_strict_calls(r4)
stw r8,FunctionProfile.n_lazy_calls(r4)
stw r8,FunctionProfile.n_curried_calls(r4)
stw r8,FunctionProfile.n_words_allocated(r4)
stw r6,FunctionProfile.next(r4)
stw r4,Globals.profile_records(r5)
stw r3,FunctionProfile.name(r4)
stw r4,0(r3)
blr
csect .write_profile_information
write_profile_information:
lea o0,profile_file_name
mflr r0
stwu r0,-4(sp)
if MACOSX
mr g0,sp
ori sp,sp,28
stwu g0,-(64+28)(sp)
else
stwu sp,-64(sp)
endif
bl .create_profile_file_name
nop
if MACOSX
lwz sp,0(sp)
lwz r0,0(sp)
addi sp,sp,4
else
lwz r0,64(sp)
addi sp,sp,68
endif
mtlr r0
lea d3,new_file_creator
li d5,'T'*256+'I'
lwz d4,0(d3)
addis d5,d5,'P'*256+'R'
stw d5,0(d3)
li d0,1
lea a0,profile_file_name
mflr r0
stwu r0,-4(sp)
bl openF
mtlr r0
stw d4,0(d3)
cmpwi 0,d2,0
beq cannot_open
mflr r0
li d3,0
stw r0,-4(sp)
stwu d3,-8(sp)
if MACOSX
mr g0,sp
ori sp,sp,28
stwu g0,-(64+28)(sp)
else
stwu sp,-64(sp)
endif
stw d3,64(sp)
li r3,'u'*256+'t'
addi r4,sp,64
addis r3,r3,'c'*256+'p'
bl .Gestalt
nop
lwz d2,64(sp)
stwu r0,-4(sp)
bl writeFI_space
mtlr r0
stw d3,64(sp)
li r3,'l'*256+'k'
addi r4,sp,64
addis r3,r3,'p'*256+'c'
bl .Gestalt
nop
lwz d2,64(sp)
stwu r0,-4(sp)
bl writeFI_space
mtlr r0
stw d3,64(sp)
li r3,'l'*256+'k'
addi r4,sp,64
addis r3,r3,'b'*256+'c'
bl .Gestalt
nop
lwz d2,64(sp)
stwu r0,-4(sp)
bl writeFI
mtlr r0
li d2,13
stwu r0,-4(sp)
bl writeFC
mtlr r0
if MACOSX
lwz sp,0(sp)
lwz r0,4(sp)
addi sp,sp,8
else
lwz r0,68(sp)
addi sp,sp,72
endif
mtlr r0
lea d2,profile_globals
lwz d2,Globals.profile_records(d2)
write_profile_lp:
cmpwi 0,d2,0
beq end_list
lwz d3,FunctionProfile.name(d2)
stwu d2,-4(sp)
#if MODULE_NAMES
stwu d3,-4(sp)
lwz d3,-4(d3)
lwz d2,0(d3)
addi d3,d3,3
write_module_name_lp:
subic. d2,d2,1
blt end_module_name
stw d2,-4(sp)
lbzu d2,1(d3)
mflr r0
stw d3,-8(sp)
stwu r0,-12(sp)
bl writeFC
mtlr r0
lwz d2,4(sp)
lwz d3,0(sp)
addi sp,sp,8
b write_module_name_lp
end_module_name:
li d2,' '
mflr r0
stwu r0,-4(sp)
bl writeFC
mtlr r0
lwz d3,0(sp)
addi sp,sp,4
#endif
addi d3,d3,3
write_function_name_lp:
lbzu d2,1(d3)
cmpwi 0,d2,0
beq end_function_name
stw d3,-4(sp)
mflr r0
stwu r0,-8(sp)
bl writeFC
mtlr r0
lwz d3,0(sp)
addi sp,sp,4
b write_function_name_lp
end_function_name:
li d2,' '
mflr r0
stwu r0,-4(sp)
bl writeFC
lwz d2,0(sp)
lwz d2,FunctionProfile.n_strict_calls(d2)
stwu r0,-4(sp)
bl writeFI_space
lwz d2,0(sp)
lwz d2,FunctionProfile.n_lazy_calls(d2)
stwu r0,-4(sp)
bl writeFI_space
lwz d2,0(sp)
lwz d2,FunctionProfile.n_curried_calls(d2)
stwu r0,-4(sp)
bl writeFI_space
lwz d2,0(sp)
lwz d2,FunctionProfile.n_profiler_calls(d2)
stwu r0,-4(sp)
bl writeFI_space
lwz d2,0(sp)
lwz d2,FunctionProfile.n_words_allocated(d2)
stwu r0,-4(sp)
bl writeFI_space
lwz d2,0(sp)
lwz d2,FunctionProfile.time_hi(d2)
stwu r0,-4(sp)
bl writeFI_space
lwz d2,0(sp)
lwz d2,FunctionProfile.time_lo(d2)
stwu r0,-4(sp)
bl writeFI
li d2,13
stwu r0,-4(sp)
bl writeFC
mtlr r0
lwz d2,0(sp)
addi sp,sp,4
lwz d2,FunctionProfile.next(d2)
b write_profile_lp
writeFI_space:
mflr r0
stwu r0,-4(sp)
bl writeFI
mtlr r0
li d2,' '
b writeFC
end_list:
mflr r0
stwu r0,-4(sp)
bl closeF
mtlr r0
cannot_open:
if USE_TEMPORARY_MEMORY
mflr r0
if MACOSX
mr g0,sp
ori sp,sp,28
stwu g0,-(96+28)(sp)
else
stwu sp,-96(sp)
endif
stw r0,96-4(sp)
lea r5,profile_globals
lwz r3,Globals.profile_stack_handle(r5)
bl free_temp_memory_handle
lea r5,profile_globals
stw r31,96-8(sp)
lwz r31,Globals.temp_handle_list(r5)
b free_temp_handles
free_temp_handles_lp:
mr r3,r31
lwz r31,0(r31)
lwz r31,0(r31)
bl free_temp_memory_handle
free_temp_handles:
cmpwi 0,r31,0
bne free_temp_handles_lp
lwz r31,96-8(sp)
lwz r0,96-4(sp)
if MACOSX
lwz sp,0(sp)
else
addi sp,sp,96
endif
mtlr r0
endif
lwz r0,0(sp)
addi sp,sp,4
blr
csect .write_profile_stack
write_profile_stack:
mflr r0
lea d0,profile_globals
stwu r0,-4(sp)
lwz d0,Globals.stack_pointer(d0)
cmpwi 0,d0,0
beq @stack_not_initialised
if MACOSX
mr g0,sp
ori sp,sp,28
stwu g0,-(64+28)(sp)
else
stwu sp,-64(sp)
endif
lea o0,stack_trace_string
bl .er_print_string
nop
if MACOSX
lwz sp,0(sp)
else
addi sp,sp,64
endif
if 1
li d2,12
else
li d2,24
endif
@write_functions_on_stack
lwzu d1,-4(d0)
cmpwi 0,d1,0
beq @end_profile_stack
lwz o0,FunctionProfile.name(d1)
if MACOSX
mr g0,sp
ori sp,sp,28
stwu g0,-(64+28)(sp)
else
stwu sp,-64(sp)
endif
addi o0,o0,4
bl .er_print_string
nop
li o0,13
bl .er_print_char
nop
if MACOSX
lwz sp,0(sp)
else
addi sp,sp,64
endif
subic. d2,d2,1
if 0
b @write_functions_on_stack
else
bne @write_functions_on_stack
endif
@end_profile_stack:
@stack_not_initialised:
lwz r0,0(sp)
mtlr r0
lwz r0,4(sp)
addi sp,sp,8
blr
csect .init_profiler
init_profiler:
if 0
mflr r0
stw r0,-4(sp)
stwu sp,-64(sp)
bl .Debugger
nop
lwz r0,64-4(sp)
addi sp,sp,64
mtlr r0
endif
mflr r0
stwu r0,-4(sp)
if MACOSX
subi sp,sp,8
mr g0,sp
ori sp,sp,28
stwu g0,-(64+28)(sp)
else
stwu sp,-72(sp)
endif
li r3,0
addi r4,sp,64
stw r3,64(sp)
li r3,'u'*256+'t'
addis r3,r3,'c'*256+'p'
bl .Gestalt
nop
lwz r3,64(sp)
if MACOSX
lwz sp,0(sp)
addi sp,sp,8
else
addi sp,sp,72
endif
cmpwi 0,r3,257
if POWER601
bne init_profiler_error1
else
beq init_profiler_error1
endif
if 1
lea r3,stack_size
lwz r3,0(r3)
addi r3,r3,4095
rlwinm r3,r3,0,0,31-12
else
li r3, (512*1024) % 65536
addis r3,r3,(512*1024) / 65536
endif
if MACOSX
mr g0,sp
ori sp,sp,28
stwu g0,-(64+28)(sp)
else
stwu sp,-64(sp)
endif
if USE_TEMPORARY_MEMORY
bl allocate_temp_memory_handle
else
bl .NewPtr
nop
endif
if MACOSX
lwz sp,0(sp)
else
addi sp,sp,64
endif
lea r5,profile_globals
and. r9,r3,r3
beq init_profiler_error
if USE_TEMPORARY_MEMORY
stw r9,Globals.profile_stack_handle(r5)
lwz r9,0(r9)
li r0,0
stw r0,Globals.temp_handle_list(r5)
endif
if CHECK_STACK_OVERFLOWS
if 1
lea r3,stack_size
lwz r3,0(r3)
else
li r3, (512*1024) % 65536
addis r3,r3,(512*1024) / 65536
endif
add r3,r3,r9
stw r3,Globals.end_profile_stack(r5)
endif
lea r3,start_string
bl allocate_function_profile_record
lwz r0,0(sp)
addi sp,sp,4
mtlr r0
li r0,0
stw r4,4(r9)
stw r0,0(r9)
addi r9,r9,8
stw r9,Globals.stack_pointer(r5)
stw r0,Globals.last_tail_call(r5)
stw d7,Globals.n_words_free(r5)
lwz r0,0(sp)
addi sp,sp,4
@store_clock:
time_hi r9
stw r9,Globals.time_hi(r5)
time_lo r10
time_hi r4
stw r10,Globals.time_lo(r5)
cmpw 0,r4,r9
beqlr+
b @store_clock
if USE_TEMPORARY_MEMORY
allocate_temp_memory_handle:
mflr r0
stw r31,-4(sp)
stw r0,8(sp)
stwu sp,-96(sp)
addi r4,sp,56
bl .TempNewHandle
nop
mr. r31,r3
beq return_r31
addi r4,sp,56
bl .TempHLock
nop
lha r0,56(sp)
cmpwi r0,0
beq+ return_r31
mr r3,r31
addi r4,sp,56
bl .TempDisposeHandle
nop
li r31,0
return_r31:
lwz r0,104(sp)
mr r3,r31
mtlr r0
addi sp,sp,96
lwz r31,-4(sp)
blr
free_temp_memory_handle:
mflr r0
stw r3,-4(sp)
stw r0,8(sp)
stwu sp,-96(sp)
addi r4,sp,56
bl .TempHUnlock
nop
lwz r3,96-4(sp)
addi r4,sp,56
bl .TempDisposeHandle
nop
lwz r0,104(sp)
addi sp,sp,96
mtlr r0
blr
endif
init_profiler_error1:
lea o0,wrong_processor
lea r5,profile_globals
li r4,0
stw r4,Globals.stack_pointer(r5)
b print_error
init_profiler_error:
lea o0,not_enough_memory_for_profile_stack
lea r5,profile_globals
li r4,0
stw r4,Globals.stack_pointer(r5)
b print_error
profiler_memory_error:
lea o0,not_enough_memory_for_profiler
b print_error
if CHECK_STACK_OVERFLOWS
profile_stack_overflow:
mflr r0
stw r0,-4(sp)
stwu sp,-64(sp)
bl .Debugger
nop
lwz r0,64-4(sp)
addi sp,sp,64
mtlr r0
b profile_stack_overflow
endif
csect data{RW}
Globals: record
n_free_records_in_block:ds.l 1 ; 0 n free records in block
last_allocated_block: ds.l 1 ; 4 latest allocated block
profile_records: ds.l 1 ; 8 profile record list
time_hi: ds.l 1 ; 12 clock
time_lo: ds.l 1
stack_pointer: ds.l 1 ; 20 stack pointer
last_tail_call ds.l 1 ; 24 last tail calling function
n_words_free: ds.l 1
if USE_TEMPORARY_MEMORY
temp_handle_list ds.l 1
profile_stack_handle ds.l 1
endif
if CHECK_STACK_OVERFLOWS
end_profile_stack ds.l 1
endif
endr
align 2
profile_globals: ds Globals
profile_file_name:
dc.l __STRING__+2
dc.l 0
ds.b 32
align 2
if MODULE_NAMES
m_system:
dc.l 6
dc.b 'System'
dc.b 0,0
dc.l m_system
endif
start_string:
dc.l 0
dc.b 'start'
dc.b 0
align 2
not_enough_memory_for_profile_stack:
dc.b 'not enough memory for profile stack'
dc.b 13
dc.b 0
not_enough_memory_for_profiler:
dc.b 'not enough memory for profiler'
dc.b 13
dc.b 0
wrong_processor:
if POWER601
dc.b 'Not a PowerPC601 processor (don''t use profiling option for 601)'
else
dc.b 'This is a PowerPC601 processor (use profiling option for 601)'
endif
dc.b 13
dc.b 0
stack_trace_string:
dc.b 'Stack trace:'
dc.b 13
dc.b 0
align 2
macro
te &address
tc &address{TC},&address
endm
toc
te profile_globals
te profile_file_name
te not_enough_memory_for_profile_stack
te not_enough_memory_for_profiler
te wrong_processor
te start_string
te stack_trace_string
te new_file_creator
te stack_size