Subversion Repositories Kolibri OS

Rev

Rev 3187 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2540 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
2540 hidnplayr 8
$Revision $
593 mikedld 9
 
10
 
276 serge 11
; Small heap based on malloc/free/realloc written by Doug Lea
12
; Version 2.8.3 Thu Sep 22 11:16:15 2005  Doug Lea  (dl at gee)
13
; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c
14
; License http://creativecommons.org/licenses/publicdomain.
15
 
16
 
17
; eax= size
18
 
19
; temp
20
;  esi= nb
21
;  ebx= idx
22
;
2382 hidnplayr 23
align 4
276 serge 24
malloc:
2382 hidnplayr 25
        push    esi
276 serge 26
 
27
; nb = ((size+7)&~7)+8;
28
 
2382 hidnplayr 29
        mov     esi, eax   ;size
30
        add     esi, 7
31
        and     esi, -8
32
        add     esi, 8
276 serge 33
 
2382 hidnplayr 34
        mov     ecx, mst.mutex
35
        call    mutex_lock
276 serge 36
 
2382 hidnplayr 37
        cmp     esi, 256
38
        jae     .large
276 serge 39
 
2382 hidnplayr 40
        mov     ecx, esi
41
        shr     ecx, 3
42
        or      eax, -1
43
        shl     eax, cl
44
        and     eax, [mst.smallmap]
45
        jz      .small
276 serge 46
 
2382 hidnplayr 47
        push    ebp
48
        push    edi
276 serge 49
 
2382 hidnplayr 50
        bsf     eax, eax
51
        mov     ebx, eax
276 serge 52
 
53
; psize= idx<<3;
54
; B = &ms.smallbins[idx];
55
; p = B->fd;
56
; F = p->fd;
57
; rsize= psize-nb;
58
 
2382 hidnplayr 59
        lea     ebp, [eax*8]              ;ebp= psize
60
        shl     eax, 4
61
        lea     edi, [mst.smallbins+eax]  ;edi= B
62
        mov     edx, [edi+8]              ;edx= p
63
        mov     eax, [edx+8]              ;eax= F
64
        mov     ecx, ebp
65
        sub     ecx, esi                  ;ecx= rsize
276 serge 66
 
67
; if (B == F)
2382 hidnplayr 68
        cmp     edi, eax
69
        jne     @F
276 serge 70
 
2382 hidnplayr 71
        btr     [mst.smallmap], ebx
276 serge 72
@@:
73
 
74
; B->fd = F;
75
; F->bk = B;
76
; if(rsize<16)
77
 
2382 hidnplayr 78
        cmp     ecx, 16
79
        mov     [edi+8], eax
80
        mov     [eax+12], edi
81
        jae     .split
276 serge 82
 
83
; p->head = psize|PINUSE_BIT|CINUSE_BIT;
84
; (p + psize)->head |= PINUSE_BIT;
85
 
2382 hidnplayr 86
        lea     eax, [edx+8]
87
        or      dword [edx+ebp+4], 1
276 serge 88
 
2382 hidnplayr 89
        or      ebp, 3
90
        mov     [edx+4], ebp
276 serge 91
 
2382 hidnplayr 92
        pop     edi
93
        pop     ebp
276 serge 94
.done:
2382 hidnplayr 95
        mov     esi, eax
96
        mov     ecx, mst.mutex
97
        call    mutex_unlock
98
        mov     eax, esi
99
        pop     esi
100
        ret
101
 
276 serge 102
.split:
2382 hidnplayr 103
        lea     ebx, [edx+8]              ;ebx=mem
276 serge 104
 
105
; r = chunk_plus_offset(p, nb);
106
; p->head = nb|PINUSE_BIT|CINUSE_BIT;
107
; r->head = rsize|PINUSE_BIT;
108
 
2382 hidnplayr 109
        lea     eax, [edx+esi]            ;eax= r
110
        or      esi, 3
111
        mov     [edx+4], esi
276 serge 112
 
2382 hidnplayr 113
        mov     edx, ecx
114
        or      edx, 1
115
        mov     [eax+4], edx
276 serge 116
 
117
; (r + rsize)->prev_foot = rsize;
118
 
2382 hidnplayr 119
        mov     [eax+ecx], ecx
276 serge 120
 
121
; I  = rsize>>3;
122
 
2382 hidnplayr 123
        shr     ecx, 3
276 serge 124
 
125
;      ms.smallmap |=  1<< I;
2382 hidnplayr 126
        bts     [mst.smallmap], ecx
