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