Class: Malloc
Constant Summary collapse
- @@base =
empty list to get started
Header.new
- @@freep =
start of free list
0.cast_to(:Header)
Class Method Summary collapse
-
.free(ap) ⇒ Object
Free memory block.
-
.malloc(nbytes) ⇒ Object
malloc: allocate n bytes of memory and return pointer to data block.
-
.morecore(nu) ⇒ Object
morecore: ask system for more memory.
Class Method Details
.free(ap) ⇒ Object
Free memory block
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rlang/lib/malloc.rb', line 126 def self.free(ap) arg ap: :UI32 result :none local bp: :Header, p: :Header # NULL is a special value used for # all Rlag object instances that doesn't # have any instance variables and therefore # doesn't use any memory return if ap == 0 bp = ap.cast_to(:Header) - 1 # point to block header p = @@freep while !(bp > p && bp < p.ptr) # freed block at start or end of arena break if (p >= p.ptr && (bp > p || bp < p.ptr)) p = p.ptr end if (bp + bp.size == p.ptr) # join to upper nbr bp.size += p.ptr.size bp.ptr = p.ptr.ptr else bp.ptr = p.ptr end if (p + p.size == bp) # join to lower nbr p.size += bp.size p.ptr = bp.ptr else p.ptr = bp end @@freep = p end |
.malloc(nbytes) ⇒ Object
malloc: allocate n bytes of memory and return pointer to data block
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/rlang/lib/malloc.rb', line 57 def self.malloc(nbytes) arg nbytes: :UI32 local p: :Header, prevp: :Header, nunits: :UI32 # allocate memory by chunk of units (the unit is # the size of a Header object here) # units = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1; nunits = (nbytes + Header._size_ - 1) / Header._size_ + 1 # No free list yet. Initialize it. if (prevp = @@freep) == 0 @@base.ptr = @@freep = prevp = @@base @@base.size = 0 end # scan the free list for a big enough free block # (first in list is taken) p = prevp.ptr while true if (p.size >= nunits) # big enough if (p.size == nunits) # exactly the requested size prevp.ptr = p.ptr else # bigger free block found # Allocate tail end p.size -= nunits p += p.size p.size = nunits end @@freep = prevp # TODO: we should actually cast to default WASM type return (p + 1).cast_to(:I32) end # wrapped around free list if p == @@freep if (p = self.morecore(nunits)) == 0 return 0 end end prevp = p; p = p.ptr end # Rlang specific: remember that while construct # doesn't evaluate to a value so we must add an # explicit return here. # However we should **never** get there so return NULL return 0 end |
.morecore(nu) ⇒ Object
morecore: ask system for more memory
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/rlang/lib/malloc.rb', line 110 def self.morecore(nu) arg nu: :UI32 result :Header local up: :Header nu = $NALLOC if nu < $NALLOC cp = Unistd::sbrk(nu * Header._size_) return 0 if cp == -1 # no space at all up = cp.cast_to(:Header) up.size = nu self.free((up + 1).to_I32) return @@freep end |