Subversion Repositories Kolibri OS

Rev

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