Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 2129 $
  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. align 4
  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 ecx, mst.mutex
  35.            call mutex_lock
  36.  
  37.            cmp esi, 256
  38.            jae .large
  39.  
  40.            mov ecx, esi
  41.            shr ecx, 3
  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.            mov esi, eax
  96.            mov ecx, mst.mutex
  97.            call mutex_unlock
  98.            mov eax, esi
  99.            pop esi
  100.            ret
  101.  
  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;
  140.  
  141.            mov eax, ebx
  142.            jmp .done
  143.  
  144. .small:
  145.  
  146. ; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
  147. ;;;;;;;;;;; start a change <lrz>
  148.            mov  eax,[mst.treemap]
  149.            test eax,eax
  150. ;;;;;;;;;;; end the change <lrz>
  151. ;           cmp [mst.treemap], 0
  152.            jz .from_top
  153.            mov eax, esi
  154.            call malloc_small
  155.            test eax, eax
  156.            jz .from_top
  157.            jmp .done
  158.  
  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]
  195.            jmp .done
  196.  
  197. .fail:
  198.            xor eax, eax
  199.            jmp .done
  200.  
  201. ; param
  202. ;  eax= mem
  203. align 4
  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 ecx, mst.mutex
  215.            call mutex_lock
  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.            btr [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.            mov esi, eax
  293.            mov ecx, mst.mutex
  294.            call mutex_unlock
  295.            mov eax, esi
  296.            pop esi
  297. .fail:
  298.            pop edi
  299.            ret
  300. @@:
  301.  
  302. ; nsize = next->head & ~INUSE_BITS;
  303.  
  304.            and eax, -4
  305.            add esi, eax                ;psize += nsize;
  306.  
  307. ; if (nsize < 256)
  308.  
  309.            cmp eax, 256
  310.            jae .unl_large
  311.  
  312.            mov edx, [ebx+8]            ;F = next->fd
  313.            mov ebx, [ebx+12]           ;B = next->bk
  314.  
  315. ; if (F == B)
  316.  
  317.            cmp edx, ebx
  318.            jne @F
  319.            mov ecx, eax
  320.            shr ecx, 3
  321.            btr [mst.smallmap], ecx
  322. @@:
  323.            mov [edx+12], ebx           ;F->bk = B
  324.  
  325. ; p->head = psize|PINUSE_BIT;
  326.  
  327.            mov ecx, esi
  328.            mov [ebx+8], edx
  329.            or ecx, 1
  330.            mov [edi+4], ecx
  331.  
  332. ; (p+psize)->prev_foot = psize;
  333.  
  334.            mov [esi+edi], esi
  335.  
  336. ; insert_chunk(p,psize);
  337.  
  338.            mov eax, esi
  339.            pop esi
  340.            mov ecx, edi
  341.            pop edi
  342.            jmp insert_chunk
  343. .unl_large:
  344.  
  345. ; unlink_large_chunk((tchunkptr)next);
  346.  
  347.            mov edx, ebx
  348.            call unlink_large_chunk
  349. ; p->head = psize|PINUSE_BIT;
  350.  
  351.            mov ecx, esi
  352.            or ecx, 1
  353.            mov [edi+4], ecx
  354.  
  355. ; (p+psize)->prev_foot = psize;
  356.  
  357.            mov [esi+edi], esi
  358.  
  359. ; insert_chunk(p,psize);
  360.  
  361.            mov eax, esi
  362.            pop esi
  363.            mov ecx, edi
  364.            pop edi
  365.            jmp insert_chunk
  366. .fix_next:
  367.  
  368. ; (p+psize)->prev_foot = psize;
  369. ; next->head &= ~PINUSE_BIT;
  370. ; p->head = psize|PINUSE_BIT;
  371.  
  372.            and eax, -2
  373.            mov edx, esi
  374.            mov [ebx+4], eax
  375.            or edx, 1
  376.            mov [edi+4], edx
  377.  
  378. ; (p+psize)->prev_foot = psize;
  379.  
  380.            mov [esi+edi], esi
  381. ; insert_chunk(p,psize);
  382.  
  383.            mov eax, esi
  384.            pop esi
  385.            mov ecx, edi
  386.            pop edi
  387.            jmp insert_chunk
  388.  
  389. ; param
  390. ;  ecx = chunk
  391. ;  eax = size
  392.  
  393. insert_chunk:
  394.  
  395.            cmp eax, 256
  396.            push esi
  397.            mov esi, ecx
  398.            jae .large
  399.  
  400. ; I  = S>>3;
  401. ; ms.smallmap |=  1<< I;
  402.  
  403.            shr eax, 3
  404.            bts [mst.smallmap], eax
  405.  
  406. ; B = &ms.smallbins[I];
  407.  
  408.            shl eax, 4
  409.            add eax, mst.smallbins
  410.            mov edx, [eax+8]            ;F = B->fd
  411.            mov [eax+8], esi            ;B->fd = P
  412.            mov [edx+12], esi           ;F->bk = P
  413.            mov [esi+8], edx            ;P->fd = F
  414.            mov [esi+12], eax           ;P->bk = B
  415.            pop esi
  416.            mov ecx, mst.mutex
  417.            call mutex_unlock
  418.            ret
  419. .large:
  420.            mov ebx, eax
  421.            call insert_large_chunk
  422.            pop esi
  423.            mov ecx, mst.mutex
  424.            call mutex_unlock
  425.            ret
  426.  
  427.  
  428. ; param
  429. ;  esi= chunk
  430. ;  ebx= size
  431.  
  432. insert_large_chunk:
  433.  
  434. ; I = compute_tree_index(S);
  435.  
  436.            mov edx, ebx
  437.            shr edx, 8
  438.            bsr eax, edx
  439.            lea ecx, [eax+7]
  440.            mov edx, ebx
  441.            shr edx, cl
  442.            and edx, 1
  443.            lea ecx, [edx+eax*2]
  444.  
  445. ; X->index = I;
  446.            mov dword [esi+28], ecx
  447.  
  448. ; X->child[0] = X->child[1] = 0;
  449.            and dword [esi+20], 0
  450.            and dword [esi+16], 0
  451.  
  452. ; H = &ms.treebins[I];
  453.  
  454.            mov eax, ecx
  455.            lea edx, [mst.treebins+eax*4]
  456.  
  457. ; if (!(ms.treemap & 1<<I))
  458.            bt [mst.treemap], ecx
  459.            jc .tree
  460.  
  461. ; ms.treemap |= 1<<I;
  462.            bts [mst.treemap], ecx
  463. ; *H = X;
  464.            mov dword [edx], esi
  465.            jmp .done
  466. .tree:
  467.  
  468. ; T = *H;
  469.            mov edx, [edx]
  470.  
  471. ; K = S << leftshift_for_tree_index(I);
  472.            mov eax, ecx
  473.            shr eax, 1
  474.            sub ecx, 31
  475.            mov edi, 37
  476.            sub edi, eax
  477.            neg ecx
  478.            sbb ecx, ecx
  479.            and ecx, edi
  480.            mov eax, ebx
  481.            shl eax, cl     ;eax= K
  482.  
  483.            jmp .loop
  484. .not_eq_size:
  485.  
  486. ; C = &(T->child[(K >> 31) & 1]);
  487.            mov ecx, eax
  488.            shr ecx, 31
  489.            lea ecx, [edx+ecx*4+16]
  490.  
  491. ; K <<= 1;
  492. ; if (*C != 0)
  493.            mov edi, [ecx]
  494.            add eax, eax
  495.            test edi, edi
  496.            jz .insert_child
  497.  
  498. ; T = *C;
  499.            mov edx, edi
  500. .loop:
  501.  
  502. ; for (;;)
  503. ; if ((T->head & ~INUSE_BITS) != S)
  504.  
  505.            mov ecx, [edx+4]
  506.            and ecx, not 3
  507.            cmp ecx, ebx
  508.            jne .not_eq_size
  509.  
  510. ; F = T->fd;
  511.            mov eax, [edx+8]
  512.  
  513. ; T->fd = F->bk = X;
  514.            mov [eax+12], esi
  515.            mov [edx+8], esi
  516.  
  517. ; X->fd = F;
  518. ; X->bk = T;
  519. ; X->parent = 0;
  520.  
  521.            and dword [esi+24], 0
  522.            mov [esi+8], eax
  523.            mov [esi+12], edx
  524.            ret
  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. unlink_large_chunk:
  544.  
  545.            mov eax, [edx+12]
  546.            cmp eax, edx
  547.            push edi
  548.            mov edi, [edx+24]
  549.            je @F
  550.  
  551.            mov ecx, [edx+8]           ;F = X->fd
  552.            mov [ecx+12], eax          ;F->bk = R;
  553.            mov [eax+8], ecx           ;R->fd = F
  554.            jmp .parent
  555. @@:
  556.            mov eax, [edx+20]
  557.            test eax, eax
  558.            push esi
  559.            lea esi, [edx+20]
  560.            jne .loop
  561.  
  562.            mov eax, [edx+16]
  563.            test eax, eax
  564.            lea esi, [edx+16]
  565.            je .l2
  566. .loop:
  567.            cmp dword [eax+20], 0
  568.            lea ecx, [eax+20]
  569.            jne @F
  570.  
  571.            cmp dword [eax+16], 0
  572.            lea ecx, [eax+16]
  573.            je .l1
  574. @@:
  575.            mov eax, [ecx]
  576.            mov esi, ecx
  577.            jmp .loop
  578. .l1:
  579.            mov dword [esi], 0
  580. .l2:
  581.            pop esi
  582. .parent:
  583.            test edi, edi
  584.            je .done
  585.  
  586.            mov ecx, [edx+28]
  587.            cmp edx, [mst.treebins+ecx*4]
  588.            lea ecx, [mst.treebins+ecx*4]
  589.            jne .l3
  590.  
  591.            test eax, eax
  592.            mov [ecx], eax
  593.            jne .l5
  594.  
  595.            mov ecx, [edx+28]
  596.            btr [mst.treemap], ecx
  597.            pop edi
  598.            ret
  599.  
  600. .l3:
  601.            cmp [edi+16], edx
  602.            jne @F
  603.  
  604.            mov [edi+16], eax
  605.            jmp .l4
  606.  
  607. @@:
  608.            mov [edi+20], eax
  609.  
  610. .l4:
  611.            test eax, eax
  612.            je .done
  613.  
  614. .l5:
  615.            mov [eax+24], edi
  616.            mov ecx, [edx+16]
  617.            test ecx, ecx
  618.            je .l6
  619.  
  620.            mov [eax+16], ecx
  621.            mov [ecx+24], eax
  622.  
  623. .l6:
  624.            mov edx, [edx+20]
  625.            test edx, edx
  626.            je .done
  627.  
  628.            mov [eax+20], edx
  629.            mov [edx+24], eax
  630.  
  631. .done:
  632.            pop edi
  633.            ret
  634.  
  635. ; param
  636. ;  esi= nb
  637.  
  638. malloc_small:
  639.            push ebp
  640.            mov ebp, esi
  641.  
  642.            push edi
  643.  
  644.            bsf eax,[mst.treemap]
  645.            mov ecx, [mst.treebins+eax*4]
  646.  
  647. ; rsize = (t->head & ~INUSE_BITS) - nb;
  648.  
  649.            mov edi, [ecx+4]
  650.            and edi, -4
  651.            sub edi, esi
  652.  
  653. .loop:
  654.            mov ebx, ecx
  655.  
  656. .loop_1:
  657.  
  658. ; while ((t = leftmost_child(t)) != 0)
  659.  
  660.            mov eax, [ecx+16]
  661.            test eax, eax
  662.            jz @F
  663.            mov ecx, eax
  664.            jmp .l1
  665.  
  666. @@:
  667.            mov ecx, [ecx+20]
  668.  
  669. .l1:
  670.            test ecx, ecx
  671.            jz .unlink
  672.  
  673. ; trem = (t->head & ~INUSE_BITS) - nb;
  674.  
  675.            mov eax, [ecx+4]
  676.            and eax, -4
  677.            sub eax, ebp
  678.  
  679. ; if (trem < rsize)
  680.  
  681.            cmp eax, edi
  682.            jae .loop_1
  683.  
  684. ; rsize = trem;
  685.  
  686.            mov edi, eax
  687.            jmp .loop
  688. .unlink:
  689.  
  690.  
  691. ; r = chunk_plus_offset((mchunkptr)v, nb);
  692. ; unlink_large_chunk(v);
  693.  
  694.            mov edx, ebx
  695.            lea esi, [ebx+ebp]
  696.            call unlink_large_chunk
  697.  
  698. ; if (rsize < 16)
  699.  
  700.            cmp edi, 16
  701.            jae .split
  702.  
  703. ; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
  704.  
  705.            lea ecx, [edi+ebp]
  706.  
  707. ; (v+rsize + nb)->head |= PINUSE_BIT;
  708.  
  709.            add edi, ebx
  710.            lea eax, [edi+ebp+4]
  711.            pop edi
  712.            or ecx, 3
  713.            mov [ebx+4], ecx
  714.            or dword [eax], 1
  715.            pop ebp
  716.  
  717.            lea eax, [ebx+8]
  718.            ret
  719.  
  720. .split:
  721.  
  722. ; v->head = nb|PINUSE_BIT|CINUSE_BIT;
  723. ; r->head = rsize|PINUSE_BIT;
  724. ; (r+rsize)->prev_foot = rsize;
  725.  
  726.            or ebp, 3
  727.            mov edx, edi
  728.            or edx, 1
  729.  
  730.            cmp edi, 256
  731.            mov [ebx+4], ebp
  732.            mov [esi+4], edx
  733.            mov [esi+edi], edi
  734.            jae .large
  735.  
  736.            shr edi, 3
  737.            bts [mst.smallmap], edi
  738.  
  739.            mov eax, edi
  740.            shl eax, 4
  741.            add eax, mst.smallbins
  742.  
  743.            mov edx, [eax+8]
  744.            mov [eax+8], esi
  745.            mov [edx+12], esi
  746.            pop edi
  747.            mov [esi+12], eax
  748.            mov [esi+8], edx
  749.            pop ebp
  750.            lea eax, [ebx+8]
  751.            ret
  752.  
  753. .large:
  754.            lea eax, [ebx+8]
  755.            push eax
  756.            mov ebx, edi
  757.            call insert_large_chunk
  758.            pop eax
  759.            pop edi
  760.            pop ebp
  761.            ret
  762.  
  763.  
  764. ; param
  765. ;  esi= nb
  766.  
  767. malloc_large:
  768. .idx equ esp+4
  769. .rst equ esp
  770.  
  771.            push ebp
  772.            push esi
  773.            push edi
  774.            sub esp, 8
  775. ; v = 0;
  776. ; rsize = -nb;
  777.  
  778.            mov edi, esi
  779.            mov ebx, esi
  780.            xor ebp, ebp
  781.            neg edi
  782.  
  783. ; idx = compute_tree_index(nb);
  784.  
  785.            mov edx, esi
  786.            shr edx, 8
  787.            bsr eax, edx
  788.            lea ecx, [eax+7]
  789.            shr esi, cl
  790.            and esi, 1
  791.            lea ecx, [esi+eax*2]
  792.            mov [.idx], ecx
  793.  
  794. ; if ((t = ms.treebins[idx]) != 0)
  795.  
  796.            mov eax, [mst.treebins+ecx*4]
  797.            test eax, eax
  798.            jz .l3
  799.  
  800. ; sizebits = nb << leftshift_for_tree_index(idx);
  801.  
  802.            cmp ecx, 31
  803.            jne @F
  804.            xor ecx, ecx
  805.            jmp .l1
  806.  
  807. @@:
  808.            mov edx, ecx
  809.            shr edx, 1
  810.            mov ecx, 37
  811.            sub ecx, edx
  812.  
  813. .l1:
  814.            mov edx, ebx
  815.            shl edx, cl
  816.  
  817. ; rst = 0;
  818.            mov [.rst], ebp
  819.  
  820. .loop:
  821.  
  822. ; trem = (t->head & ~INUSE_BITS) - nb;
  823.  
  824.            mov ecx, [eax+4]
  825.            and ecx, -4
  826.            sub ecx, ebx
  827.  
  828. ; if (trem < rsize)
  829.  
  830.            cmp ecx, edi
  831.            jae @F
  832. ; v = t;
  833. ; if ((rsize = trem) == 0)
  834.  
  835.            test ecx, ecx
  836.            mov ebp, eax
  837.            mov edi, ecx
  838.            je .l2
  839.  
  840. @@:
  841.  
  842. ; rt = t->child[1];
  843.  
  844.            mov ecx, [eax+20]
  845.  
  846. ; t = t->child[(sizebits >> 31) & 1];
  847.  
  848.            mov esi, edx
  849.            shr esi, 31
  850.  
  851. ; if (rt != 0 && rt != t)
  852.  
  853.            test ecx, ecx
  854.            mov eax, [eax+esi*4+16]
  855.            jz @F
  856.            cmp ecx, eax
  857.            jz @F
  858.  
  859. ; rst = rt;
  860.            mov [.rst], ecx
  861.  
  862. @@:
  863. ; if (t == 0)
  864.  
  865.            test eax, eax
  866.            jz @F
  867.  
  868. ; sizebits <<= 1;
  869.  
  870.            add edx, edx
  871.            jmp .loop
  872.  
  873. @@:
  874. ; t = rst;
  875.            mov eax, [.rst]
  876.  
  877. .l2:
  878. ; if (t == 0 && v == 0)
  879.  
  880.            test eax, eax
  881.            jne .l4
  882.            test ebp, ebp
  883.            jne .l7
  884.            mov ecx, [.idx]
  885.  
  886. .l3:
  887.  
  888. ; leftbits = (-1<<idx) & ms.treemap;
  889. ; if (leftbits != 0)
  890.  
  891.            or edx, -1
  892.            shl edx, cl
  893.            and edx, [mst.treemap]
  894.            jz @F
  895.  
  896.            bsf eax, edx
  897. ; t = ms.treebins[i];
  898.            mov eax, [mst.treebins+eax*4]
  899.  
  900. @@:
  901.  
  902. ; while (t != 0)
  903.            test eax, eax
  904.            jz .l5
  905.  
  906. .l4:
  907.  
  908. ; trem = (t->head & ~INUSE_BITS) - nb;
  909.  
  910.            mov ecx, [eax+4]
  911.            and ecx, -4
  912.            sub ecx, ebx
  913.  
  914. ; if (trem < rsize)
  915.  
  916.            cmp ecx, edi
  917.            jae @F
  918. ; rsize = trem;
  919.  
  920.            mov edi, ecx
  921. ; v = t;
  922.            mov ebp, eax
  923.  
  924. @@:
  925.  
  926. ; t = leftmost_child(t);
  927.  
  928.            mov ecx, [eax+16]
  929.            test ecx, ecx
  930.            je @F
  931.            mov eax, ecx
  932.            jmp .l6
  933.  
  934. @@:
  935.            mov eax, [eax+20]
  936.  
  937. .l6:
  938.  
  939. ; while (t != 0)
  940.  
  941.            test eax, eax
  942.            jne .l4
  943.  
  944. .l5:
  945.  
  946. ; if (v != 0)
  947.  
  948.            test ebp, ebp
  949.            jz .done
  950.  
  951. .l7:
  952.  
  953. ; r = chunk_plus_offset((mchunkptr)v, nb);
  954. ; unlink_large_chunk(v);
  955.  
  956.            mov edx, ebp
  957.            lea esi, [ebx+ebp]
  958.            call unlink_large_chunk
  959.  
  960. ; if (rsize < 16)
  961.  
  962.            cmp edi, 16
  963.            jae .large
  964.  
  965. ; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
  966.  
  967.            lea ecx, [edi+ebx]
  968.  
  969. ; (v+rsize + nb)->head |= PINUSE_BIT;
  970.  
  971.            add edi, ebp
  972.            lea eax, [edi+ebx+4]
  973.            or ecx, 3
  974.            mov [ebp+4], ecx
  975.            or dword [eax], 1
  976.            lea eax, [ebp+8]
  977.            add esp, 8
  978.            pop edi
  979.            pop esi
  980.            pop ebp
  981.            ret
  982.  
  983. .large:
  984.  
  985. ; v->head = nb|PINUSE_BIT|CINUSE_BIT;
  986. ; r->head = rsize|PINUSE_BIT;
  987.  
  988.            mov edx, edi
  989.            or ebx, 3
  990.            mov [ebp+4], ebx
  991.            or edx, 1
  992.            mov [esi+4], edx
  993.  
  994. ; (r+rsize)->prev_foot = rsize;
  995. ; insert_large_chunk((tchunkptr)r, rsize);
  996.  
  997.            mov [esi+edi], edi
  998.            mov eax, edi
  999.            mov ecx, esi
  1000.            call insert_chunk
  1001.  
  1002.            lea eax, [ebp+8]
  1003.            add esp, 8
  1004.            pop edi
  1005.            pop esi
  1006.            pop ebp
  1007.            ret
  1008.  
  1009. .done:
  1010.            add esp, 8
  1011.            pop edi
  1012.            pop esi
  1013.            pop ebp
  1014.            xor eax, eax
  1015.            ret
  1016.  
  1017. init_malloc:
  1018.  
  1019.            stdcall kernel_alloc, 0x40000
  1020.  
  1021.            mov [mst.top], eax
  1022.            mov [mst.topsize], 128*1024
  1023.            mov dword [eax+4], (128*1024) or 1
  1024.            mov eax, mst.smallbins
  1025.  
  1026. @@:
  1027.            mov [eax+8], eax
  1028.            mov [eax+12], eax
  1029.            add eax, 16
  1030.            cmp eax, mst.smallbins+512
  1031.            jb @B
  1032.  
  1033.            mov ecx, mst.mutex
  1034.            call mutex_init
  1035.  
  1036.            ret
  1037.  
  1038.