276 serge 127
 
128
; B = &ms.smallbins[I];
129
 
2382 hidnplayr 130
        shl     ecx, 4
131
        pop     edi
132
        pop     ebp
133
        add     ecx, mst.smallbins        ;ecx= B
276 serge 134
 
2382 hidnplayr 135
        mov     edx, [ecx+8]              ; F = B->fd;
136
        mov     [ecx+8], eax              ; B->fd = r;
137
        mov     [edx+12], eax             ; F->bk = r;
138
        mov     [eax+8], edx              ; r->fd = F;
139
        mov     [eax+12], ecx             ; r->bk = B;
140
 
141
        mov     eax, ebx
142
        jmp     .done
143
 
276 serge 144
.small:
145
 
146
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
1210 Lrz 147
;;;;;;;;;;; start a change 
2382 hidnplayr 148
        mov     eax, [mst.treemap]
149
        test    eax, eax
1210 Lrz 150
;;;;;;;;;;; end the change 
151
;           cmp [mst.treemap], 0
2382 hidnplayr 152
        jz      .from_top
153
        mov     eax, esi
154
        call    malloc_small
155
        test    eax, eax
156
        jz      .from_top
157
        jmp     .done
158
 
276 serge 159
.large:
160
 
161
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
162
 
2382 hidnplayr 163
        cmp     [mst.treemap], 0
164
        je      .from_top
276 serge 165
 
2382 hidnplayr 166
        call    malloc_large  ;esi= nb
167
        test    eax, eax
168
        jne     .done
276 serge 169
.from_top:
170
 
171
; if (nb < ms.topsize)
172
 
2382 hidnplayr 173
        mov     eax, [mst.topsize]
174
        cmp     esi, eax
175
        jae     .fail
276 serge 176
 
177
; rsize = ms.topsize -= nb;
178
; p = ms.top;
179
 
2382 hidnplayr 180
        mov     ecx, [mst.top]
181
        sub     eax, esi
182
        mov     [mst.topsize], eax
276 serge 183
 
184
; r = ms.top = chunk_plus_offset(p, nb);
185
; r->head = rsize | PINUSE_BIT;
186
; p->head = nb |PINUSE_BIT|CINUSE_BIT;
187
 
2382 hidnplayr 188
        lea     edx, [ecx+esi]
189
        or      eax, 1
190
        mov     [mst.top], edx
191
        or      esi, 3
192
        mov     [edx+4], eax
193
        mov     [ecx+4], esi
194
        lea     eax, [ecx+8]
195
        jmp     .done
196
 
276 serge 197
.fail:
2382 hidnplayr 198
        xor     eax, eax
199
        jmp     .done
276 serge 200
 
201
; param
202
;  eax= mem
2382 hidnplayr 203
align 4
276 serge 204
free:
2382 hidnplayr 205
        test    eax, eax
206
        jz      .exit
276 serge 207
 
2382 hidnplayr 208
        push    edi
209
        mov     edi, eax
210
        add     edi, -8
211
 
276 serge 212
; if(p->head & CINUSE_BIT)
213
 
2382 hidnplayr 214
        test    byte [edi+4], 2
215
        je      .fail
276 serge 216
 
2382 hidnplayr 217
        mov     ecx, mst.mutex
218
        call    mutex_lock
276 serge 219
 
220
; psize = p->head & (~3);
221
 
2382 hidnplayr 222
        mov     eax, [edi+4]
223
        push    esi
224
        mov     esi, eax
225
        and     esi, -4
276 serge 226
 
227
; next = chunk_plus_offset(p, psize);
228
; if(!(p->head & PINUSE_BIT))
229
 
2382 hidnplayr 230
        test    al, 1
231
        lea     ebx, [esi+edi]
232
        jne     .next
276 serge 233
 
234
; prevsize = p->prev_foot;
235
; prev=p - prevsize;
236
; psize += prevsize;
237
; p = prev;
238
 
2382 hidnplayr 239
        mov     ecx, [edi] ;ecx= prevsize
240
        add     esi, ecx             ;esi= psize
241
        sub     edi, ecx             ;edi= p
276 serge 242
 
243
; if (prevsize < 256)
244
 
2382 hidnplayr 245
        cmp     ecx, 256
246
        jae     .unlink_large
276 serge 247
 
2382 hidnplayr 248
        mov     eax, [edi+8]         ;F = p->fd;
249
        mov     edx, [edi+12]        ;B = p->bk;
