Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 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
 
593 mikedld 8
$Revision: 3232 $
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
;
2130 serge 23
align 4
276 serge 24
malloc:
2434 Serge 25
        push    esi
276 serge 26
 
27
; nb = ((size+7)&~7)+8;
28
 
2434 Serge 29
        mov     esi, eax   ;size
30
        add     esi, 7
31
        and     esi, -8
32
        add     esi, 8
276 serge 33
 
2434 Serge 34
        mov     ecx, mst.mutex
35
        call    mutex_lock
276 serge 36
 
2434 Serge 37
        cmp     esi, 256
38
        jae     .large
276 serge 39
 
2434 Serge 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
 
2434 Serge 47
        push    ebp
48
        push    edi
276 serge 49
 
2434 Serge 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
 
2434 Serge 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)
2434 Serge 68
        cmp     edi, eax
69
        jne     @F
276 serge 70
 
2434 Serge 71
        btr     [mst.smallmap], ebx
276 serge 72
@@:
73
 
74
; B->fd = F;
75
; F->bk = B;
76
; if(rsize<16)
77
 
2434 Serge 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
 
2434 Serge 86
        lea     eax, [edx+8]
87
        or      dword [edx+ebp+4], 1
276 serge 88
 
2434 Serge 89
        or      ebp, 3
90
        mov     [edx+4], ebp
276 serge 91
 
2434 Serge 92
        pop     edi
93
        pop     ebp
276 serge 94
.done:
2434 Serge 95
        mov     esi, eax
96
        mov     ecx, mst.mutex
97
        call    mutex_unlock
98
        mov     eax, esi
99
        pop     esi
100
        ret
2130 serge 101
 
276 serge 102
.split:
2434 Serge 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
 
2434 Serge 109
        lea     eax, [edx+esi]            ;eax= r
110
        or      esi, 3
111
        mov     [edx+4], esi
276 serge 112
 
2434 Serge 113
        mov     edx, ecx
114
        or      edx, 1
115
        mov     [eax+4], edx
276 serge 116
 
117
; (r + rsize)->prev_foot = rsize;
118
 
2434 Serge 119
        mov     [eax+ecx], ecx
276 serge 120
 
121
; I  = rsize>>3;
122
 
2434 Serge 123
        shr     ecx, 3
276 serge 124
 
125
;      ms.smallmap |=  1<< I;
2434 Serge 126
        bts     [mst.smallmap], ecx
276 serge 127
 
128
; B = &ms.smallbins[I];
129
 
2434 Serge 130
        shl     ecx, 4
131
        pop     edi
132
        pop     ebp
133
        add     ecx, mst.smallbins        ;ecx= B
276 serge 134
 
2434 Serge 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;
2130 serge 140
 
2434 Serge 141
        mov     eax, ebx
142
        jmp     .done
2130 serge 143
 
276 serge 144
.small:
145
 
146
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
1210 Lrz 147
;;;;;;;;;;; start a change 
2434 Serge 148
        mov     eax, [mst.treemap]
149
        test    eax, eax
1210 Lrz 150
;;;;;;;;;;; end the change 
151
;           cmp [mst.treemap], 0
2434 Serge 152
        jz      .from_top
153
        mov     eax, esi
154
        call    malloc_small
155
        test    eax, eax
156
        jz      .from_top
157
        jmp     .done
2130 serge 158
 
276 serge 159
.large:
160
 
161
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
162
 
2434 Serge 163
        cmp     [mst.treemap], 0
164
        je      .from_top
276 serge 165
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 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
2130 serge 196
 
276 serge 197
.fail:
2434 Serge 198
        xor     eax, eax
199
        jmp     .done
276 serge 200
 
201
; param
202
;  eax= mem
2130 serge 203
align 4
276 serge 204
free:
2434 Serge 205
        test    eax, eax
206
        jz      .exit
2259 Serge 207
 
2434 Serge 208
        push    edi
209
        mov     edi, eax
210
        add     edi, -8
276 serge 211
 
212
; if(p->head & CINUSE_BIT)
213
 
2434 Serge 214
        test    byte [edi+4], 2
215
        je      .fail
276 serge 216
 
2434 Serge 217
        mov     ecx, mst.mutex
218
        call    mutex_lock
276 serge 219
 
220
; psize = p->head & (~3);
221
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 245
        cmp     ecx, 256
