Subversion Repositories Kolibri OS

Rev

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

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