Subversion Repositories Kolibri OS

Rev

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