246
        jae     .unlink_large
276 serge 247
 
2434 Serge 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);
2434 Serge 253
        shr     ecx, 3
254
        cmp     eax, edx
255
        jne     @F
256
        btr     [mst.smallmap], ecx
276 serge 257
@@:
2434 Serge 258
        mov     [eax+12], edx          ;F->bk = B;
259
        mov     [edx+8], eax           ;B->fd = F
260
        jmp     .next
276 serge 261
.unlink_large:
2434 Serge 262
        mov     edx, edi
263
        call    unlink_large_chunk
276 serge 264
.next:
265
 
266
; if(next->head & PINUSE_BIT)
267
 
2434 Serge 268
        mov     eax, [ebx+4]
269
        test    al, 1
270
        jz      .fail2
276 serge 271
 
272
; if (! (next->head & CINUSE_BIT))
273
 
2434 Serge 274
        test    al, 2
275
        jnz     .fix_next
276 serge 276
 
277
; if (next == ms.top)
278
 
2434 Serge 279
        cmp     ebx, [mst.top]
280
        jne     @F
276 serge 281
 
282
; tsize = ms.topsize += psize;
283
 
2434 Serge 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
 
2434 Serge 291
        or      eax, 1
292
        mov     [mst.top], edi
293
        mov     [edi+4], eax
276 serge 294
.fail2:
2434 Serge 295
        mov     esi, eax
296
        mov     ecx, mst.mutex
297
        call    mutex_unlock
298
        mov     eax, esi
299
        pop     esi
276 serge 300
.fail:
2434 Serge 301
        pop     edi
2259 Serge 302
.exit:
2434 Serge 303
        ret
2259 Serge 304
 
276 serge 305
@@:
306
 
307
; nsize = next->head & ~INUSE_BITS;
308
 
2434 Serge 309
        and     eax, -4
310
        add     esi, eax               ;psize += nsize;
276 serge 311
 
312
; if (nsize < 256)
313
 
2434 Serge 314
        cmp     eax, 256
315
        jae     .unl_large
276 serge 316
 
2434 Serge 317
        mov     edx, [ebx+8]           ;F = next->fd
318
        mov     ebx, [ebx+12]          ;B = next->bk
276 serge 319
 
320
; if (F == B)
321
 
2434 Serge 322
        cmp     edx, ebx
323
        jne     @F
324
        mov     ecx, eax
325
        shr     ecx, 3
326
        btr     [mst.smallmap], ecx
276 serge 327
@@:
2434 Serge 328
        mov     [edx+12], ebx          ;F->bk = B
276 serge 329
 
330
; p->head = psize|PINUSE_BIT;
331
 
2434 Serge 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
 
2434 Serge 339
        mov     [esi+edi], esi
276 serge 340
 
341
; insert_chunk(p,psize);
342
 
2434 Serge 343
        mov     eax, esi
344
        mov     ecx, edi
3232 Serge 345
        call    insert_chunk
346
        jmp     .fail2
276 serge 347
.unl_large:
348
 
349
; unlink_large_chunk((tchunkptr)next);
350
 
2434 Serge 351
        mov     edx, ebx
352
        call    unlink_large_chunk
276 serge 353
; p->head = psize|PINUSE_BIT;
354
 
2434 Serge 355
        mov     ecx, esi
356
        or      ecx, 1
357
        mov     [edi+4], ecx
276 serge 358
 
359
; (p+psize)->prev_foot = psize;
360
 
2434 Serge 361
        mov     [esi+edi], esi
276 serge 362
 
363
; insert_chunk(p,psize);
364
 
2434 Serge 365
        mov     eax, esi
366
        mov     ecx, edi
3232 Serge 367
        call    insert_chunk
368
        jmp     .fail2
276 serge 369
.fix_next:
370
 
371
; (p+psize)->prev_foot = psize;
372
; next->head &= ~PINUSE_BIT;
373
; p->head = psize|PINUSE_BIT;
374
 
2434 Serge 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
 
2434 Serge 383
        mov     [esi+edi], esi
276 serge 384
; insert_chunk(p,psize);
385
 
2434 Serge 386
        mov     eax, esi
387
        mov     ecx, edi
3232 Serge 388
        call    insert_chunk
389
        jmp     .fail2
276 serge 390
 
391
; param
392
;  ecx = chunk
393
;  eax = size
394
 
