Subversion Repositories Kolibri OS

Rev

Rev 1211 | Rev 2129 | 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: 1292 $
  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.            mov [mst.mutex], 0
  139.            ret
  140. .small:
  141.  
  142. ; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
  143. ;;;;;;;;;;; start a change <lrz>
  144.            mov  eax,[mst.treemap]
  145.            test eax,eax
  146. ;;;;;;;;;;; end the change <lrz>
  147. ;           cmp [mst.treemap], 0
  148.            jz .from_top
  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
  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. 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<<I))
  453.            bt [mst.treemap], ecx
  454.            jc .tree
  455.  
  456. ; ms.treemap |= 1<<I;
  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
  594.  
  595. .l3:
  596.            cmp [edi+16], edx
  597.            jne @F
  598.  
  599.            mov [edi+16], eax
  600.            jmp .l4
  601.  
  602. @@:
  603.            mov [edi+20], eax
  604.  
  605. .l4:
  606.            test eax, eax
  607.            je .done
  608.  
  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
  617.  
  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
  625.  
  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
  647.  
  648. .loop:
  649.            mov ebx, ecx
  650.  
  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
  660.  
  661. @@:
  662.            mov ecx, [ecx+20]
  663.  
  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
  714.  
  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
  747.  
  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
  767.            push edi
  768.            sub esp, 8
  769. ; v = 0;
  770. ; rsize = -nb;
  771.  
  772.            mov edi, esi
  773.            mov ebx, esi
  774.            xor ebp, ebp
  775.            neg edi
  776.  
  777. ; idx = compute_tree_index(nb);
  778.  
  779.            mov edx, esi
  780.            shr edx, 8
  781.            bsr eax, edx
  782.            lea ecx, [eax+7]
  783.            shr esi, cl
  784.            and esi, 1
  785.            lea ecx, [esi+eax*2]
  786.            mov [.idx], ecx
  787.  
  788. ; if ((t = ms.treebins[idx]) != 0)
  789.  
  790.            mov eax, [mst.treebins+ecx*4]
  791.            test eax, eax
  792.            jz .l3
  793.  
  794. ; sizebits = nb << leftshift_for_tree_index(idx);
  795.  
  796.            cmp ecx, 31
  797.            jne @F
  798.            xor ecx, ecx
  799.            jmp .l1
  800.  
  801. @@:
  802.            mov edx, ecx
  803.            shr edx, 1
  804.            mov ecx, 37
  805.            sub ecx, edx
  806.  
  807. .l1:
  808.            mov edx, ebx
  809.            shl edx, cl
  810.  
  811. ; rst = 0;
  812.            mov [.rst], ebp
  813.  
  814. .loop:
  815.  
  816. ; trem = (t->head & ~INUSE_BITS) - nb;
  817.  
  818.            mov ecx, [eax+4]
  819.            and ecx, -4
  820.            sub ecx, ebx
  821.  
  822. ; if (trem < rsize)
  823.  
  824.            cmp ecx, edi
  825.            jae @F
  826. ; v = t;
  827. ; if ((rsize = trem) == 0)
  828.  
  829.            test ecx, ecx
  830.            mov ebp, eax
  831.            mov edi, ecx
  832.            je .l2
  833.  
  834. @@:
  835.  
  836. ; rt = t->child[1];
  837.  
  838.            mov ecx, [eax+20]
  839.  
  840. ; t = t->child[(sizebits >> 31) & 1];
  841.  
  842.            mov esi, edx
  843.            shr esi, 31
  844.  
  845. ; if (rt != 0 && rt != t)
  846.  
  847.            test ecx, ecx
  848.            mov eax, [eax+esi*4+16]
  849.            jz @F
  850.            cmp ecx, eax
  851.            jz @F
  852.  
  853. ; rst = rt;
  854.            mov [.rst], ecx
  855.  
  856. @@:
  857. ; if (t == 0)
  858.  
  859.            test eax, eax
  860.            jz @F
  861.  
  862. ; sizebits <<= 1;
  863.  
  864.            add edx, edx
  865.            jmp .loop
  866.  
  867. @@:
  868. ; t = rst;
  869.            mov eax, [.rst]
  870.  
  871. .l2:
  872. ; if (t == 0 && v == 0)
  873.  
  874.            test eax, eax
  875.            jne .l4
  876.            test ebp, ebp
  877.            jne .l7
  878.            mov ecx, [.idx]
  879.  
  880. .l3:
  881.  
  882. ; leftbits = (-1<<idx) & ms.treemap;
  883. ; if (leftbits != 0)
  884.  
  885.            or edx, -1
  886.            shl edx, cl
  887.            and edx, [mst.treemap]
  888.            jz @F
  889.  
  890.            bsf eax, edx
  891. ; t = ms.treebins[i];
  892.            mov eax, [mst.treebins+eax*4]
  893.  
  894. @@:
  895.  
  896. ; while (t != 0)
  897.            test eax, eax
  898.            jz .l5
  899.  
  900. .l4:
  901.  
  902. ; trem = (t->head & ~INUSE_BITS) - nb;
  903.  
  904.            mov ecx, [eax+4]
  905.            and ecx, -4
  906.            sub ecx, ebx
  907.  
  908. ; if (trem < rsize)
  909.  
  910.            cmp ecx, edi
  911.            jae @F
  912. ; rsize = trem;
  913.  
  914.            mov edi, ecx
  915. ; v = t;
  916.            mov ebp, eax
  917.  
  918. @@:
  919.  
  920. ; t = leftmost_child(t);
  921.  
  922.            mov ecx, [eax+16]
  923.            test ecx, ecx
  924.            je @F
  925.            mov eax, ecx
  926.            jmp .l6
  927.  
  928. @@:
  929.            mov eax, [eax+20]
  930.  
  931. .l6:
  932.  
  933. ; while (t != 0)
  934.  
  935.            test eax, eax
  936.            jne .l4
  937.  
  938. .l5:
  939.  
  940. ; if (v != 0)
  941.  
  942.            test ebp, ebp
  943.            jz .done
  944.  
  945. .l7:
  946.  
  947. ; r = chunk_plus_offset((mchunkptr)v, nb);
  948. ; unlink_large_chunk(v);
  949.  
  950.            mov edx, ebp
  951.            lea esi, [ebx+ebp]
  952.            call unlink_large_chunk
  953.  
  954. ; if (rsize < 16)
  955.  
  956.            cmp edi, 16
  957.            jae .large
  958.  
  959. ; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
  960.  
  961.            lea ecx, [edi+ebx]
  962.  
  963. ; (v+rsize + nb)->head |= PINUSE_BIT;
  964.  
  965.            add edi, ebp
  966.            lea eax, [edi+ebx+4]
  967.            or ecx, 3
  968.            mov [ebp+4], ecx
  969.            or dword [eax], 1
  970.            lea eax, [ebp+8]
  971.            add esp, 8
  972.            pop edi
  973.            pop ebp
  974.            ret
  975.  
  976. .large:
  977.  
  978. ; v->head = nb|PINUSE_BIT|CINUSE_BIT;
  979. ; r->head = rsize|PINUSE_BIT;
  980.  
  981.            mov edx, edi
  982.            or ebx, 3
  983.            mov [ebp+4], ebx
  984.            or edx, 1
  985.            mov [esi+4], edx
  986.  
  987. ; (r+rsize)->prev_foot = rsize;
  988. ; insert_large_chunk((tchunkptr)r, rsize);
  989.  
  990.            mov [esi+edi], edi
  991.            mov eax, edi
  992.            mov ecx, esi
  993.            call insert_chunk
  994.  
  995.            lea eax, [ebp+8]
  996.            add esp, 8
  997.            pop edi
  998.            pop ebp
  999.            ret
  1000.  
  1001. .done:
  1002.            add esp, 8
  1003.            pop edi
  1004.            pop ebp
  1005.            xor eax, eax
  1006.            ret
  1007.  
  1008. init_malloc:
  1009.  
  1010.            stdcall kernel_alloc, 0x40000
  1011.  
  1012.            mov [mst.top], eax
  1013.            mov [mst.topsize], 128*1024
  1014.            mov dword [eax+4], (128*1024) or 1
  1015.            mov eax, mst.smallbins
  1016.  
  1017. @@:
  1018.            mov [eax+8], eax
  1019.            mov [eax+12], eax
  1020.            add eax, 16
  1021.            cmp eax, mst.smallbins+512
  1022.            jb @B
  1023.  
  1024.            ret
  1025.  
  1026.