Subversion Repositories Kolibri OS

Rev

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

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