Subversion Repositories Kolibri OS

Rev

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