395
insert_chunk:
396
 
2434 Serge 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
 
2434 Serge 405
        shr     eax, 3
406
        bts     [mst.smallmap], eax
276 serge 407
 
408
; B = &ms.smallbins[I];
409
 
2434 Serge 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
415
        mov     [esi+8], edx           ;P->fd = F
416
        mov     [esi+12], eax          ;P->bk = B
417
        pop     esi
418
        ret
276 serge 419
.large:
2434 Serge 420
        mov     ebx, eax
421
        call    insert_large_chunk
422
        pop     esi
423
        ret
276 serge 424
 
425
 
426
; param
427
;  esi= chunk
428
;  ebx= size
429
 
430
insert_large_chunk:
431
 
432
; I = compute_tree_index(S);
433
 
2434 Serge 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;
2434 Serge 444
        mov     dword [esi+28], ecx
276 serge 445
 
446
; X->child[0] = X->child[1] = 0;
2434 Serge 447
        and     dword [esi+20], 0
448
        and     dword [esi+16], 0
276 serge 449
 
450
; H = &ms.treebins[I];
451
 
2434 Serge 452
        mov     eax, ecx
453
        lea     edx, [mst.treebins+eax*4]
276 serge 454
 
455
; if (!(ms.treemap & 1<
2434 Serge 456
        bt      [mst.treemap], ecx
457
        jc      .tree
276 serge 458
 
459
; ms.treemap |= 1<
2434 Serge 460
        bts     [mst.treemap], ecx
276 serge 461
; *H = X;
2434 Serge 462
        mov     dword [edx], esi
463
        jmp     .done
276 serge 464
.tree:
465
 
466
; T = *H;
2434 Serge 467
        mov     edx, [edx]
276 serge 468
 
469
; K = S << leftshift_for_tree_index(I);
2434 Serge 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
 
2434 Serge 481
        jmp     .loop
276 serge 482
.not_eq_size:
483
 
484
; C = &(T->child[(K >> 31) & 1]);
2434 Serge 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)
2434 Serge 491
        mov     edi, [ecx]
492
        add     eax, eax
493
        test    edi, edi
494
        jz      .insert_child
276 serge 495
 
496
; T = *C;
2434 Serge 497
        mov     edx, edi
276 serge 498
.loop:
499
 
500
; for (;;)
501
; if ((T->head & ~INUSE_BITS) != S)
502
 
2434 Serge 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;
2434 Serge 509
        mov     eax, [edx+8]
276 serge 510
 
511
; T->fd = F->bk = X;
2434 Serge 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
 
2434 Serge 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;
2434 Serge 526
        mov     [ecx], esi
276 serge 527
.done:
528
 
529
; X->parent = T;
2434 Serge 530
        mov     [esi+24], edx
276 serge 531
 
532
; X->fd = X->bk = X;
2434 Serge 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
 
2434 Serge 543
        mov     eax, [edx+12]
544
        cmp     eax, edx
545
        push    edi
546
        mov     edi, [edx+24]
547
        je      @F
276 serge 548
 
2434 Serge 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
@@:
2434 Serge 554
        mov     eax, [edx+20]
555
        test    eax, eax
556
        push    esi
557
        lea     esi, [edx+20]
558
        jne     .loop
276 serge 559
 
2434 Serge 560
        mov     eax, [edx+16]
561
        test    eax, eax
562
        lea     esi, [edx+16]
563
        je      .l2
276 serge 564
.loop:
2434 Serge 565
        cmp     dword [eax+20], 0
566
        lea     ecx, [eax+20]
567
        jne     @F
276 serge 568
 
2434 Serge 569
        cmp     dword [eax+16], 0
570
        lea     ecx, [eax+16]
571
        je      .l1
276 serge 572
@@:
2434 Serge 573
        mov     eax, [ecx]
574
        mov     esi, ecx
575
        jmp     .loop
276 serge 576
.l1:
2434 Serge 577
        mov     dword [esi], 0
276 serge 578
.l2:
2434 Serge 579
        pop     esi
276 serge 580
.parent:
2434 Serge 581
        test    edi, edi
582
        je      .done
276 serge 583
 
2434 Serge 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
 
2434 Serge 589
        test    eax, eax
590
        mov     [ecx], eax
591
        jne     .l5
276 serge 592
 
2434 Serge 593
        mov     ecx, [edx+28]
594
        btr     [mst.treemap], ecx
595
        pop     edi
596
        ret
2259 Serge 597
 
276 serge 598
.l3:
2434 Serge 599
        cmp     [edi+16], edx
600
        jne     @F
276 serge 601
 
2434 Serge 602
        mov     [edi+16], eax
603
        jmp     .l4
2259 Serge 604
 
276 serge 605
@@:
2434 Serge 606
        mov     [edi+20], eax
2259 Serge 607
 
276 serge 608
.l4:
2434 Serge 609
        test    eax, eax
610
        je      .done
2259 Serge 611
 
276 serge 612
.l5:
2434 Serge 613
        mov     [eax+24], edi
614
        mov     ecx, [edx+16]
615
        test    ecx, ecx
616
        je      .l6
276 serge 617
 
2434 Serge 618
        mov     [eax+16], ecx
619
        mov     [ecx+24], eax
2259 Serge 620
 
276 serge 621
.l6:
2434 Serge 622
        mov     edx, [edx+20]
623
        test    edx, edx
624
        je      .done
276 serge 625
 
2434 Serge 626
        mov     [eax+20], edx
627
        mov     [edx+24], eax
2259 Serge 628
 
276 serge 629
.done:
2434 Serge 630
        pop     edi
631
        ret
276 serge 632
 
633
; param
634
;  esi= nb
635
 
636
malloc_small:
2434 Serge 637
        push    ebp
638
        mov     ebp, esi
276 serge 639
 
2434 Serge 640
        push    edi
276 serge 641
 
2434 Serge 642
        bsf     eax, [mst.treemap]
643
        mov     ecx, [mst.treebins+eax*4]
276 serge 644
 
645
; rsize = (t->head & ~INUSE_BITS) - nb;
646
 
2434 Serge 647
        mov     edi, [ecx+4]
648
        and     edi, -4
649
        sub     edi, esi
2259 Serge 650
 
276 serge 651
.loop:
2434 Serge 652
        mov     ebx, ecx
2259 Serge 653
 
276 serge 654
.loop_1:
655
 
656
; while ((t = leftmost_child(t)) != 0)
657
 
2434 Serge 658
        mov     eax, [ecx+16]
659
        test    eax, eax
660
        jz      @F
661
        mov     ecx, eax
662
        jmp     .l1
2259 Serge 663
 
276 serge 664
@@:
2434 Serge 665
        mov     ecx, [ecx+20]
2259 Serge 666
 
276 serge 667
.l1:
2434 Serge 668
        test    ecx, ecx
669
        jz      .unlink
276 serge 670
 
671
; trem = (t->head & ~INUSE_BITS) - nb;
672
 
2434 Serge 673
        mov     eax, [ecx+4]
674
        and     eax, -4
675
        sub     eax, ebp
276 serge 676
 
677
; if (trem < rsize)
678
 
2434 Serge 679
        cmp     eax, edi
680
        jae     .loop_1
276 serge 681
 
682
; rsize = trem;
683
 
2434 Serge 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
 
2434 Serge 692
        mov     edx, ebx
693
        lea     esi, [ebx+ebp]
694
        call    unlink_large_chunk
276 serge 695
 
696
; if (rsize < 16)
697
 
2434 Serge 698
        cmp     edi, 16
699
        jae     .split
276 serge 700
 
701
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
702
 
2434 Serge 703
        lea     ecx, [edi+ebp]
276 serge 704
 
705
; (v+rsize + nb)->head |= PINUSE_BIT;
706
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 724
        or      ebp, 3
725
        mov     edx, edi
726
        or      edx, 1
276 serge 727
 
2434 Serge 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
 
2434 Serge 734
        shr     edi, 3
735
        bts     [mst.smallmap], edi
276 serge 736
 
2434 Serge 737
        mov     eax, edi
738
        shl     eax, 4
739
        add     eax, mst.smallbins
276 serge 740
 
2434 Serge 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:
2434 Serge 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
 
2434 Serge 769
        push    ebp
770
        push    esi
771
        push    edi
772
        sub     esp, 8
276 serge 773
; v = 0;
774
; rsize = -nb;
775
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 800
        cmp     ecx, 31
801
        jne     @F
802
        xor     ecx, ecx
803
        jmp     .l1
804
 
276 serge 805
@@:
2434 Serge 806
        mov     edx, ecx
807
        shr     edx, 1
808
        mov     ecx, 37
809
        sub     ecx, edx
810
 
276 serge 811
.l1:
2434 Serge 812
        mov     edx, ebx
813
        shl     edx, cl
276 serge 814
 
815
; rst = 0;
2434 Serge 816
        mov     [.rst], ebp
817
 
276 serge 818
.loop:
819
 
820
; trem = (t->head & ~INUSE_BITS) - nb;
821
 
2434 Serge 822
        mov     ecx, [eax+4]
823
        and     ecx, -4
824
        sub     ecx, ebx
276 serge 825
 
826
; if (trem < rsize)
827
 
2434 Serge 828
        cmp     ecx, edi
829
        jae     @F
276 serge 830
; v = t;
831
; if ((rsize = trem) == 0)
832
 
2434 Serge 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
 
2434 Serge 842
        mov     ecx, [eax+20]
276 serge 843
 
844
; t = t->child[(sizebits >> 31) & 1];
845
 
2434 Serge 846
        mov     esi, edx
847
        shr     esi, 31
276 serge 848
 
849
; if (rt != 0 && rt != t)
850
 
2434 Serge 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;
2434 Serge 858
        mov     [.rst], ecx
859
 
276 serge 860
@@:
861
; if (t == 0)
862
 
2434 Serge 863
        test    eax, eax
864
        jz      @F
276 serge 865
 
866
; sizebits <<= 1;
867
 
2434 Serge 868
        add     edx, edx
869
        jmp     .loop
870
 
276 serge 871
@@:
872
; t = rst;
2434 Serge 873
        mov     eax, [.rst]
874
 
276 serge 875
.l2:
876
; if (t == 0 && v == 0)
877
 
2434 Serge 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
 
2434 Serge 889
        or      edx, -1
890
        shl     edx, cl
891
        and     edx, [mst.treemap]
892
        jz      @F
276 serge 893
 
2434 Serge 894
        bsf     eax, edx
276 serge 895
; t = ms.treebins[i];
2434 Serge 896
        mov     eax, [mst.treebins+eax*4]
897
 
276 serge 898
@@:
899
 
900
; while (t != 0)
2434 Serge 901
        test    eax, eax
902
        jz      .l5
903
 
276 serge 904
.l4:
905
 
906
; trem = (t->head & ~INUSE_BITS) - nb;
907
 
2434 Serge 908
        mov     ecx, [eax+4]
909
        and     ecx, -4
910
        sub     ecx, ebx
276 serge 911
 
912
; if (trem < rsize)
913
 
2434 Serge 914
        cmp     ecx, edi
915
        jae     @F
276 serge 916
; rsize = trem;
917
 
2434 Serge 918
        mov     edi, ecx
276 serge 919
; v = t;
2434 Serge 920
        mov     ebp, eax
921
 
276 serge 922
@@:
923
 
924
; t = leftmost_child(t);
925
 
2434 Serge 926
        mov     ecx, [eax+16]
927
        test    ecx, ecx
928
        je      @F
929
        mov     eax, ecx
930
        jmp     .l6
931
 
276 serge 932
@@:
2434 Serge 933
        mov     eax, [eax+20]
934
 
276 serge 935
.l6:
936
 
937
; while (t != 0)
938
 
2434 Serge 939
        test    eax, eax
940
        jne     .l4
941
 
276 serge 942
.l5:
943
 
944
; if (v != 0)
945
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 960
        cmp     edi, 16
961
        jae     .large
276 serge 962
 
963
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
964
 
2434 Serge 965
        lea     ecx, [edi+ebx]
276 serge 966
 
967
; (v+rsize + nb)->head |= PINUSE_BIT;
968
 
2434 Serge 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
 
2434 Serge 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
 
2434 Serge 995
        mov     [esi+edi], edi
996
        mov     eax, edi
997
        mov     ecx, esi
998
        call    insert_chunk
276 serge 999
 
2434 Serge 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:
2434 Serge 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
 
2434 Serge 1017
        stdcall kernel_alloc, 0x40000
276 serge 1018
 
2434 Serge 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
@@:
2434 Serge 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
 
2434 Serge 1031
        mov     ecx, mst.mutex
1032
        call    mutex_init
2130 serge 1033
 
2434 Serge 1034
        ret
276 serge 1035