Skip to content

Commit 432c6ba

Browse files
committed
allocator switches to nonzero_fill_calloc when malloc(0) is known to return NULL
1 parent a826a8c commit 432c6ba

File tree

2 files changed

+133
-71
lines changed

2 files changed

+133
-71
lines changed

src/libc/allocator.src

Lines changed: 6 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,15 @@
11
assume adl=1
22

33
section .text
4-
public _malloc, _free, _realloc
54

6-
public _calloc
7-
8-
if defined __TICE__
9-
10-
; uses the hardware specific $E40000 memory location
11-
12-
; void *calloc(size_t nmemb, size_t size)
13-
_calloc:
14-
pop de
15-
pop bc
16-
ex (sp), hl
17-
push bc
18-
push de
19-
call __imulu
20-
push hl
21-
push hl
22-
call _malloc
23-
pop bc ; reset SP
24-
; test for NULL
25-
add hl, bc
26-
or a, a
27-
sbc hl, bc
28-
pop bc ; BC = size
29-
ret z ; return NULL
30-
; inlined bzero
31-
push hl
32-
ex de, hl ; DE = dest
33-
; test if the size is zero
34-
scf
35-
sbc hl, hl
36-
add hl, bc
37-
jr nc, .finish
38-
; large region of all zeros on the Ti84CE
39-
ld hl, $E40000 ; HL = src
40-
ldir
41-
.finish:
42-
pop hl ; return value
43-
ret
44-
45-
else
46-
47-
; makes no hardware assumptions
48-
49-
; void *calloc(size_t nmemb, size_t size)
50-
_calloc:
51-
pop de
52-
pop bc
53-
ex (sp),hl
54-
push bc
55-
push de
56-
call __imulu
57-
push hl
58-
push hl
59-
call _malloc
60-
pop de
61-
add hl,de
62-
xor a,a
63-
sbc hl,de
64-
ld e,a
65-
push de
66-
push hl
67-
call nz,_memset
68-
pop de
69-
pop de
70-
pop de
71-
ret
72-
73-
end if
5+
public _malloc, _free, _realloc, _calloc
746

757
if defined ALLOCATOR_SIMPLE
768

779
_malloc := __simple_malloc
7810
_free := __simple_free
7911
_realloc := __simple_realloc
12+
_calloc := __nonzero_fill_calloc
8013
extern __simple_free
8114
extern __simple_malloc
8215
extern __simple_realloc
@@ -86,6 +19,7 @@ else if defined ALLOCATOR_STANDARD
8619
_malloc := __standard_malloc
8720
_free := __standard_free
8821
_realloc := __standard_realloc
22+
_calloc := __nonzero_fill_calloc
8923
extern __standard_malloc
9024
extern __standard_free
9125
extern __standard_realloc
@@ -95,11 +29,12 @@ else ; custom functions provided by the program
9529
_malloc := __custom_malloc
9630
_free := __custom_free
9731
_realloc := __custom_realloc
32+
_calloc := __generic_calloc
9833
extern __custom_malloc
9934
extern __custom_free
10035
extern __custom_realloc
10136

10237
end if
10338

104-
extern __imulu
105-
extern _memset
39+
extern __nonzero_fill_calloc
40+
extern __generic_calloc

src/libc/calloc.src

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
assume adl=1
2+
3+
; __nonzero_fill_calloc assumes that malloc(0) returns NULL
4+
; __generic_calloc makes no assumptions
5+
6+
;-------------------------------------------------------------------------------
7+
8+
section .text
9+
10+
public __generic_calloc
11+
12+
if defined __TICE__
13+
14+
; uses TICE specific hardware/platform optimizations
15+
16+
; void *calloc(size_t nmemb, size_t size)
17+
__generic_calloc:
18+
pop de
19+
pop bc
20+
ex (sp), hl
21+
push bc
22+
push de
23+
call __imulu
24+
push hl
25+
push hl
26+
call _malloc
27+
pop bc ; reset SP
28+
pop bc ; BC = size
29+
; test for NULL
30+
add hl, bc
31+
; or a, a ; assumes that ptr + size does not overflow on TICE
32+
sbc hl, bc
33+
ret z ; return NULL
34+
; inlined bzero
35+
push hl
36+
ex de, hl ; DE = dest
37+
; test if the size is zero
38+
scf
39+
sbc hl, hl
40+
add hl, bc
41+
jr nc, .finish
42+
; large region of all zeros on the Ti84CE
43+
ld hl, $E40000 ; HL = src
44+
ldir
45+
pop hl ; return value
46+
ret
47+
48+
else
49+
50+
; makes no hardware assumptions
51+
52+
; void *calloc(size_t nmemb, size_t size)
53+
__generic_calloc:
54+
pop de
55+
pop bc
56+
ex (sp),hl
57+
push bc
58+
push de
59+
call __imulu
60+
push hl
61+
push hl
62+
call _malloc
63+
pop de
64+
add hl,de
65+
xor a,a
66+
sbc hl,de
67+
ld e,a
68+
push de
69+
push hl
70+
call nz,_memset
71+
pop de
72+
pop de
73+
pop de
74+
ret
75+
76+
end if
77+
78+
;-------------------------------------------------------------------------------
79+
80+
section .text
81+
82+
public __nonzero_fill_calloc
83+
84+
if defined __TICE__
85+
86+
; uses TICE specific hardware/platform optimizations
87+
88+
; void *calloc(size_t nmemb, size_t size)
89+
__nonzero_fill_calloc:
90+
pop de
91+
pop bc
92+
ex (sp), hl
93+
push bc
94+
push de
95+
call __imulu
96+
push hl
97+
push hl
98+
call _malloc
99+
pop bc ; reset SP
100+
pop bc ; BC = size
101+
; test for NULL
102+
add hl, bc
103+
; or a, a ; assumes that ptr + size does not overflow on TICE
104+
sbc hl, bc
105+
ret z ; return NULL
106+
; assumes that malloc(0) returns NULL, so we can skip the check for zero bytes
107+
push hl
108+
ex de, hl
109+
; large region of all zeros on the Ti84CE
110+
ld hl, $E40000
111+
ldir
112+
pop hl
113+
ret
114+
115+
else
116+
117+
; makes no hardware assumptions
118+
119+
_nonzero_fill_calloc := _generic_calloc
120+
121+
end if
122+
123+
;-------------------------------------------------------------------------------
124+
125+
extern __imulu
126+
extern _malloc
127+
extern _memset

0 commit comments

Comments
 (0)