Subversion Repositories Kolibri OS

Rev

Rev 425 | Go to most recent revision | Blame | Compare with Previous | 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.            or eax, -1
  31.            shl eax, cl
  32.            and eax, [mst.smallmap]
  33.            jz .small
  34.  
  35.            push ebp
  36.            push edi
  37.  
  38.            bsf eax, eax
  39.            mov ebx, eax
  40.  
  41. ; psize= idx<<3;
  42. ; B = &ms.smallbins[idx];
  43. ; p = B->fd;
  44. ; F = p->fd;
  45. ; rsize= psize-nb;
  46.  
  47.            lea ebp, [eax*8]               ;ebp= psize
  48.            shl eax, 4
  49.            lea edi, [mst.smallbins+eax]   ;edi= B
  50.            mov edx, [edi+8]               ;edx= p
  51.            mov eax, [edx+8]               ;eax= F
  52.            mov ecx, ebp
  53.            sub ecx, esi                   ;ecx= rsize
  54.  
  55. ; if (B == F)
  56.            cmp edi, eax
  57.            jne @F
  58.  
  59.            btr [mst.smallmap], ebx
  60. @@:
  61.  
  62. ; B->fd = F;
  63. ; F->bk = B;
  64. ; if(rsize<16)
  65.  
  66.            cmp ecx, 16
  67.            mov [edi+8], eax
  68.            mov [eax+12], edi
  69.            jae .split
  70.  
  71. ; p->head = psize|PINUSE_BIT|CINUSE_BIT;
  72. ; (p + psize)->head |= PINUSE_BIT;
  73.  
  74.            lea eax, [edx+8]
  75.            or dword [edx+ebp+4], 1
  76.  
  77.            or ebp, 3
  78.            mov [edx+4], ebp
  79.  
  80.            pop edi
  81.            pop ebp
  82. .done:
  83.            pop esi
  84.            mov [mst.mutex], 0
  85.            ret
  86. .split:
  87.            lea ebx, [edx+8]               ;ebx=mem
  88.  
  89. ; r = chunk_plus_offset(p, nb);
  90. ; p->head = nb|PINUSE_BIT|CINUSE_BIT;
  91. ; r->head = rsize|PINUSE_BIT;
  92.  
  93.            lea eax, [edx+esi]             ;eax= r
  94.            or esi, 3
  95.            mov [edx+4], esi
  96.  
  97.            mov edx, ecx
  98.            or edx, 1
  99.            mov [eax+4], edx
  100.  
  101. ; (r + rsize)->prev_foot = rsize;
  102.  
  103.            mov [eax+ecx], ecx
  104.  
  105. ; I  = rsize>>3;
  106.  
  107.            shr ecx, 3
  108.  
  109. ;      ms.smallmap |=  1<< I;
  110.            bts [mst.smallmap], ecx
  111.  
  112. ; B = &ms.smallbins[I];
  113.  
  114.            shl ecx, 4
  115.            pop edi
  116.            pop ebp
  117.            add ecx, mst.smallbins         ;ecx= B
  118.  
  119.            mov edx, [ecx+8]               ; F = B->fd;
  120.            mov [ecx+8], eax               ; B->fd = r;
  121.            mov [edx+12], eax              ; F->bk = r;
  122.            mov [eax+8], edx               ; r->fd = F;
  123.            mov [eax+12], ecx              ; r->bk = B;
  124.            mov eax, ebx
  125.            pop esi
  126.            ret
  127. .small:
  128.  
  129. ; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
  130.  
  131.            cmp [mst.treemap], 0
  132.            je .from_top
  133.            mov eax, esi
  134.            call malloc_small
  135.            test eax, eax
  136.            jz .from_top
  137.            pop esi
  138.            and [mst.mutex], 0
  139.            ret
  140. .large:
  141.  
  142. ; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
  143.  
  144.            cmp [mst.treemap], 0
  145.            je .from_top
  146.  
  147.            call malloc_large  ;esi= nb
  148.            test eax, eax
  149.            jne .done
  150. .from_top:
  151.  
  152. ; if (nb < ms.topsize)
  153.  
  154.            mov eax, [mst.topsize]
  155.            cmp esi, eax
  156.            jae .fail
  157.  
  158. ; rsize = ms.topsize -= nb;
  159. ; p = ms.top;
  160.  
  161.            mov ecx, [mst.top]
  162.            sub eax, esi
  163.            mov [mst.topsize], eax
  164.  
  165. ; r = ms.top = chunk_plus_offset(p, nb);
  166. ; r->head = rsize | PINUSE_BIT;
  167. ; p->head = nb |PINUSE_BIT|CINUSE_BIT;
  168.  
  169.            lea edx, [ecx+esi]
  170.            or eax, 1
  171.            mov [mst.top], edx
  172.            or esi, 3
  173.            mov [edx+4], eax
  174.            mov [ecx+4], esi
  175.            lea eax, [ecx+8]
  176.            pop esi
  177.            and [mst.mutex], 0
  178.            ret
  179. .fail:
  180.            xor eax, eax
  181.            pop esi
  182.            and [mst.mutex], 0
  183.            ret
  184.  
  185. ; param
  186. ;  eax= mem
  187.  
  188. align 4
  189. free:
  190.            push edi
  191.            mov edi, eax
  192.            add edi, -8
  193.  
  194. ; if(p->head & CINUSE_BIT)
  195.  
  196.            test byte [edi+4], 2
  197.            je .fail
  198.  
  199.            mov ebx, mst.mutex
  200.            call wait_mutex    ;ebx
  201.  
  202. ; psize = p->head & (~3);
  203.  
  204.            mov eax, [edi+4]
  205.            push esi
  206.            mov esi, eax
  207.            and esi, -4
  208.  
  209. ; next = chunk_plus_offset(p, psize);
  210. ; if(!(p->head & PINUSE_BIT))
  211.  
  212.            test al, 1
  213.            lea ebx, [esi+edi]
  214.            jne .next
  215.  
  216. ; prevsize = p->prev_foot;
  217. ; prev=p - prevsize;
  218. ; psize += prevsize;
  219. ; p = prev;
  220.  
  221.            mov ecx, [edi]  ;ecx= prevsize
  222.            add esi, ecx              ;esi= psize
  223.            sub edi, ecx              ;edi= p
  224.  
  225. ; if (prevsize < 256)
  226.  
  227.            cmp ecx, 256
  228.            jae .unlink_large
  229.  
  230.            mov eax, [edi+8]          ;F = p->fd;
  231.            mov edx, [edi+12]         ;B = p->bk;
  232.  
  233. ; if (F == B)
  234. ; ms.smallmap &=  ~(1<< I);
  235.            shr ecx, 3
  236.            cmp eax, edx
  237.            jne @F
  238.            and [mst.smallmap], ecx
  239. @@:
  240.            mov [eax+12], edx           ;F->bk = B;
  241.            mov [edx+8], eax            ;B->fd = F
  242.            jmp .next
  243. .unlink_large:
  244.            mov edx, edi
  245.            call unlink_large_chunk
  246. .next:
  247.  
  248. ; if(next->head & PINUSE_BIT)
  249.  
  250.            mov eax, [ebx+4]
  251.            test al, 1
  252.            jz .fail2
  253.  
  254. ; if (! (next->head & CINUSE_BIT))
  255.  
  256.            test al, 2
  257.            jnz .fix_next
  258.  
  259. ; if (next == ms.top)
  260.  
  261.            cmp ebx, [mst.top]
  262.            jne @F
  263.  
  264. ; tsize = ms.topsize += psize;
  265.  
  266.            mov eax, [mst.topsize]
  267.            add eax, esi
  268.            mov [mst.topsize], eax
  269.  
  270. ; ms.top = p;
  271. ; p->head = tsize | PINUSE_BIT;
  272.  
  273.            or eax, 1
  274.            mov [mst.top], edi
  275.            mov [edi+4], eax
  276. .fail2:
  277.            and [mst.mutex], 0
  278.            pop esi
  279. .fail:
  280.            pop edi
  281.            ret
  282. @@:
  283.  
  284. ; nsize = next->head & ~INUSE_BITS;
  285.  
  286.            and eax, -4
  287.            add esi, eax                ;psize += nsize;
  288.  
  289. ; if (nsize < 256)
  290.  
  291.            cmp eax, 256
  292.            jae .unl_large
  293.  
  294.            mov edx, [ebx+8]            ;F = next->fd
  295.            mov ebx, [ebx+12]           ;B = next->bk
  296.  
  297. ; if (F == B)
  298.  
  299.            cmp edx, ebx
  300.            jne @F
  301.            mov ecx, eax
  302.            shr ecx, 3
  303.            btr [mst.smallmap], ecx
  304. @@:
  305.            mov [edx+12], ebx           ;F->bk = B
  306.  
  307. ; p->head = psize|PINUSE_BIT;
  308.  
  309.            mov ecx, esi
  310.            mov [ebx+8], edx
  311.            or ecx, 1
  312.            mov [edi+4], ecx
  313.  
  314. ; (p+psize)->prev_foot = psize;
  315.  
  316.            mov [esi+edi], esi
  317.  
  318. ; insert_chunk(p,psize);
  319.  
  320.            mov eax, esi
  321.            pop esi
  322.            mov ecx, edi
  323.            pop edi
  324.            jmp insert_chunk
  325. .unl_large:
  326.  
  327. ; unlink_large_chunk((tchunkptr)next);
  328.  
  329.            mov edx, ebx
  330.            call unlink_large_chunk
  331. ; p->head = psize|PINUSE_BIT;
  332.  
  333.            mov ecx, esi
  334.            or ecx, 1
  335.            mov [edi+4], ecx
  336.  
  337. ; (p+psize)->prev_foot = psize;
  338.  
  339.            mov [esi+edi], esi
  340.  
  341. ; insert_chunk(p,psize);
  342.  
  343.            mov eax, esi
  344.            pop esi
  345.            mov ecx, edi
  346.            pop edi
  347.            jmp insert_chunk
  348. .fix_next:
  349.  
  350. ; (p+psize)->prev_foot = psize;
  351. ; next->head &= ~PINUSE_BIT;
  352. ; p->head = psize|PINUSE_BIT;
  353.  
  354.            and eax, -2
  355.            mov edx, esi
  356.            mov [ebx+4], eax
  357.            or edx, 1
  358.            mov [edi+4], edx
  359.  
  360. ; (p+psize)->prev_foot = psize;
  361.  
  362.            mov [esi+edi], esi
  363. ; insert_chunk(p,psize);
  364.  
  365.            mov eax, esi
  366.            pop esi
  367.            mov ecx, edi
  368.            pop edi
  369.            jmp insert_chunk
  370.  
  371. ; param
  372. ;  ecx = chunk
  373. ;  eax = size
  374.  
  375. align 4
  376. insert_chunk:
  377.  
  378.            cmp eax, 256
  379.            push esi
  380.            mov esi, ecx
  381.            jae .large
  382.  
  383. ; I  = S>>3;
  384. ; ms.smallmap |=  1<< I;
  385.  
  386.            shr eax, 3
  387.            bts [mst.smallmap], eax
  388.  
  389. ; B = &ms.smallbins[I];
  390.  
  391.            shl eax, 4
  392.            add eax, mst.smallbins
  393.            mov edx, [eax+8]            ;F = B->fd
  394.            mov [eax+8], esi            ;B->fd = P
  395.            mov [edx+12], esi           ;F->bk = P
  396.            mov [esi+8], edx            ;P->fd = F
  397.            mov [esi+12], eax           ;P->bk = B
  398.            pop esi
  399.            and [mst.mutex], 0
  400.            ret
  401. .large:
  402.            mov ebx, eax
  403.            call insert_large_chunk
  404.            pop esi
  405.            and [mst.mutex], 0
  406.            ret
  407.  
  408. align 4
  409.  
  410. ; param
  411. ;  esi= chunk
  412. ;  ebx= size
  413.  
  414. align 4
  415. insert_large_chunk:
  416.  
  417. ; I = compute_tree_index(S);
  418.  
  419.            mov edx, ebx
  420.            shr edx, 8
  421.            bsr eax, edx
  422.            lea ecx, [eax+7]
  423.            mov edx, ebx
  424.            shr edx, cl
  425.            and edx, 1
  426.            lea ecx, [edx+eax*2]
  427.  
  428. ; X->index = I;
  429.            mov dword [esi+28], ecx
  430.  
  431. ; X->child[0] = X->child[1] = 0;
  432.            and dword [esi+20], 0
  433.            and dword [esi+16], 0
  434.  
  435. ; H = &ms.treebins[I];
  436.  
  437.            mov eax, ecx
  438.            lea edx, [mst.treebins+eax*4]
  439.  
  440. ; if (!(ms.treemap & 1<<I))
  441.            bt [mst.treemap], ecx
  442.            jc .tree
  443.  
  444. ; ms.treemap |= 1<<I;
  445.            bts [mst.treemap], ecx
  446. ; *H = X;
  447.            mov dword [edx], esi
  448.            jmp .done
  449. .tree:
  450.  
  451. ; T = *H;
  452.            mov edx, [edx]
  453.  
  454. ; K = S << leftshift_for_tree_index(I);
  455.            mov eax, ecx
  456.            shr eax, 1
  457.            sub ecx, 31
  458.            mov edi, 37
  459.            sub edi, eax
  460.            neg ecx
  461.            sbb ecx, ecx
  462.            and ecx, edi
  463.            mov eax, ebx
  464.            shl eax, cl     ;eax= K
  465.  
  466.            jmp .loop
  467.  
  468. .not_eq_size:
  469.  
  470. ; C = &(T->child[(K >> 31) & 1]);
  471.            mov ecx, eax
  472.            shr ecx, 31
  473.            lea ecx, [edx+ecx*4+16]
  474.  
  475. ; K <<= 1;
  476. ; if (*C != 0)
  477.            mov edi, [ecx]
  478.            add eax, eax
  479.            test edi, edi
  480.            jz .insert_child
  481.  
  482. ; T = *C;
  483.            mov edx, edi
  484. .loop:
  485.  
  486. ; for (;;)
  487. ; if ((T->head & ~INUSE_BITS) != S)
  488.  
  489.            mov ecx, [edx+4]
  490.            and ecx, not 3
  491.            cmp ecx, ebx
  492.            jne .not_eq_size
  493.  
  494. ; F = T->fd;
  495.            mov eax, [edx+8]
  496.  
  497. ; T->fd = F->bk = X;
  498.            mov [eax+12], esi
  499.            mov [edx+8], esi
  500.  
  501. ; X->fd = F;
  502. ; X->bk = T;
  503. ; X->parent = 0;
  504.  
  505.            and dword [esi+24], 0
  506.            mov [esi+8], eax
  507.            mov [esi+12], edx
  508.            ret
  509.  
  510. .insert_child:
  511.  
  512. ; *C = X;
  513.            mov [ecx], esi
  514. .done:
  515.  
  516. ; X->parent = T;
  517.            mov [esi+24], edx
  518.  
  519. ; X->fd = X->bk = X;
  520.            mov [esi+12], esi
  521.            mov [esi+8], esi
  522.            ret
  523.  
  524.  
  525. ; param
  526. ;  edx= chunk
  527.  
  528. align 4
  529. unlink_large_chunk:
  530.  
  531.            mov eax, [edx+12]
  532.            cmp eax, edx
  533.            push edi
  534.            mov edi, [edx+24]
  535.            je @F
  536.  
  537.            mov ecx, [edx+8]           ;F = X->fd
  538.            mov [ecx+12], eax          ;F->bk = R;
  539.            mov [eax+8], ecx           ;R->fd = F
  540.            jmp .parent
  541. @@:
  542.            mov eax, [edx+20]
  543.            test eax, eax
  544.            push esi
  545.            lea esi, [edx+20]
  546.            jne .loop
  547.  
  548.            mov eax, [edx+16]
  549.            test eax, eax
  550.            lea esi, [edx+16]
  551.            je .l2
  552. .loop:
  553.            cmp dword [eax+20], 0
  554.            lea ecx, [eax+20]
  555.            jne @F
  556.  
  557.            cmp dword [eax+16], 0
  558.            lea ecx, [eax+16]
  559.            je .l1
  560. @@:
  561.            mov eax, [ecx]
  562.            mov esi, ecx
  563.            jmp .loop
  564. .l1:
  565.            mov dword [esi], 0
  566. .l2:
  567.            pop esi
  568. .parent:
  569.            test edi, edi
  570.            je .done
  571.  
  572.            mov ecx, [edx+28]
  573.            cmp edx, [mst.treebins+ecx*4]
  574.            lea ecx, [mst.treebins+ecx*4]
  575.            jne .l3
  576.  
  577.            test eax, eax
  578.            mov [ecx], eax
  579.            jne .l5
  580.  
  581.            mov ecx, [edx+28]
  582.            btr [mst.treemap], ecx
  583.            pop edi
  584.            ret
  585. .l3:
  586.            cmp [edi+16], edx
  587.            jne @F
  588.  
  589.            mov [edi+16], eax
  590.            jmp .l4
  591. @@:
  592.            mov [edi+20], eax
  593. .l4:
  594.            test eax, eax
  595.            je .done
  596. .l5:
  597.            mov [eax+24], edi
  598.            mov ecx, [edx+16]
  599.            test ecx, ecx
  600.            je .l6
  601.  
  602.            mov [eax+16], ecx
  603.            mov [ecx+24], eax
  604. .l6:
  605.            mov edx, [edx+20]
  606.            test edx, edx
  607.            je .done
  608.  
  609.            mov [eax+20], edx
  610.            mov [edx+24], eax
  611. .done:
  612.            pop edi
  613.            ret
  614.  
  615. ; param
  616. ;  esi= nb
  617.  
  618. align 4
  619. malloc_small:
  620.            push ebp
  621.            mov ebp, esi
  622.  
  623.            push edi
  624.  
  625.            bsf eax,[mst.treemap]
  626.            mov ecx, [mst.treebins+eax*4]
  627.  
  628. ; rsize = (t->head & ~INUSE_BITS) - nb;
  629.  
  630.            mov edi, [ecx+4]
  631.            and edi, -4
  632.            sub edi, esi
  633. .loop:
  634.            mov ebx, ecx
  635. .loop_1:
  636.  
  637. ; while ((t = leftmost_child(t)) != 0)
  638.  
  639.            mov eax, [ecx+16]
  640.            test eax, eax
  641.            jz @F
  642.            mov ecx, eax
  643.            jmp .l1
  644. @@:
  645.            mov ecx, [ecx+20]
  646. .l1:
  647.            test ecx, ecx
  648.            jz .unlink
  649.  
  650. ; trem = (t->head & ~INUSE_BITS) - nb;
  651.  
  652.            mov eax, [ecx+4]
  653.            and eax, -4
  654.            sub eax, ebp
  655.  
  656. ; if (trem < rsize)
  657.  
  658.            cmp eax, edi
  659.            jae .loop_1
  660.  
  661. ; rsize = trem;
  662.  
  663.            mov edi, eax
  664.            jmp .loop
  665. .unlink:
  666.  
  667.  
  668. ; r = chunk_plus_offset((mchunkptr)v, nb);
  669. ; unlink_large_chunk(v);
  670.  
  671.            mov edx, ebx
  672.            lea esi, [ebx+ebp]
  673.            call unlink_large_chunk
  674.  
  675. ; if (rsize < 16)
  676.  
  677.            cmp edi, 16
  678.            jae .split
  679.  
  680. ; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
  681.  
  682.            lea ecx, [edi+ebp]
  683.  
  684. ; (v+rsize + nb)->head |= PINUSE_BIT;
  685.  
  686.            add edi, ebx
  687.            lea eax, [edi+ebp+4]
  688.            pop edi
  689.            or ecx, 3
  690.            pop esi
  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 < 256)
  922.  
  923.            cmp edi, 256
  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 ebx, edi
  958.            call insert_large_chunk
  959.  
  960.            lea eax, [ebp+8]
  961.            add esp, 8
  962.            pop edi
  963.            pop ebp
  964.            ret
  965. .done:
  966.            add esp, 8
  967.            pop edi
  968.            pop ebp
  969.            xor eax, eax
  970.            ret
  971.  
  972. align 4
  973. init_malloc:
  974.  
  975.            stdcall kernel_alloc, 0x20000
  976.  
  977.            mov [mst.top], eax
  978.            mov [mst.topsize], 128*1024
  979.            mov dword [eax+4], (128*1024) or 1
  980.            mov eax, mst.smallbins
  981. @@:
  982.            mov [eax+8], eax
  983.            mov [eax+12], eax
  984.            add eax, 16
  985.            cmp eax, mst.smallbins+512
  986.            jl @B
  987.  
  988.            ret
  989.  
  990.  
  991.  
  992.  
  993.