Skip to content

Commit 07d546f

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

File tree

2 files changed

+178
-80
lines changed

2 files changed

+178
-80
lines changed

src/libc/allocator.src

Lines changed: 15 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,40 @@
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
80-
extern __simple_free
81-
extern __simple_malloc
82-
extern __simple_realloc
12+
_calloc := __nonzero_fill_calloc
13+
extern __simple_free
14+
extern __simple_malloc
15+
extern __simple_realloc
8316

8417
else if defined ALLOCATOR_STANDARD
8518

8619
_malloc := __standard_malloc
8720
_free := __standard_free
8821
_realloc := __standard_realloc
89-
extern __standard_malloc
90-
extern __standard_free
91-
extern __standard_realloc
22+
_calloc := __nonzero_fill_calloc
23+
extern __standard_malloc
24+
extern __standard_free
25+
extern __standard_realloc
9226

9327
else ; custom functions provided by the program
9428

9529
_malloc := __custom_malloc
9630
_free := __custom_free
9731
_realloc := __custom_realloc
98-
extern __custom_malloc
99-
extern __custom_free
100-
extern __custom_realloc
32+
_calloc := __generic_calloc
33+
extern __custom_malloc
34+
extern __custom_free
35+
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: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
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 bc ; reset SP
64+
pop bc ; BC = size
65+
; test for NULL
66+
add hl, bc
67+
xor a, a
68+
sbc hl, bc
69+
ret z ; return NULL
70+
; inlined memset/bzero
71+
cpi
72+
add hl, bc
73+
ret c ; size is zero
74+
dec hl
75+
ld (hl), a
76+
ret po ; size is one
77+
push hl
78+
pop de
79+
dec de
80+
lddr
81+
ret
82+
83+
end if
84+
85+
;-------------------------------------------------------------------------------
86+
87+
section .text
88+
89+
public __nonzero_fill_calloc
90+
91+
if defined __TICE__
92+
93+
; uses TICE specific hardware/platform optimizations
94+
95+
; void *calloc(size_t nmemb, size_t size)
96+
__nonzero_fill_calloc:
97+
pop de
98+
pop bc
99+
ex (sp), hl
100+
push bc
101+
push de
102+
call __imulu
103+
push hl
104+
push hl
105+
call _malloc
106+
pop bc ; reset SP
107+
pop bc ; BC = size
108+
; test for NULL
109+
add hl, bc
110+
; or a, a ; assumes that ptr + size does not overflow on TICE
111+
sbc hl, bc
112+
ret z ; return NULL
113+
; inlined bzero
114+
; assumes that malloc(0) returns NULL, so we can skip the check for zero size
115+
push hl
116+
ex de, hl ; DE = dest
117+
; large region of all zeros on the Ti84CE
118+
ld hl, $E40000 ; HL = src
119+
ldir
120+
pop hl ; return value
121+
ret
122+
123+
else
124+
125+
; makes no hardware assumptions
126+
127+
; void *calloc(size_t nmemb, size_t size)
128+
__nonzero_fill_calloc:
129+
pop de
130+
pop bc
131+
ex (sp), hl
132+
push bc
133+
push de
134+
call __imulu
135+
push hl
136+
push hl
137+
call _malloc
138+
pop bc ; reset SP
139+
pop bc ; BC = size
140+
; test for NULL
141+
add hl, bc
142+
xor a, a
143+
sbc hl, bc
144+
ret z ; return NULL
145+
; inlined memset/bzero
146+
; assumes that malloc(0) returns NULL, so we can skip the check for zero size
147+
add hl, bc
148+
cpd
149+
ld (hl), a
150+
ret po ; size is one
151+
push hl
152+
pop de
153+
dec de
154+
lddr
155+
ret
156+
157+
end if
158+
159+
;-------------------------------------------------------------------------------
160+
161+
extern __imulu
162+
extern _malloc
163+
extern _memset

0 commit comments

Comments
 (0)