276 serge 250
 
251
; if (F == B)
252
; ms.smallmap &=  ~(1<< I);
2382 hidnplayr 253
        shr     ecx, 3
254
        cmp     eax, edx
255
        jne     @F
256
        btr     [mst.smallmap], ecx
276 serge 257
@@:
2382 hidnplayr 258
        mov     [eax+12], edx          ;F->bk = B;
259
        mov     [edx+8], eax           ;B->fd = F
260
        jmp     .next
276 serge 261
.unlink_large:
2382 hidnplayr 262
        mov     edx, edi
263
        call    unlink_large_chunk
276 serge 264
.next:
265
 
266
; if(next->head & PINUSE_BIT)
267
 
2382 hidnplayr 268
        mov     eax, [ebx+4]
269
        test    al, 1
270
        jz      .fail2
276 serge 271
 
272
; if (! (next->head & CINUSE_BIT))
273
 
2382 hidnplayr 274
        test    al, 2
275
        jnz     .fix_next
276 serge 276
 
277
; if (next == ms.top)
278
 
2382 hidnplayr 279
        cmp     ebx, [mst.top]
280
        jne     @F
276 serge 281
 
282
; tsize = ms.topsize += psize;
283
 
2382 hidnplayr 284
        mov     eax, [mst.topsize]
285
        add     eax, esi
286
        mov     [mst.topsize], eax
276 serge 287
 
288
; ms.top = p;
289
; p->head = tsize | PINUSE_BIT;
290
 
2382 hidnplayr 291
        or      eax, 1
292
        mov     [mst.top], edi
293
        mov     [edi+4], eax
276 serge 294
.fail2:
2382 hidnplayr 295
        mov     esi, eax
296
        mov     ecx, mst.mutex
297
        call    mutex_unlock
298
        mov     eax, esi
299
        pop     esi
276 serge 300
.fail:
2382 hidnplayr 301
        pop     edi
302
.exit:
303
        ret
304
 
276 serge 305
@@:
306
 
307
; nsize = next->head & ~INUSE_BITS;
308
 
2382 hidnplayr 309
        and     eax, -4
310
        add     esi, eax               ;psize += nsize;
276 serge 311
 
312
; if (nsize < 256)
313
 
2382 hidnplayr 314
        cmp     eax, 256
315
        jae     .unl_large
276 serge 316
 
2382 hidnplayr 317
        mov     edx, [ebx+8]           ;F = next->fd
318
        mov     ebx, [ebx+12]          ;B = next->bk
276 serge 319
 
320
; if (F == B)
321
 
2382 hidnplayr 322
        cmp     edx, ebx
323
        jne     @F
324
        mov     ecx, eax
325
        shr     ecx, 3
326
        btr     [mst.smallmap], ecx
276 serge 327
@@:
2382 hidnplayr 328
        mov     [edx+12], ebx          ;F->bk = B
276 serge 329
 
330
; p->head = psize|PINUSE_BIT;
331
 
2382 hidnplayr 332
        mov     ecx, esi
333
        mov     [ebx+8], edx
334
        or      ecx, 1
335
        mov     [edi+4], ecx
276 serge 336
 
337
; (p+psize)->prev_foot = psize;
338
 
2382 hidnplayr 339
        mov     [esi+edi], esi
276 serge 340
 
3359 hidnplayr 341
; insert_chunk(p,psize);
276 serge 342
 
3359 hidnplayr 343
        mov     eax, esi
344
        mov     ecx, edi
345
        call    insert_chunk
346
        jmp     .fail2
347
.unl_large:
348
 
349
; unlink_large_chunk((tchunkptr)next);
350
 
2382 hidnplayr 351
        mov     edx, ebx
352
        call    unlink_large_chunk
276 serge 353
; p->head = psize|PINUSE_BIT;
354
 
2382 hidnplayr 355
        mov     ecx, esi
356
        or      ecx, 1
357
        mov     [edi+4], ecx
276 serge 358
 
359
; (p+psize)->prev_foot = psize;
360
 
2382 hidnplayr 361
        mov     [esi+edi], esi
276 serge 362
 
3359 hidnplayr 363
; insert_chunk(p,psize);
364
 
365
        mov     eax, esi
366
        mov     ecx, edi
367
        call    insert_chunk
368
        jmp     .fail2
369
.fix_next:
370
 
371
; (p+psize)->prev_foot = psize;
276 serge 372
; next->head &= ~PINUSE_BIT;
373
; p->head = psize|PINUSE_BIT;
374
 
