Differences From
Artifact [a0c3213659]:
173 173 v.metamethods.__apply = terra(self: &v, idx: intptr): &ty -- no index??
174 174 if self.sz > idx then
175 175 return self.storage.ptr + idx
176 176 else lib.bail('vector overrun!') end
177 177 end
178 178 return v
179 179 end)
180 +
181 +struct m.pool {
182 + -- implements growable memory pools. EVERY THREAD MUST HAVE ITS OWN
183 + storage: &opaque
184 + cursor: &opaque
185 + sz: intptr
186 +}
187 +
188 +terra m.pool:cue(sz: intptr)
189 + if self.storage == nil then
190 + self.storage = m.heapa_raw(sz)
191 + self.cursor = self.storage
192 + self.sz = sz
193 + else
194 + if self.sz >= sz then return self end
195 + var ofs = [&uint8](self.cursor) - [&uint8](self.storage)
196 + self.storage = m.heapr_raw(self.storage, sz)
197 + self.cursor = [&opaque]([&uint8](self.storage) + ofs)
198 + self.sz = sz
199 + end
200 + return self
201 +end
202 +
203 +terra m.pool:init(sz: intptr)
204 + self.storage = nil
205 + self:cue(sz)
206 + return self
207 +end
208 +
209 +terra m.pool:free()
210 + m.heapf(self.storage)
211 + self.storage = nil
212 + self.cursor = nil
213 + self.sz = 0
214 +end
215 +
216 +terra m.pool:clear()
217 + self.cursor = self.storage
218 + return self
219 +end
220 +
221 +terra m.pool:alloc_bytes(sz: intptr): &opaque
222 + var space = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage))
223 + if space < sz then self:cue(space + sz + 256) end
224 + var ptr = self.cursor
225 + self.cursor = [&opaque]([&uint8](self.cursor) + sz)
226 + return ptr
227 +end
228 +
229 +m.pool.methods.alloc = macro(function(self,ty,sz)
230 + return `[ty](self:alloc_bytes(sizeof(ty) * sz))
231 +end)
232 +
233 +terra m.pool:frame() -- stack-style linear mgmt
234 + return self.cursor
235 +end
236 +
237 +terra m.pool:reset(frame: &opaque)
238 + self.cursor = frame
239 + return self
240 +end
241 +
180 242
181 243 return m