Subversion Repositories Kolibri OS

Rev

Rev 864 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 890 $
  9.  
  10.  
  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. ;
  23.  
  24. align 4
  25. _Kmalloc:
  26. malloc:
  27.            push esi
  28.  
  29. ; nb = ((size+7)&~7)+8;
  30.  
  31.            mov esi, eax    ;size
  32.            add esi, 7
  33.            and esi, -8
  34.            add esi, 8
  35.  
  36.            mov ebx, mst.mutex
  37.            call wait_mutex    ;ebx
  38.  
  39.            cmp esi, 256
  40.            jae .large
  41.  
  42.            mov ecx, esi
  43.            shr ecx, 3
  44.            or eax, -1
  45.            shl eax, cl
  46.            and eax, [mst.smallmap]
  47.            jz .small
  48.  
  49.            push ebp
  50.            push edi
  51.  
  52.            bsf eax, eax
  53.            mov ebx, eax
  54.  
  55. ; psize= idx<<3;
  56. ; B = &ms.smallbins[idx];
  57. ; p = B->fd;
  58. ; F = p->fd;
  59. ; rsize= psize-nb;
  60.  
  61.            lea ebp, [eax*8]               ;ebp= psize
  62.            shl eax, 4
  63.            lea edi, [mst.smallbins+eax]   ;edi= B
  64.            mov edx, [edi+8]               ;edx= p
  65.            mov eax, [edx+8]               ;eax= F
  66.            mov ecx, ebp
  67.            sub ecx, esi                   ;ecx= rsize
  68.  
  69. ; if (B == F)
  70.            cmp edi, eax
  71.            jne @F
  72.  
  73.            btr [mst.smallmap], ebx
  74. @@:
  75.  
  76. ; B->fd = F;
  77. ; F->bk = B;
  78. ; if(rsize<16)
  79.  
  80.            cmp ecx, 16
  81.            mov [edi+8], eax
  82.            mov [eax+12], edi
  83.            jae .split
  84.  
  85. ; p->head = psize|PINUSE_BIT|CINUSE_BIT;
  86. ; (p + psize)->head |= PINUSE_BIT;
  87.  
  88.            lea eax, [edx+8]
  89.            or dword [edx+ebp+4], 1
  90.  
  91.            or ebp, 3
  92.            mov [edx+4], ebp
  93.  
  94.            pop edi
  95.            pop ebp
  96. .done:
  97.            pop esi
  98.            mov [mst.mutex], 0
  99.            ret
  100. .split:
  101.            lea ebx, [edx+8]               ;ebx=mem
  102.  
  103. ; r = chunk_plus_offset(p, nb);
  104. ; p->head = nb|PINUSE_BIT|CINUSE_BIT;
  105. ; r->head = rsize|PINUSE_BIT;
  106.  
  107.            lea eax, [edx+esi]             ;eax= r
  108.            or esi, 3
  109.            mov [edx+4], esi
  110.  
  111.            mov edx, ecx
  112.            or edx, 1
  113.            mov [eax+4], edx
  114.  
  115. ; (r + rsize)->prev_foot = rsize;
  116.  
  117.            mov [eax+ecx], ecx
  118.  
  119. ; I  = rsize>>3;
  120.  
  121.            shr ecx, 3
  122.  
  123. ;      ms.smallmap |=  1<< I;
  124.            bts [mst.smallmap], ecx
  125.  
  126. ; B = &ms.smallbins[I];
  127.  
  128.            shl ecx, 4
  129.            pop edi
  130.            pop ebp
  131.            add ecx, mst.smallbins         ;ecx= B
  132.  
  133.            mov edx, [ecx+8]               ; F = B->fd;
  134.            mov [ecx+8], eax               ; B->fd = r;
  135.            mov [edx+12], eax              ; F->bk = r;
  136.            mov [eax+8], edx               ; r->fd = F;
  137.            mov [eax+12], ecx              ; r->bk = B;
  138.            mov eax, ebx
  139.            pop esi
  140.            ret
  141. .small:
  142.  
  143. ; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
  144.  
  145.            cmp [mst.treemap], 0
  146.            je .from_top
  147.            mov eax, esi
  148.            call malloc_small
  149.            test eax, eax
  150.            jz .from_top
  151.            pop esi
  152.            and [mst.mutex], 0
  153.            ret
  154. .large:
  155.  
  156. ; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
  157.  
  158.            cmp [mst.treemap], 0
  159.            je .from_top
  160.  
  161.            call malloc_large  ;esi= nb
  162.            test eax, eax
  163.            jne .done
  164. .from_top:
  165.  
  166. ; if (nb < ms.topsize)
  167.  
  168.            mov eax, [mst.topsize]
  169.            cmp esi, eax
  170.            jae .fail
  171.  
  172. ; rsize = ms.topsize -= nb;
  173. ; p = ms.top;
  174.  
  175.            mov ecx, [mst.top]
  176.            sub eax, esi
  177.            mov [mst.topsize], eax
  178.  
  179. ; r = ms.top = chunk_plus_offset(p, nb);
  180. ; r->head = rsize | PINUSE_BIT;
  181. ; p->head = nb |PINUSE_BIT|CINUSE_BIT;
  182.  
  183.            lea edx, [ecx+esi]
  184.            or eax, 1
  185.            mov [mst.top], edx
  186.            or esi, 3
  187.            mov [edx+4], eax
  188.            mov [ecx+4], esi
  189.            lea eax, [ecx+8]
  190.            pop esi
  191.            and [mst.mutex], 0
  192.            ret
  193. .fail:
  194.            xor eax, eax
  195.            pop esi
  196.            and [mst.mutex], 0
  197.            ret
  198.  
  199. ; param
  200. ;  eax= mem
  201.  
  202. align 4
  203. _Kfree:
  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
  253.            and [mst.smallmap], ecx
  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. align 4
  391. insert_chunk:
  392.  
  393.            cmp eax, 256
  394.            push esi
  395.            mov esi, ecx
  396.            jae .large
  397.  
  398. ; I  = S>>3;
  399. ; ms.smallmap |=  1<< I;
  400.  
  401.            shr eax, 3
  402.            bts [mst.smallmap], eax
  403.  
  404. ; B = &ms.smallbins[I];
  405.  
  406.            shl eax, 4
  407.            add eax, mst.smallbins
  408.            mov edx, [eax+8]            ;F = B->fd
  409.            mov [eax+8], esi            ;B->fd = P
  410.            mov [edx+12], esi           ;F->bk = P
  411.            mov [esi+8], edx            ;P->fd = F
  412.            mov [esi+12], eax           ;P->bk = B
  413.            pop esi
  414.            and [mst.mutex], 0
  415.            ret
  416. .large:
  417.            mov ebx, eax
  418.            call insert_large_chunk
  419.            pop esi
  420.            and [mst.mutex], 0
  421.            ret
  422.  
  423. align 4
  424.  
  425. ; param
  426. ;  esi= chunk
  427. ;  ebx= size
  428.  
  429. align 4
  430. insert_large_chunk:
  431.  
  432. ; I = compute_tree_index(S);
  433.  
  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]
  442.  
  443. ; X->index = I;
  444.            mov dword [esi+28], ecx
  445.  
  446. ; X->child[0] = X->child[1] = 0;
  447.            and dword [esi+20], 0
  448.            and dword [esi+16], 0
  449.  
  450. ; H = &ms.treebins[I];
  451.  
  452.            mov eax, ecx
  453.            lea edx, [mst.treebins+eax*4]
  454.  
  455. ; if (!(ms.treemap & 1<<I))
  456.            bt [mst.treemap], ecx
  457.            jc .tree
  458.  
  459. ; ms.treemap |= 1<<I;
  460.            bts [mst.treemap], ecx
  461. ; *H = X;
  462.            mov dword [edx], esi
  463.            jmp .done
  464. .tree:
  465.  
  466. ; T = *H;
  467.            mov edx, [edx]
  468.  
  469. ; K = S << leftshift_for_tree_index(I);
  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
  480.  
  481.            jmp .loop
  482.  
  483. .not_eq_size:
  484.  
  485. ; C = &(T->child[(K >> 31) & 1]);
  486.            mov ecx, eax
  487.            shr ecx, 31
  488.            lea ecx, [edx+ecx*4+16]
  489.  
  490. ; K <<= 1;
  491. ; if (*C != 0)
  492.            mov edi, [ecx]
  493.            add eax, eax
  494.            test edi, edi
  495.            jz .insert_child
  496.  
  497. ; T = *C;
  498.            mov edx, edi
  499. .loop:
  500.  
  501. ; for (;;)
  502. ; if ((T->head & ~INUSE_BITS) != S)
  503.  
  504.            mov ecx, [edx+4]
  505.            and ecx, not 3
  506.            cmp ecx, ebx
  507.            jne .not_eq_size
  508.  
  509. ; F = T->fd;
  510.            mov eax, [edx+8]
  511.  
  512. ; T->fd = F->bk = X;
  513.            mov [eax+12], esi
  514.            mov [edx+8], esi
  515.  
  516. ; X->fd = F;
  517. ; X->bk = T;
  518. ; X->parent = 0;
  519.  
  520.            and dword [esi+24], 0
  521.            mov [esi+8], eax
  522.            mov [esi+12], edx
  523.            ret
  524.  
  525. .insert_child:
  526.  
  527. ; *C = X;
  528.            mov [ecx], esi
  529. .done:
  530.  
  531. ; X->parent = T;
  532.            mov [esi+24], edx
  533.  
  534. ; X->fd = X->bk = X;
  535.            mov [esi+12], esi
  536.            mov [esi+8], esi
  537.            ret
  538.  
  539.  
  540. ; param
  541. ;  edx= chunk
  542.  
  543. align 4
  544. unlink_large_chunk:
  545.  
  546.            mov eax, [edx+12]
  547.            cmp eax, edx
  548.            push edi
  549.            mov edi, [edx+24]
  550.            je @F
  551.  
  552.            mov ecx, [edx+8]           ;F = X->fd
  553.            mov [ecx+12], eax          ;F->bk = R;
  554.            mov [eax+8], ecx           ;R->fd = F
  555.            jmp .parent
  556. @@:
  557.            mov eax, [edx+20]
  558.            test eax, eax
  559.            push esi
  560.            lea esi, [edx+20]
  561.            jne .loop
  562.  
  563.            mov eax, [edx+16]
  564.            test eax, eax
  565.            lea esi, [edx+16]
  566.            je .l2
  567. .loop:
  568.            cmp dword [eax+20], 0
  569.            lea ecx, [eax+20]
  570.            jne @F
  571.  
  572.            cmp dword [eax+16], 0
  573.            lea ecx, [eax+16]
  574.            je .l1
  575. @@:
  576.            mov eax, [ecx]
  577.            mov esi, ecx
  578.            jmp .loop
  579. .l1:
  580.            mov dword [esi], 0
  581. .l2:
  582.            pop esi
  583. .parent:
  584.            test edi, edi
  585.            je .done
  586.  
  587.            mov ecx, [edx+28]
  588.            cmp edx, [mst.treebins+ecx*4]
  589.            lea ecx, [mst.treebins+ecx*4]
  590.            jne .l3
  591.  
  592.            test eax, eax
  593.            mov [ecx], eax
  594.            jne .l5
  595.  
  596.            mov ecx, [edx+28]
  597.            btr [mst.treemap], ecx
  598.            pop edi
  599.            ret
  600. .l3:
  601.            cmp [edi+16], edx
  602.            jne @F
  603.  
  604.            mov [edi+16], eax
  605.            jmp .l4
  606. @@:
  607.            mov [edi+20], eax
  608. .l4:
  609.            test eax, eax
  610.            je .done
  611. .l5:
  612.            mov [eax+24], edi
  613.            mov ecx, [edx+16]
  614.            test ecx, ecx
  615.            je .l6
  616.  
  617.            mov [eax+16], ecx
  618.            mov [ecx+24], eax
  619. .l6:
  620.            mov edx, [edx+20]
  621.            test edx, edx
  622.            je .done
  623.  
  624.            mov [eax+20], edx
  625.            mov [edx+24], eax
  626. .done:
  627.            pop edi
  628.            ret
  629.  
  630. ; param
  631. ;  esi= nb
  632.  
  633. align 4
  634. malloc_small:
  635.            push ebp
  636.            mov ebp, esi
  637.  
  638.            push edi
  639.  
  640.            bsf eax,[mst.treemap]
  641.            mov ecx, [mst.treebins+eax*4]
  642.  
  643. ; rsize = (t->head & ~INUSE_BITS) - nb;
  644.  
  645.            mov edi, [ecx+4]
  646.            and edi, -4
  647.            sub edi, esi
  648. .loop:
  649.            mov ebx, ecx
  650. .loop_1:
  651.  
  652. ; while ((t = leftmost_child(t)) != 0)
  653.  
  654.            mov eax, [ecx+16]
  655.            test eax, eax
  656.            jz @F
  657.            mov ecx, eax
  658.            jmp .l1
  659. @@:
  660.            mov ecx, [ecx+20]
  661. .l1:
  662.            test ecx, ecx
  663.            jz .unlink
  664.  
  665. ; trem = (t->head & ~INUSE_BITS) - nb;
  666.  
  667.            mov eax, [ecx+4]
  668.            and eax, -4
  669.            sub eax, ebp
  670.  
  671. ; if (trem < rsize)
  672.  
  673.            cmp eax, edi
  674.            jae .loop_1
  675.  
  676. ; rsize = trem;
  677.  
  678.            mov edi, eax
  679.            jmp .loop
  680. .unlink:
  681.  
  682.  
  683. ; r = chunk_plus_offset((mchunkptr)v, nb);
  684. ; unlink_large_chunk(v);
  685.  
  686.            mov edx, ebx
  687.            lea esi, [ebx+ebp]
  688.            call unlink_large_chunk
  689.  
  690. ; if (rsize < 16)
  691.  
  692.            cmp edi, 16
  693.            jae .split
  694.  
  695. ; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
  696.  
  697.            lea ecx, [edi+ebp]
  698.  
  699. ; (v+rsize + nb)->head |= PINUSE_BIT;
  700.  
  701.            add edi, ebx
  702.            lea eax, [edi+ebp+4]
  703.            pop edi
  704.            or ecx, 3
  705.            mov [ebx+4], ecx
  706.            or dword [eax], 1
  707.            pop ebp
  708.  
  709.            lea eax, [ebx+8]
  710.            ret
  711. .split:
  712.  
  713. ; v->head = nb|PINUSE_BIT|CINUSE_BIT;
  714. ; r->head = rsize|PINUSE_BIT;
  715. ; (r+rsize)->prev_foot = rsize;
  716.  
  717.            or ebp, 3
  718.            mov edx, edi
  719.            or edx, 1
  720.  
  721.            cmp edi, 256
  722.            mov [ebx+4], ebp
  723.            mov [esi+4], edx
  724.            mov [esi+edi], edi
  725.            jae .large
  726.  
  727.            shr edi, 3
  728.            bts [mst.smallmap], edi
  729.  
  730.            mov eax, edi
  731.            shl eax, 4
  732.            add eax, mst.smallbins
  733.  
  734.            mov edx, [eax+8]
  735.            mov [eax+8], esi
  736.            mov [edx+12], esi
  737.            pop edi
  738.            mov [esi+12], eax
  739.            mov [esi+8], edx
  740.            pop ebp
  741.            lea eax, [ebx+8]
  742.            ret
  743. .large:
  744.            lea eax, [ebx+8]
  745.            push eax
  746.            mov ebx, edi
  747.            call insert_large_chunk
  748.            pop eax
  749.            pop edi
  750.            pop ebp
  751.            ret
  752.  
  753.  
  754. ; param
  755. ;  esi= nb
  756.  
  757. align 4
  758. malloc_large:
  759. .idx equ esp+4
  760. .rst equ esp
  761.  
  762.            push ebp
  763.            push edi
  764.            sub esp, 8
  765. ; v = 0;
  766. ; rsize = -nb;
  767.  
  768.            mov edi, esi
  769.            mov ebx, esi
  770.            xor ebp, ebp
  771.            neg edi
  772.  
  773. ; idx = compute_tree_index(nb);
  774.  
  775.            mov edx, esi
  776.            shr edx, 8
  777.            bsr eax, edx
  778.            lea ecx, [eax+7]
  779.            shr esi, cl
  780.            and esi, 1
  781.            lea ecx, [esi+eax*2]
  782.            mov [.idx], ecx
  783.  
  784. ; if ((t = ms.treebins[idx]) != 0)
  785.  
  786.            mov eax, [mst.treebins+ecx*4]
  787.            test eax, eax
  788.            jz .l3
  789.  
  790. ; sizebits = nb << leftshift_for_tree_index(idx);
  791.  
  792.            cmp ecx, 31
  793.            jne @F
  794.            xor ecx, ecx
  795.            jmp .l1
  796. @@:
  797.            mov edx, ecx
  798.            shr edx, 1
  799.            mov ecx, 37
  800.            sub ecx, edx
  801. .l1:
  802.            mov edx, ebx
  803.            shl edx, cl
  804.  
  805. ; rst = 0;
  806.            mov [.rst], ebp
  807. .loop:
  808.  
  809. ; trem = (t->head & ~INUSE_BITS) - nb;
  810.  
  811.            mov ecx, [eax+4]
  812.            and ecx, -4
  813.            sub ecx, ebx
  814.  
  815. ; if (trem < rsize)
  816.  
  817.            cmp ecx, edi
  818.            jae @F
  819. ; v = t;
  820. ; if ((rsize = trem) == 0)
  821.  
  822.            test ecx, ecx
  823.            mov ebp, eax
  824.            mov edi, ecx
  825.            je .l2
  826. @@:
  827.  
  828. ; rt = t->child[1];
  829.  
  830.            mov ecx, [eax+20]
  831.  
  832. ; t = t->child[(sizebits >> 31) & 1];
  833.  
  834.            mov esi, edx
  835.            shr esi, 31
  836.  
  837. ; if (rt != 0 && rt != t)
  838.  
  839.            test ecx, ecx
  840.            mov eax, [eax+esi*4+16]
  841.            jz @F
  842.            cmp ecx, eax
  843.            jz @F
  844.  
  845. ; rst = rt;
  846.            mov [.rst], ecx
  847. @@:
  848. ; if (t == 0)
  849.  
  850.            test eax, eax
  851.            jz @F
  852.  
  853. ; sizebits <<= 1;
  854.  
  855.            add edx, edx
  856.            jmp .loop
  857. @@:
  858. ; t = rst;
  859.            mov eax, [.rst]
  860. .l2:
  861. ; if (t == 0 && v == 0)
  862.  
  863.            test eax, eax
  864.            jne .l4
  865.            test ebp, ebp
  866.            jne .l7
  867.            mov ecx, [.idx]
  868. .l3:
  869.  
  870. ; leftbits = (-1<<idx) & ms.treemap;
  871. ; if (leftbits != 0)
  872.  
  873.            or edx, -1
  874.            shl edx, cl
  875.            and edx, [mst.treemap]
  876.            jz @F
  877.  
  878.            bsf eax, edx
  879. ; t = ms.treebins[i];
  880.            mov eax, [mst.treebins+eax*4]
  881. @@:
  882.  
  883. ; while (t != 0)
  884.            test eax, eax
  885.            jz .l5
  886. .l4:
  887.  
  888. ; trem = (t->head & ~INUSE_BITS) - nb;
  889.  
  890.            mov ecx, [eax+4]
  891.            and ecx, -4
  892.            sub ecx, ebx
  893.  
  894. ; if (trem < rsize)
  895.  
  896.            cmp ecx, edi
  897.            jae @F
  898. ; rsize = trem;
  899.  
  900.            mov edi, ecx
  901. ; v = t;
  902.            mov ebp, eax
  903. @@:
  904.  
  905. ; t = leftmost_child(t);
  906.  
  907.            mov ecx, [eax+16]
  908.            test ecx, ecx
  909.            je @F
  910.            mov eax, ecx
  911.            jmp .l6
  912. @@:
  913.            mov eax, [eax+20]
  914. .l6:
  915.  
  916. ; while (t != 0)
  917.  
  918.            test eax, eax
  919.            jne .l4
  920. .l5:
  921.  
  922. ; if (v != 0)
  923.  
  924.            test ebp, ebp
  925.            jz .done
  926. .l7:
  927.  
  928. ; r = chunk_plus_offset((mchunkptr)v, nb);
  929. ; unlink_large_chunk(v);
  930.  
  931.            mov edx, ebp
  932.            lea esi, [ebx+ebp]
  933.            call unlink_large_chunk
  934.  
  935. ; if (rsize < 16)
  936.  
  937.            cmp edi, 16
  938.            jae .large
  939.  
  940. ; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
  941.  
  942.            lea ecx, [edi+ebx]
  943.  
  944. ; (v+rsize + nb)->head |= PINUSE_BIT;
  945.  
  946.            add edi, ebp
  947.            lea eax, [edi+ebx+4]
  948.            or ecx, 3
  949.            mov [ebp+4], ecx
  950.            or dword [eax], 1
  951.            lea eax, [ebp+8]
  952.            add esp, 8
  953.            pop edi
  954.            pop ebp
  955.            ret
  956. .large:
  957.  
  958. ; v->head = nb|PINUSE_BIT|CINUSE_BIT;
  959. ; r->head = rsize|PINUSE_BIT;
  960.  
  961.            mov edx, edi
  962.            or ebx, 3
  963.            mov [ebp+4], ebx
  964.            or edx, 1
  965.            mov [esi+4], edx
  966.  
  967. ; (r+rsize)->prev_foot = rsize;
  968. ; insert_large_chunk((tchunkptr)r, rsize);
  969.  
  970.            mov [esi+edi], edi
  971.            mov eax, edi
  972.            mov ecx, esi
  973.            call insert_chunk
  974.  
  975.            lea eax, [ebp+8]
  976.            add esp, 8
  977.            pop edi
  978.            pop ebp
  979.            ret
  980. .done:
  981.            add esp, 8
  982.            pop edi
  983.            pop ebp
  984.            xor eax, eax
  985.            ret
  986.  
  987. align 4
  988. init_malloc:
  989.  
  990.            mov ecx, 6
  991.            call @core_alloc@4
  992.            add eax, OS_BASE
  993.  
  994.            mov [mst.top], eax
  995.            mov [mst.topsize], 256*1024
  996.            mov dword [eax+4], (256*1024) or 1
  997.            mov eax, mst.smallbins
  998. @@:
  999.            mov [eax+8], eax
  1000.            mov [eax+12], eax
  1001.            add eax, 16
  1002.            cmp eax, mst.smallbins+512
  1003.            jb @B
  1004.  
  1005.            ret
  1006.  
  1007.  
  1008.  
  1009.  
  1010.