2382 hidnplayr 375
        and     eax, -2
376
        mov     edx, esi
377
        mov     [ebx+4], eax
378
        or      edx, 1
379
        mov     [edi+4], edx
276 serge 380
 
381
; (p+psize)->prev_foot = psize;
382
 
2382 hidnplayr 383
        mov     [esi+edi], esi
3359 hidnplayr 384
; insert_chunk(p,psize);
385
 
386
        mov     eax, esi
387
        mov     ecx, edi
388
        call    insert_chunk
389
        jmp     .fail2
390
 
391
; param
392
;  ecx = chunk
276 serge 393
;  eax = size
394
 
395
insert_chunk:
396
 
2382 hidnplayr 397
        cmp     eax, 256
398
        push    esi
399
        mov     esi, ecx
400
        jae     .large
276 serge 401
 
402
; I  = S>>3;
403
; ms.smallmap |=  1<< I;
404
 
2382 hidnplayr 405
        shr     eax, 3
406
        bts     [mst.smallmap], eax
276 serge 407
 
408
; B = &ms.smallbins[I];
409
 
2382 hidnplayr 410
        shl     eax, 4
411
        add     eax, mst.smallbins
412
        mov     edx, [eax+8]           ;F = B->fd
413
        mov     [eax+8], esi           ;B->fd = P
414
        mov     [edx+12], esi          ;F->bk = P
3359 hidnplayr 415
        mov     [esi+8], edx           ;P->fd = F
416
        mov     [esi+12], eax          ;P->bk = B
417
        pop     esi
418
        ret
419
.large:
420
        mov     ebx, eax
421
        call    insert_large_chunk
422
        pop     esi
423
        ret
424
 
425
 
276 serge 426
; param
427
;  esi= chunk
428
;  ebx= size
429
 
430
insert_large_chunk:
431
 
432
; I = compute_tree_index(S);
433
 
2382 hidnplayr 434
        mov     edx, ebx
435
        shr     edx, 8
436
        bsr     eax, edx
437
        lea     ecx, [eax+7]
438
        mov     edx, ebx
439
        shr     edx, cl
440
        and     edx, 1
441
        lea     ecx, [edx+eax*2]
276 serge 442
 
443
; X->index = I;
2382 hidnplayr 444
        mov     dword [esi+28], ecx
276 serge 445
 
446
; X->child[0] = X->child[1] = 0;
2382 hidnplayr 447
        and     dword [esi+20], 0
448
        and     dword [esi+16], 0
276 serge 449
 
450
; H = &ms.treebins[I];
451
 
2382 hidnplayr 452
        mov     eax, ecx
453
        lea     edx, [mst.treebins+eax*4]
276 serge 454
 
