Subversion Repositories Kolibri OS

Rev

Rev 394 | Blame | Last modification | View Log | Download | RSS feed

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