parsav  Diff

Differences From Artifact [de24aef2de]:

To Artifact [7e2b478eaf]:


   179    179   end)
   180    180   
   181    181   struct m.pool {
   182    182    -- implements growable memory pools. EVERY THREAD MUST HAVE ITS OWN
   183    183   	storage: &opaque
   184    184   	cursor: &opaque
   185    185   	sz: intptr
          186  +	debris: &m.pool
   186    187   }
   187    188   
   188    189   terra m.pool:cue(sz: intptr)
   189    190   	if self.storage == nil then
   190    191   		self.storage = m.heapa_raw(sz)
   191    192   		self.cursor = self.storage
   192    193   		self.sz = sz
   193    194   	else
   194    195   		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
          196  +		var oldblock = @self
          197  +		self:init(sz)
          198  +		@self.debris = oldblock
   199    199   	end
   200    200   	return self
   201    201   end
   202    202   
   203    203   terra m.pool:init(sz: intptr)
   204         -	self.storage = nil
   205         -	self:cue(sz)
          204  +	var b = m.heapa_raw(sz + sizeof(m.pool))
          205  +	self.storage = [&uint8](b) + sizeof(m.pool)
          206  +	self.cursor = self.storage
          207  +	self.sz = sz
          208  +	self.debris = [&m.pool](b)
          209  +	self.debris.storage = nil
   206    210   	return self
   207    211   end
   208    212   
   209         -terra m.pool:free()
   210         -	m.heapf(self.storage)
          213  +terra m.pool:free(): {}
          214  +lib.io.fmt('DRAINING POOL %p\n',self.storage)
          215  +	if self.storage == nil then return end
          216  +	if self.debris.storage ~= nil then self.debris:free() end
          217  +	m.heapf(self.debris) -- storage + debris field allocated in one block
   211    218   	self.storage = nil
   212    219   	self.cursor = nil
   213    220   	self.sz = 0
          221  +	self.debris = nil
   214    222   end
   215    223   
   216    224   terra m.pool:clear()
          225  +	if self.debris.storage ~= nil then self.debris:free() end
   217    226   	self.cursor = self.storage
   218    227   	return self
   219    228   end
   220    229   
   221    230   terra m.pool:alloc_bytes(sz: intptr): &opaque
   222    231   	var space = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage))
   223         -	if space < sz then self:cue(space + sz + 256) end
          232  +lib.io.fmt('%p / %p @ allocating %llu bytes in %llu of space\n',self.storage,self.cursor,sz,space)
          233  +	if space < sz then
          234  +lib.dbg('reserving more space')
          235  +		self:cue(space + sz + 256) end
   224    236   	var ptr = self.cursor
   225    237   	self.cursor = [&opaque]([&uint8](self.cursor) + sz)
   226    238   	return ptr
   227    239   end
   228    240   
   229         -m.pool.methods.alloc = macro(function(self,ty,sz)
   230         -	return `[ty](self:alloc_bytes(sizeof(ty) * sz))
          241  +terra m.pool:realloc_bytes(oldptr: &opaque, oldsz: intptr, newsz: intptr): &opaque
          242  +	var space = self.sz - ([&uint8](self.cursor) - [&uint8](self.storage))
          243  +	var cur = [&uint8](self.cursor)
          244  +	if cur - [&uint8](oldptr) == oldsz and newsz - oldsz < space then
          245  +		lib.dbg('moving pool cursor')
          246  +		cur = cur + (newsz - oldsz)
          247  +		self.cursor = [&opaque](cur)
          248  +		return oldptr
          249  +	else
          250  +		lib.dbg('copying pool object')
          251  +		var new = self:alloc_bytes(newsz)
          252  +		m.cpy(new, oldptr, oldsz)
          253  +		return new
          254  +	end
          255  +end
          256  +
          257  +m.pool.methods.alloc = macro(function(self,typ,sz)
          258  + 	local ty = typ:astype()
          259  +	return `[m.ptr(ty)] {
          260  +		ptr = [&ty](self:alloc_bytes(sizeof([ty]) * [sz]));
          261  +		ct = [sz];
          262  +	}
          263  +end)
          264  +
          265  +m.pool.methods.realloc = macro(function(self,ptr,oldsz,newsz)
          266  +	local ty = self.tree.type.type
          267  +	return `[m.ptr(ty)] {
          268  +		ptr = [&ty](self:realloc_bytes(ptr,
          269  +			sizeof(ty) * oldsz,
          270  +			sizeof(ty) * newsz));
          271  +		ct = sz;
          272  +	}
   231    273   end)
   232    274   
   233    275   terra m.pool:frame() -- stack-style linear mgmt
   234    276   	return self.cursor
   235    277   end
   236    278   
   237    279   terra m.pool:reset(frame: &opaque)
   238         -	self.cursor = frame
          280  +	if frame >= self.storage and frame <= self.cursor then
          281  +		self.cursor = frame
          282  +	else -- trying to rewind into a previous block! not possible
          283  +		self.cursor = self.storage
          284  +	end
   239    285   	return self
   240    286   end
   241    287   
   242    288   
   243    289   return m