Rev 887 | Rev 889 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
431 | serge | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
164 | serge | 7 | |
593 | mikedld | 8 | $Revision: 888 $ |
9 | |||
10 | |||
164 | serge | 11 | |
357 | serge | 12 | MEM_LIST_OFFSET equ 8 |
164 | serge | 13 | FREE_BLOCK equ 4 |
14 | USED_BLOCK equ 8 |
||
546 | diamond | 15 | DONT_FREE_BLOCK equ 10h |
164 | serge | 16 | |
17 | |||
18 | align 4 |
||
321 | diamond | 19 | proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
279 | serge | 20 | |
164 | serge | 21 | ret |
22 | endp |
||
23 | |||
24 | |||
25 | ;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
||
26 | |||
188 | serge | 27 | HEAP_TOP equ 0x5FC00000 |
28 | |||
164 | serge | 29 | align 4 |
188 | serge | 30 | proc init_heap |
164 | serge | 31 | |
465 | serge | 32 | mov ebx,[current_slot] |
33 | mov eax, [ebx+APPDATA.heap_top] |
||
172 | serge | 34 | test eax, eax |
35 | jz @F |
||
465 | serge | 36 | sub eax,[ebx+APPDATA.heap_base] |
172 | serge | 37 | sub eax, 4096 |
38 | ret |
||
39 | @@: |
||
465 | serge | 40 | mov esi, [ebx+APPDATA.mem_size] |
188 | serge | 41 | add esi, 4095 |
42 | and esi, not 4095 |
||
465 | serge | 43 | mov [ebx+APPDATA.mem_size], esi |
188 | serge | 44 | mov eax, HEAP_TOP |
465 | serge | 45 | mov [ebx+APPDATA.heap_base], esi |
46 | mov [ebx+APPDATA.heap_top], eax |
||
164 | serge | 47 | |
188 | serge | 48 | sub eax, esi |
49 | shr esi, 10 |
||
50 | mov ecx, eax |
||
164 | serge | 51 | sub eax, 4096 |
188 | serge | 52 | or ecx, FREE_BLOCK |
365 | serge | 53 | mov [page_tabs+esi], ecx |
164 | serge | 54 | ret |
55 | endp |
||
56 | |||
57 | align 4 |
||
58 | proc user_alloc stdcall, alloc_size:dword |
||
59 | |||
662 | serge | 60 | push ebx |
61 | push esi |
||
62 | push edi |
||
63 | |||
164 | serge | 64 | mov ecx, [alloc_size] |
65 | add ecx, (4095+4096) |
||
66 | and ecx, not 4095 |
||
67 | |||
465 | serge | 68 | mov ebx, [current_slot] |
69 | mov esi, dword [ebx+APPDATA.heap_base] ; heap_base |
||
70 | mov edi, dword [ebx+APPDATA.heap_top] ; heap_top |
||
164 | serge | 71 | l_0: |
72 | cmp esi, edi |
||
73 | jae m_exit |
||
74 | |||
75 | mov ebx, esi |
||
76 | shr ebx, 12 |
||
365 | serge | 77 | mov eax, [page_tabs+ebx*4] |
620 | diamond | 78 | test al, FREE_BLOCK |
164 | serge | 79 | jz test_used |
80 | and eax, 0xFFFFF000 |
||
81 | cmp eax, ecx ;alloc_size |
||
82 | jb m_next |
||
270 | diamond | 83 | jz @f |
164 | serge | 84 | |
620 | diamond | 85 | lea edx, [esi+ecx] |
86 | sub eax, ecx |
||
87 | or al, FREE_BLOCK |
||
164 | serge | 88 | shr edx, 12 |
365 | serge | 89 | mov [page_tabs+edx*4], eax |
294 | diamond | 90 | @@: |
164 | serge | 91 | or ecx, USED_BLOCK |
365 | serge | 92 | mov [page_tabs+ebx*4], ecx |
164 | serge | 93 | shr ecx, 12 |
620 | diamond | 94 | inc ebx |
164 | serge | 95 | dec ecx |
620 | diamond | 96 | jz .no |
164 | serge | 97 | @@: |
365 | serge | 98 | mov dword [page_tabs+ebx*4], 2 |
164 | serge | 99 | inc ebx |
100 | dec ecx |
||
101 | jnz @B |
||
620 | diamond | 102 | .no: |
164 | serge | 103 | |
465 | serge | 104 | mov edx, [current_slot] |
105 | mov ebx, [alloc_size] |
||
106 | add ebx, 0xFFF |
||
107 | and ebx, not 0xFFF |
||
108 | add ebx, [edx+APPDATA.mem_size] |
||
109 | call update_mem_size |
||
294 | diamond | 110 | |
620 | diamond | 111 | lea eax, [esi+4096] |
662 | serge | 112 | |
113 | pop edi |
||
114 | pop esi |
||
115 | pop ebx |
||
164 | serge | 116 | ret |
117 | test_used: |
||
620 | diamond | 118 | test al, USED_BLOCK |
164 | serge | 119 | jz m_exit |
120 | |||
121 | and eax, 0xFFFFF000 |
||
620 | diamond | 122 | m_next: |
164 | serge | 123 | add esi, eax |
124 | jmp l_0 |
||
125 | m_exit: |
||
126 | xor eax, eax |
||
662 | serge | 127 | pop edi |
128 | pop esi |
||
129 | pop ebx |
||
164 | serge | 130 | ret |
131 | endp |
||
132 | |||
133 | align 4 |
||
134 | proc user_free stdcall, base:dword |
||
135 | |||
662 | serge | 136 | push esi |
137 | |||
164 | serge | 138 | mov esi, [base] |
139 | test esi, esi |
||
140 | jz .exit |
||
141 | |||
662 | serge | 142 | push ebx |
143 | |||
294 | diamond | 144 | xor ebx, ebx |
164 | serge | 145 | shr esi, 12 |
620 | diamond | 146 | mov eax, [page_tabs+(esi-1)*4] |
546 | diamond | 147 | test al, USED_BLOCK |
620 | diamond | 148 | jz .cantfree |
546 | diamond | 149 | test al, DONT_FREE_BLOCK |
150 | jnz .cantfree |
||
164 | serge | 151 | |
888 | serge | 152 | push edi |
153 | |||
164 | serge | 154 | and eax, not 4095 |
888 | serge | 155 | mov edi, eax |
620 | diamond | 156 | or al, FREE_BLOCK |
157 | mov [page_tabs+(esi-1)*4], eax |
||
888 | serge | 158 | sub edi, 4096 |
159 | mov ebx, edi |
||
160 | shr edi, 12 |
||
620 | diamond | 161 | jz .released |
164 | serge | 162 | .release: |
888 | serge | 163 | xor ecx, ecx |
164 | xchg ecx, [page_tabs+esi*4] |
||
165 | test cl, 1 |
||
188 | serge | 166 | jz @F |
888 | serge | 167 | |
168 | call @core_free@4 |
||
448 | diamond | 169 | mov eax, esi |
170 | shl eax, 12 |
||
171 | invlpg [eax] |
||
188 | serge | 172 | @@: |
164 | serge | 173 | inc esi |
888 | serge | 174 | dec edi |
164 | serge | 175 | jnz .release |
620 | diamond | 176 | .released: |
465 | serge | 177 | mov edx, [current_slot] |
178 | mov esi, dword [edx+APPDATA.heap_base] |
||
179 | mov edi, dword [edx+APPDATA.heap_top] |
||
180 | sub ebx, [edx+APPDATA.mem_size] |
||
294 | diamond | 181 | neg ebx |
182 | call update_mem_size |
||
448 | diamond | 183 | call user_normalize |
662 | serge | 184 | pop edi |
185 | pop ebx |
||
186 | pop esi |
||
448 | diamond | 187 | ret |
188 | .exit: |
||
189 | xor eax, eax |
||
190 | inc eax |
||
662 | serge | 191 | pop esi |
448 | diamond | 192 | ret |
546 | diamond | 193 | .cantfree: |
194 | xor eax, eax |
||
662 | serge | 195 | pop ebx |
196 | pop esi |
||
546 | diamond | 197 | ret |
448 | diamond | 198 | endp |
199 | |||
200 | user_normalize: |
||
201 | ; in: esi=heap_base, edi=heap_top |
||
202 | ; out: eax=0 <=> OK |
||
203 | ; destroys: ebx,edx,esi,edi |
||
164 | serge | 204 | shr esi, 12 |
205 | shr edi, 12 |
||
206 | @@: |
||
365 | serge | 207 | mov eax, [page_tabs+esi*4] |
620 | diamond | 208 | test al, USED_BLOCK |
164 | serge | 209 | jz .test_free |
210 | shr eax, 12 |
||
211 | add esi, eax |
||
212 | jmp @B |
||
213 | .test_free: |
||
620 | diamond | 214 | test al, FREE_BLOCK |
164 | serge | 215 | jz .err |
216 | mov edx, eax |
||
217 | shr edx, 12 |
||
218 | add edx, esi |
||
219 | cmp edx, edi |
||
220 | jae .exit |
||
221 | |||
365 | serge | 222 | mov ebx, [page_tabs+edx*4] |
620 | diamond | 223 | test bl, USED_BLOCK |
164 | serge | 224 | jz .next_free |
225 | |||
226 | shr ebx, 12 |
||
227 | add edx, ebx |
||
228 | mov esi, edx |
||
229 | jmp @B |
||
230 | .next_free: |
||
620 | diamond | 231 | test bl, FREE_BLOCK |
164 | serge | 232 | jz .err |
365 | serge | 233 | and dword [page_tabs+edx*4], 0 |
164 | serge | 234 | add eax, ebx |
235 | and eax, not 4095 |
||
236 | or eax, FREE_BLOCK |
||
365 | serge | 237 | mov [page_tabs+esi*4], eax |
164 | serge | 238 | jmp @B |
239 | .exit: |
||
240 | xor eax, eax |
||
241 | inc eax |
||
242 | ret |
||
243 | .err: |
||
244 | xor eax, eax |
||
245 | ret |
||
246 | |||
448 | diamond | 247 | user_realloc: |
248 | ; in: eax = pointer, ebx = new size |
||
249 | ; out: eax = new pointer or NULL |
||
250 | test eax, eax |
||
251 | jnz @f |
||
252 | ; realloc(NULL,sz) - same as malloc(sz) |
||
253 | push ebx |
||
254 | call user_alloc |
||
255 | ret |
||
256 | @@: |
||
257 | push ecx edx |
||
465 | serge | 258 | lea ecx, [eax - 0x1000] |
448 | diamond | 259 | shr ecx, 12 |
260 | mov edx, [page_tabs+ecx*4] |
||
620 | diamond | 261 | test dl, USED_BLOCK |
448 | diamond | 262 | jnz @f |
263 | ; attempt to realloc invalid pointer |
||
264 | .ret0: |
||
265 | pop edx ecx |
||
266 | xor eax, eax |
||
267 | ret |
||
268 | @@: |
||
620 | diamond | 269 | test dl, DONT_FREE_BLOCK |
546 | diamond | 270 | jnz .ret0 |
448 | diamond | 271 | add ebx, 0x1FFF |
272 | shr edx, 12 |
||
273 | shr ebx, 12 |
||
274 | ; edx = allocated size, ebx = new size |
||
275 | add edx, ecx |
||
276 | add ebx, ecx |
||
277 | cmp edx, ebx |
||
278 | jb .realloc_add |
||
279 | ; release part of allocated memory |
||
888 | serge | 280 | |
281 | push ecx |
||
448 | diamond | 282 | .loop: |
283 | cmp edx, ebx |
||
284 | jz .release_done |
||
285 | dec edx |
||
888 | serge | 286 | xor ecx, ecx |
287 | xchg ecx, [page_tabs+edx*4] |
||
448 | diamond | 288 | test al, 1 |
289 | jz .loop |
||
888 | serge | 290 | |
291 | push edx |
||
292 | call @core_free@4 |
||
293 | pop edx |
||
448 | diamond | 294 | mov eax, edx |
295 | shl eax, 12 |
||
296 | invlpg [eax] |
||
297 | jmp .loop |
||
298 | .release_done: |
||
888 | serge | 299 | |
300 | pop ecx |
||
301 | |||
448 | diamond | 302 | sub ebx, ecx |
303 | cmp ebx, 1 |
||
304 | jnz .nofreeall |
||
305 | mov eax, [page_tabs+ecx*4] |
||
306 | and eax, not 0xFFF |
||
465 | serge | 307 | mov edx, [current_slot] |
308 | mov ebx, [APPDATA.mem_size+edx] |
||
448 | diamond | 309 | sub ebx, eax |
310 | add ebx, 0x1000 |
||
311 | or al, FREE_BLOCK |
||
312 | mov [page_tabs+ecx*4], eax |
||
313 | push esi edi |
||
465 | serge | 314 | mov esi, [APPDATA.heap_base+edx] |
315 | mov edi, [APPDATA.heap_top+edx] |
||
448 | diamond | 316 | call update_mem_size |
317 | call user_normalize |
||
318 | pop edi esi |
||
319 | jmp .ret0 ; all freed |
||
320 | .nofreeall: |
||
321 | sub edx, ecx |
||
322 | shl ebx, 12 |
||
323 | or ebx, USED_BLOCK |
||
324 | xchg [page_tabs+ecx*4], ebx |
||
325 | shr ebx, 12 |
||
326 | sub ebx, edx |
||
327 | push ebx ecx edx |
||
465 | serge | 328 | mov edx, [current_slot] |
448 | diamond | 329 | shl ebx, 12 |
465 | serge | 330 | sub ebx, [APPDATA.mem_size+edx] |
448 | diamond | 331 | neg ebx |
332 | call update_mem_size |
||
333 | pop edx ecx ebx |
||
465 | serge | 334 | lea eax, [ecx+1] |
448 | diamond | 335 | shl eax, 12 |
336 | push eax |
||
823 | diamond | 337 | add ecx, edx |
338 | lea edx, [ecx+ebx] |
||
448 | diamond | 339 | shl ebx, 12 |
340 | jz .ret |
||
341 | push esi |
||
465 | serge | 342 | mov esi, [current_slot] |
343 | mov esi, [APPDATA.heap_top+esi] |
||
448 | diamond | 344 | shr esi, 12 |
345 | @@: |
||
346 | cmp edx, esi |
||
347 | jae .merge_done |
||
348 | mov eax, [page_tabs+edx*4] |
||
349 | test al, USED_BLOCK |
||
823 | diamond | 350 | jnz .merge_done |
448 | diamond | 351 | and dword [page_tabs+edx*4], 0 |
823 | diamond | 352 | shr eax, 12 |
353 | add edx, eax |
||
354 | shl eax, 12 |
||
448 | diamond | 355 | add ebx, eax |
356 | jmp @b |
||
357 | .merge_done: |
||
358 | pop esi |
||
359 | or ebx, FREE_BLOCK |
||
360 | mov [page_tabs+ecx*4], ebx |
||
361 | .ret: |
||
362 | pop eax edx ecx |
||
363 | ret |
||
364 | .realloc_add: |
||
365 | ; get some additional memory |
||
465 | serge | 366 | mov eax, [current_slot] |
367 | mov eax, [APPDATA.heap_top+eax] |
||
448 | diamond | 368 | shr eax, 12 |
369 | cmp edx, eax |
||
370 | jae .cant_inplace |
||
371 | mov eax, [page_tabs+edx*4] |
||
620 | diamond | 372 | test al, FREE_BLOCK |
373 | jz .cant_inplace |
||
448 | diamond | 374 | shr eax, 12 |
375 | add eax, edx |
||
620 | diamond | 376 | sub eax, ebx |
448 | diamond | 377 | jb .cant_inplace |
378 | jz @f |
||
379 | shl eax, 12 |
||
380 | or al, FREE_BLOCK |
||
381 | mov [page_tabs+ebx*4], eax |
||
382 | @@: |
||
383 | mov eax, ebx |
||
384 | sub eax, ecx |
||
385 | shl eax, 12 |
||
386 | or al, USED_BLOCK |
||
387 | mov [page_tabs+ecx*4], eax |
||
465 | serge | 388 | lea eax, [ecx+1] |
448 | diamond | 389 | shl eax, 12 |
390 | push eax |
||
391 | push edi |
||
392 | lea edi, [page_tabs+edx*4] |
||
393 | mov eax, 2 |
||
394 | sub ebx, edx |
||
395 | mov ecx, ebx |
||
396 | cld |
||
397 | rep stosd |
||
398 | pop edi |
||
465 | serge | 399 | mov edx, [current_slot] |
448 | diamond | 400 | shl ebx, 12 |
465 | serge | 401 | add ebx, [APPDATA.mem_size+edx] |
448 | diamond | 402 | call update_mem_size |
403 | pop eax edx ecx |
||
404 | ret |
||
405 | .cant_inplace: |
||
406 | push esi edi |
||
465 | serge | 407 | mov eax, [current_slot] |
408 | mov esi, [APPDATA.heap_base+eax] |
||
409 | mov edi, [APPDATA.heap_top+eax] |
||
448 | diamond | 410 | shr esi, 12 |
411 | shr edi, 12 |
||
412 | sub ebx, ecx |
||
413 | .find_place: |
||
414 | cmp esi, edi |
||
415 | jae .place_not_found |
||
416 | mov eax, [page_tabs+esi*4] |
||
417 | test al, FREE_BLOCK |
||
418 | jz .next_place |
||
419 | shr eax, 12 |
||
420 | cmp eax, ebx |
||
421 | jae .place_found |
||
422 | add esi, eax |
||
423 | jmp .find_place |
||
424 | .next_place: |
||
425 | shr eax, 12 |
||
426 | add esi, eax |
||
427 | jmp .find_place |
||
428 | .place_not_found: |
||
429 | pop edi esi |
||
430 | jmp .ret0 |
||
431 | .place_found: |
||
432 | sub eax, ebx |
||
433 | jz @f |
||
434 | push esi |
||
620 | diamond | 435 | add esi, ebx |
448 | diamond | 436 | shl eax, 12 |
437 | or al, FREE_BLOCK |
||
438 | mov [page_tabs+esi*4], eax |
||
439 | pop esi |
||
440 | @@: |
||
441 | mov eax, ebx |
||
442 | shl eax, 12 |
||
443 | or al, USED_BLOCK |
||
444 | mov [page_tabs+esi*4], eax |
||
445 | inc esi |
||
446 | mov eax, esi |
||
447 | shl eax, 12 |
||
448 | push eax |
||
449 | mov eax, [page_tabs+ecx*4] |
||
450 | and eax, not 0xFFF |
||
451 | or al, FREE_BLOCK |
||
452 | sub edx, ecx |
||
453 | mov [page_tabs+ecx*4], eax |
||
454 | inc ecx |
||
620 | diamond | 455 | dec ebx |
456 | dec edx |
||
457 | jz .no |
||
448 | diamond | 458 | @@: |
459 | xor eax, eax |
||
460 | xchg eax, [page_tabs+ecx*4] |
||
461 | mov [page_tabs+esi*4], eax |
||
462 | mov eax, ecx |
||
463 | shl eax, 12 |
||
464 | invlpg [eax] |
||
620 | diamond | 465 | inc esi |
448 | diamond | 466 | inc ecx |
467 | dec ebx |
||
468 | dec edx |
||
469 | jnz @b |
||
620 | diamond | 470 | .no: |
448 | diamond | 471 | push ebx |
465 | serge | 472 | mov edx, [current_slot] |
448 | diamond | 473 | shl ebx, 12 |
465 | serge | 474 | add ebx, [APPDATA.mem_size+edx] |
448 | diamond | 475 | call update_mem_size |
476 | pop ebx |
||
477 | @@: |
||
478 | mov dword [page_tabs+esi*4], 2 |
||
479 | inc esi |
||
480 | dec ebx |
||
481 | jnz @b |
||
482 | pop eax edi esi edx ecx |
||
483 | ret |
||
484 | |||
278 | serge | 485 | if 0 |
164 | serge | 486 | align 4 |
487 | proc alloc_dll |
||
488 | pushf |
||
489 | cli |
||
490 | bsf eax, [dll_map] |
||
491 | jnz .find |
||
492 | popf |
||
493 | xor eax, eax |
||
494 | ret |
||
495 | .find: |
||
496 | btr [dll_map], eax |
||
497 | popf |
||
498 | shl eax, 5 |
||
499 | add eax, dll_tab |
||
500 | ret |
||
501 | endp |
||
502 | |||
503 | align 4 |
||
504 | proc alloc_service |
||
505 | pushf |
||
506 | cli |
||
507 | bsf eax, [srv_map] |
||
508 | jnz .find |
||
509 | popf |
||
510 | xor eax, eax |
||
511 | ret |
||
214 | serge | 512 | .find: |
513 | btr [srv_map], eax |
||
164 | serge | 514 | popf |
214 | serge | 515 | shl eax,0x02 |
516 | lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 |
||
164 | serge | 517 | ret |
518 | endp |
||
278 | serge | 519 | |
520 | end if=> |