455
; if (!(ms.treemap & 1<
2382 hidnplayr 456
        bt      [mst.treemap], ecx
457
        jc      .tree
276 serge 458
 
459
; ms.treemap |= 1<
2382 hidnplayr 460
        bts     [mst.treemap], ecx
276 serge 461
; *H = X;
2382 hidnplayr 462
        mov     dword [edx], esi
463
        jmp     .done
276 serge 464
.tree:
465
 
466
; T = *H;
2382 hidnplayr 467
        mov     edx, [edx]
276 serge 468
 
469
; K = S << leftshift_for_tree_index(I);
2382 hidnplayr 470
        mov     eax, ecx
471
        shr     eax, 1
472
        sub     ecx, 31
473
        mov     edi, 37
474
        sub     edi, eax
475
        neg     ecx
476
        sbb     ecx, ecx
477
        and     ecx, edi
478
        mov     eax, ebx
479
        shl     eax, cl    ;eax= K
276 serge 480
 
2382 hidnplayr 481
        jmp     .loop
276 serge 482
.not_eq_size:
483
 
484
; C = &(T->child[(K >> 31) & 1]);
2382 hidnplayr 485
        mov     ecx, eax
486
        shr     ecx, 31
487
        lea     ecx, [edx+ecx*4+16]
276 serge 488
 
489
; K <<= 1;
490
; if (*C != 0)
2382 hidnplayr 491
        mov     edi, [ecx]
492
        add     eax, eax
493
        test    edi, edi
494
        jz      .insert_child
276 serge 495
 
496
; T = *C;
2382 hidnplayr 497
        mov     edx, edi
276 serge 498
.loop:
499
 
500
; for (;;)
501
; if ((T->head & ~INUSE_BITS) != S)
502
 
2382 hidnplayr 503
        mov     ecx, [edx+4]
504
        and     ecx, not 3
505
        cmp     ecx, ebx
506
        jne     .not_eq_size
276 serge 507
 
508
; F = T->fd;
2382 hidnplayr 509
        mov     eax, [edx+8]
276 serge 510
 
511
; T->fd = F->bk = X;
2382 hidnplayr 512
        mov     [eax+12], esi
513
        mov     [edx+8], esi
276 serge 514
 
515
; X->fd = F;
516
; X->bk = T;
517
; X->parent = 0;
518
 
2382 hidnplayr 519
        and     dword [esi+24], 0
520
        mov     [esi+8], eax
521
        mov     [esi+12], edx
522
        ret
276 serge 523
.insert_child:
524
 
525
; *C = X;
2382 hidnplayr 526
        mov     [ecx], esi
276 serge 527
.done:
528
 
529
; X->parent = T;
2382 hidnplayr 530
        mov     [esi+24], edx
276 serge 531
 
532
; X->fd = X->bk = X;
2382 hidnplayr 533
        mov     [esi+12], esi
534
        mov     [esi+8], esi
535
        ret
276 serge 536
 
537
 
538
; param
539
;  edx= chunk
540
 
541
unlink_large_chunk:
542
 
2382 hidnplayr 543
        mov     eax, [edx+12]
544
        cmp     eax, edx
545
        push    edi
546
        mov     edi, [edx+24]
547
        je      @F
276 serge 548
 
2382 hidnplayr 549
        mov     ecx, [edx+8]          ;F = X->fd
550
        mov     [ecx+12], eax         ;F->bk = R;
551
        mov     [eax+8], ecx          ;R->fd = F
552
        jmp     .parent
276 serge 553
@@:
2382 hidnplayr 554
        mov     eax, [edx+20]
555
        test    eax, eax
556
        push    esi
557
        lea     esi, [edx+20]
558
        jne     .loop
276 serge 559
 
2382 hidnplayr 560
        mov     eax, [edx+16]
561
        test    eax, eax
562
        lea     esi, [edx+16]
563
        je      .l2
276 serge 564
.loop:
2382 hidnplayr 565
        cmp     dword [eax+20], 0
566
        lea     ecx, [eax+20]
567
        jne     @F
276 serge 568
 
2382 hidnplayr 569
        cmp     dword [eax+16], 0
570
        lea     ecx, [eax+16]
571
        je      .l1
276 serge 572
@@:
2382 hidnplayr 573
        mov     eax, [ecx]
574
        mov     esi, ecx
575
        jmp     .loop
276 serge 576
.l1:
2382 hidnplayr 577
        mov     dword [esi], 0
276 serge 578
.l2:
2382 hidnplayr 579
        pop     esi
276 serge 580
.parent:
2382 hidnplayr 581
        test    edi, edi
582
        je      .done
276 serge 583
 
2382 hidnplayr 584
        mov     ecx, [edx+28]
585
        cmp     edx, [mst.treebins+ecx*4]
586
        lea     ecx, [mst.treebins+ecx*4]
587
        jne     .l3
276 serge 588
 
2382 hidnplayr 589
        test    eax, eax
590
        mov     [ecx], eax
591
        jne     .l5
276 serge 592
 
2382 hidnplayr 593
        mov     ecx, [edx+28]
594
        btr     [mst.treemap], ecx
595
        pop     edi
596
        ret
597
 
276 serge 598
.l3:
2382 hidnplayr 599
        cmp     [edi+16], edx
600
        jne     @F
276 serge 601
 
2382 hidnplayr 602
        mov     [edi+16], eax
603
        jmp     .l4
604
 
276 serge 605
@@:
2382 hidnplayr 606
        mov     [edi+20], eax
607
 
276 serge 608
.l4:
2382 hidnplayr 609
        test    eax, eax
610
        je      .done
611
 
276 serge 612
.l5:
2382 hidnplayr 613
        mov     [eax+24], edi
614
        mov     ecx, [edx+16]
615
        test    ecx, ecx
616
        je      .l6
276 serge 617
 
2382 hidnplayr 618
        mov     [eax+16], ecx
619
        mov     [ecx+24], eax
620
 
276 serge 621
.l6:
2382 hidnplayr 622
        mov     edx, [edx+20]
623
        test    edx, edx
624
        je      .done
276 serge 625
 
2382 hidnplayr 626
        mov     [eax+20], edx
627
        mov     [edx+24], eax
628
 
276 serge 629
.done:
2382 hidnplayr 630
        pop     edi
631
        ret
276 serge 632
 
633
; param
634
;  esi= nb
635
 
636
malloc_small:
2382 hidnplayr 637
        push    ebp
638
        mov     ebp, esi
276 serge 639
 
2382 hidnplayr 640
        push    edi
276 serge 641
 
2382 hidnplayr 642
        bsf     eax, [mst.treemap]
643
        mov     ecx, [mst.treebins+eax*4]
276 serge 644
 
645
; rsize = (t->head & ~INUSE_BITS) - nb;
646
 
2382 hidnplayr 647
        mov     edi, [ecx+4]
648
        and     edi, -4
649
        sub     edi, esi
650
 
276 serge 651
.loop:
2382 hidnplayr 652
        mov     ebx, ecx
653
 
276 serge 654
.loop_1:
655
 
656
; while ((t = leftmost_child(t)) != 0)
657
 
2382 hidnplayr 658
        mov     eax, [ecx+16]
659
        test    eax, eax
660
        jz      @F
661
        mov     ecx, eax
662
        jmp     .l1
663
 
276 serge 664
@@:
2382 hidnplayr 665
        mov     ecx, [ecx+20]
666
 
276 serge 667
.l1:
2382 hidnplayr 668
        test    ecx, ecx
669
        jz      .unlink
276 serge 670
 
671
; trem = (t->head & ~INUSE_BITS) - nb;
672
 
2382 hidnplayr 673
        mov     eax, [ecx+4]
674
        and     eax, -4
675
        sub     eax, ebp
276 serge 676
 
677
; if (trem < rsize)
678
 
2382 hidnplayr 679
        cmp     eax, edi
680
        jae     .loop_1
276 serge 681
 
682
; rsize = trem;
683
 
2382 hidnplayr 684
        mov     edi, eax
685
        jmp     .loop
276 serge 686
.unlink:
687
 
688
 
689
; r = chunk_plus_offset((mchunkptr)v, nb);
690
; unlink_large_chunk(v);
691
 
2382 hidnplayr 692
        mov     edx, ebx
693
        lea     esi, [ebx+ebp]
694
        call    unlink_large_chunk
276 serge 695
 
696
; if (rsize < 16)
697
 
2382 hidnplayr 698
        cmp     edi, 16
699
        jae     .split
276 serge 700
 
701
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
702
 
2382 hidnplayr 703
        lea     ecx, [edi+ebp]
276 serge 704
 
705
; (v+rsize + nb)->head |= PINUSE_BIT;
706
 
2382 hidnplayr 707
        add     edi, ebx
708
        lea     eax, [edi+ebp+4]
709
        pop     edi
710
        or      ecx, 3
711
        mov     [ebx+4], ecx
712
        or      dword [eax], 1
713
        pop     ebp
276 serge 714
 
2382 hidnplayr 715
        lea     eax, [ebx+8]
716
        ret
717
 
276 serge 718
.split:
719
 
720
; v->head = nb|PINUSE_BIT|CINUSE_BIT;
721
; r->head = rsize|PINUSE_BIT;
722
; (r+rsize)->prev_foot = rsize;
723
 
2382 hidnplayr 724
        or      ebp, 3
725
        mov     edx, edi
726
        or      edx, 1
276 serge 727
 
2382 hidnplayr 728
        cmp     edi, 256
729
        mov     [ebx+4], ebp
730
        mov     [esi+4], edx
731
        mov     [esi+edi], edi
732
        jae     .large
276 serge 733
 
2382 hidnplayr 734
        shr     edi, 3
735
        bts     [mst.smallmap], edi
276 serge 736
 
2382 hidnplayr 737
        mov     eax, edi
738
        shl     eax, 4
739
        add     eax, mst.smallbins
276 serge 740
 
2382 hidnplayr 741
        mov     edx, [eax+8]
742
        mov     [eax+8], esi
743
        mov     [edx+12], esi
744
        pop     edi
745
        mov     [esi+12], eax
746
        mov     [esi+8], edx
747
        pop     ebp
748
        lea     eax, [ebx+8]
749
        ret
750
 
276 serge 751
.large:
2382 hidnplayr 752
        lea     eax, [ebx+8]
753
        push    eax
754
        mov     ebx, edi
755
        call    insert_large_chunk
756
        pop     eax
757
        pop     edi
758
        pop     ebp
759
        ret
276 serge 760
 
761
 
762
; param
763
;  esi= nb
764
 
765
malloc_large:
766
.idx equ esp+4
767
.rst equ esp
768
 
2382 hidnplayr 769
        push    ebp
770
        push    esi
771
        push    edi
772
        sub     esp, 8
276 serge 773
; v = 0;
774
; rsize = -nb;
775
 
2382 hidnplayr 776
        mov     edi, esi
777
        mov     ebx, esi
778
        xor     ebp, ebp
779
        neg     edi
276 serge 780
 
781
; idx = compute_tree_index(nb);
782
 
2382 hidnplayr 783
        mov     edx, esi
784
        shr     edx, 8
785
        bsr     eax, edx
786
        lea     ecx, [eax+7]
787
        shr     esi, cl
788
        and     esi, 1
789
        lea     ecx, [esi+eax*2]
790
        mov     [.idx], ecx
276 serge 791
 
792
; if ((t = ms.treebins[idx]) != 0)
793
 
2382 hidnplayr 794
        mov     eax, [mst.treebins+ecx*4]
795
        test    eax, eax
796
        jz      .l3
276 serge 797
 
798
; sizebits = nb << leftshift_for_tree_index(idx);
799
 
2382 hidnplayr 800
        cmp     ecx, 31
801
        jne     @F
802
        xor     ecx, ecx
803
        jmp     .l1
804
 
276 serge 805
@@:
2382 hidnplayr 806
        mov     edx, ecx
807
        shr     edx, 1
808
        mov     ecx, 37
809
        sub     ecx, edx
810
 
276 serge 811
.l1:
2382 hidnplayr 812
        mov     edx, ebx
813
        shl     edx, cl
276 serge 814
 
815
; rst = 0;
2382 hidnplayr 816
        mov     [.rst], ebp
817
 
276 serge 818
.loop:
819
 
820
; trem = (t->head & ~INUSE_BITS) - nb;
821
 
2382 hidnplayr 822
        mov     ecx, [eax+4]
823
        and     ecx, -4
824
        sub     ecx, ebx
276 serge 825
 
826
; if (trem < rsize)
827
 
2382 hidnplayr 828
        cmp     ecx, edi
829
        jae     @F
276 serge 830
; v = t;
831
; if ((rsize = trem) == 0)
832
 
2382 hidnplayr 833
        test    ecx, ecx
834
        mov     ebp, eax
835
        mov     edi, ecx
836
        je      .l2
837
 
276 serge 838
@@:
839
 
840
; rt = t->child[1];
841
 
2382 hidnplayr 842
        mov     ecx, [eax+20]
276 serge 843
 
844
; t = t->child[(sizebits >> 31) & 1];
845
 
2382 hidnplayr 846
        mov     esi, edx
847
        shr     esi, 31
276 serge 848
 
849
; if (rt != 0 && rt != t)
850
 
2382 hidnplayr 851
        test    ecx, ecx
852
        mov     eax, [eax+esi*4+16]
853
        jz      @F
854
        cmp     ecx, eax
855
        jz      @F
276 serge 856
 
857
; rst = rt;
2382 hidnplayr 858
        mov     [.rst], ecx
859
 
276 serge 860
@@:
861
; if (t == 0)
862
 
2382 hidnplayr 863
        test    eax, eax
864
        jz      @F
276 serge 865
 
866
; sizebits <<= 1;
867
 
2382 hidnplayr 868
        add     edx, edx
869
        jmp     .loop
870
 
276 serge 871
@@:
872
; t = rst;
2382 hidnplayr 873
        mov     eax, [.rst]
874
 
276 serge 875
.l2:
876
; if (t == 0 && v == 0)
877
 
2382 hidnplayr 878
        test    eax, eax
879
        jne     .l4
880
        test    ebp, ebp
881
        jne     .l7
882
        mov     ecx, [.idx]
883
 
276 serge 884
.l3:
885
 
886
; leftbits = (-1<
887
; if (leftbits != 0)
888
 
2382 hidnplayr 889
        or      edx, -1
890
        shl     edx, cl
891
        and     edx, [mst.treemap]
892
        jz      @F
276 serge 893
 
2382 hidnplayr 894
        bsf     eax, edx
276 serge 895
; t = ms.treebins[i];
2382 hidnplayr 896
        mov     eax, [mst.treebins+eax*4]
897
 
276 serge 898
@@:
899
 
900
; while (t != 0)
2382 hidnplayr 901
        test    eax, eax
902
        jz      .l5
903
 
276 serge 904
.l4:
905
 
906
; trem = (t->head & ~INUSE_BITS) - nb;
907
 
2382 hidnplayr 908
        mov     ecx, [eax+4]
909
        and     ecx, -4
910
        sub     ecx, ebx
276 serge 911
 
912
; if (trem < rsize)
913
 
2382 hidnplayr 914
        cmp     ecx, edi
915
        jae     @F
276 serge 916
; rsize = trem;
917
 
2382 hidnplayr 918
        mov     edi, ecx
276 serge 919
; v = t;
2382 hidnplayr 920
        mov     ebp, eax
921
 
276 serge 922
@@:
923
 
924
; t = leftmost_child(t);
925
 
2382 hidnplayr 926
        mov     ecx, [eax+16]
927
        test    ecx, ecx
928
        je      @F
929
        mov     eax, ecx
930
        jmp     .l6
931
 
276 serge 932
@@:
2382 hidnplayr 933
        mov     eax, [eax+20]
934
 
276 serge 935
.l6:
936
 
937
; while (t != 0)
938
 
2382 hidnplayr 939
        test    eax, eax
940
        jne     .l4
941
 
276 serge 942
.l5:
943
 
944
; if (v != 0)
945
 
2382 hidnplayr 946
        test    ebp, ebp
947
        jz      .done
948
 
276 serge 949
.l7:
950
 
951
; r = chunk_plus_offset((mchunkptr)v, nb);
952
; unlink_large_chunk(v);
953
 
2382 hidnplayr 954
        mov     edx, ebp
955
        lea     esi, [ebx+ebp]
956
        call    unlink_large_chunk
276 serge 957
 
326 serge 958
; if (rsize < 16)
276 serge 959
 
2382 hidnplayr 960
        cmp     edi, 16
961
        jae     .large
276 serge 962
 
963
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
964
 
2382 hidnplayr 965
        lea     ecx, [edi+ebx]
276 serge 966
 
967
; (v+rsize + nb)->head |= PINUSE_BIT;
968
 
2382 hidnplayr 969
        add     edi, ebp
970
        lea     eax, [edi+ebx+4]
971
        or      ecx, 3
972
        mov     [ebp+4], ecx
973
        or      dword [eax], 1
974
        lea     eax, [ebp+8]
975
        add     esp, 8
976
        pop     edi
977
        pop     esi
978
        pop     ebp
979
        ret
980
 
276 serge 981
.large:
982
 
983
; v->head = nb|PINUSE_BIT|CINUSE_BIT;
984
; r->head = rsize|PINUSE_BIT;
985
 
2382 hidnplayr 986
        mov     edx, edi
987
        or      ebx, 3
988
        mov     [ebp+4], ebx
989
        or      edx, 1
990
        mov     [esi+4], edx
276 serge 991
 
992
; (r+rsize)->prev_foot = rsize;
993
; insert_large_chunk((tchunkptr)r, rsize);
994
 
2382 hidnplayr 995
        mov     [esi+edi], edi
996
        mov     eax, edi
997
        mov     ecx, esi
998
        call    insert_chunk
276 serge 999
 
2382 hidnplayr 1000
        lea     eax, [ebp+8]
1001
        add     esp, 8
1002
        pop     edi
1003
        pop     esi
1004
        pop     ebp
1005
        ret
1006
 
276 serge 1007
.done:
2382 hidnplayr 1008
        add     esp, 8
1009
        pop     edi
1010
        pop     esi
1011
        pop     ebp
1012
        xor     eax, eax
1013
        ret
276 serge 1014
 
1015
init_malloc:
1016
 
2382 hidnplayr 1017
        stdcall kernel_alloc, 0x40000
276 serge 1018
 
2382 hidnplayr 1019
        mov     [mst.top], eax
1020
        mov     [mst.topsize], 128*1024
1021
        mov     dword [eax+4], (128*1024) or 1
1022
        mov     eax, mst.smallbins
1023
 
276 serge 1024
@@:
2382 hidnplayr 1025
        mov     [eax+8], eax
1026
        mov     [eax+12], eax
1027
        add     eax, 16
1028
        cmp     eax, mst.smallbins+512
1029
        jb      @B
276 serge 1030
 
2382 hidnplayr 1031
        mov     ecx, mst.mutex
1032
        call    mutex_init
276 serge 1033
 
2382 hidnplayr 1034
        ret
1035