Subversion Repositories Kolibri OS

Rev

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