273 retTL == retTL->parent()->left() ||
274 retTL == retTL->parent()->right(),
275 "list is inconsistent");
276 )
277 retTL->decrement_count();
278
279 assert(tc->is_free(), "Should still be a free chunk");
280 assert(retTL->head() == NULL || retTL->head()->prev() == NULL,
281 "list invariant");
282 assert(retTL->tail() == NULL || retTL->tail()->next() == NULL,
283 "list invariant");
284 return retTL;
285 }
286
287 template <class Chunk_t, template <class> class FreeList_t>
288 void TreeList<Chunk_t, FreeList_t>::return_chunk_at_tail(TreeChunk<Chunk_t, FreeList_t>* chunk) {
289 assert(chunk != NULL, "returning NULL chunk");
290 assert(chunk->list() == this, "list should be set for chunk");
291 assert(tail() != NULL, "The tree list is embedded in the first chunk");
292 // which means that the list can never be empty.
293 assert(!verify_chunk_in_free_list(chunk), "Double entry");
294 assert(head() == NULL || head()->prev() == NULL, "list invariant");
295 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
296
297 Chunk_t* fc = tail();
298 fc->link_after(chunk);
299 this->link_tail(chunk);
300
301 assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list");
302 FreeList_t<Chunk_t>::increment_count();
303 debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
304 assert(head() == NULL || head()->prev() == NULL, "list invariant");
305 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
306 }
307
308 // Add this chunk at the head of the list. "At the head of the list"
309 // is defined to be after the chunk pointer to by head(). This is
310 // because the TreeList<Chunk_t, FreeList_t> is embedded in the first TreeChunk<Chunk_t, FreeList_t> in the
311 // list. See the definition of TreeChunk<Chunk_t, FreeList_t>.
312 template <class Chunk_t, template <class> class FreeList_t>
313 void TreeList<Chunk_t, FreeList_t>::return_chunk_at_head(TreeChunk<Chunk_t, FreeList_t>* chunk) {
314 assert(chunk->list() == this, "list should be set for chunk");
315 assert(head() != NULL, "The tree list is embedded in the first chunk");
316 assert(chunk != NULL, "returning NULL chunk");
317 assert(!verify_chunk_in_free_list(chunk), "Double entry");
318 assert(head() == NULL || head()->prev() == NULL, "list invariant");
319 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
320
321 Chunk_t* fc = head()->next();
322 if (fc != NULL) {
323 chunk->link_after(fc);
324 } else {
325 assert(tail() == NULL, "List is inconsistent");
326 this->link_tail(chunk);
327 }
328 head()->link_after(chunk);
329 assert(!head() || size() == head()->size(), "Wrong sized chunk in list");
330 FreeList_t<Chunk_t>::increment_count();
331 debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
332 assert(head() == NULL || head()->prev() == NULL, "list invariant");
333 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
334 }
335
336 template <class Chunk_t, template <class> class FreeList_t>
337 void TreeChunk<Chunk_t, FreeList_t>::assert_is_mangled() const {
338 assert((ZapUnusedHeapArea &&
339 SpaceMangler::is_mangled((HeapWord*) Chunk_t::size_addr()) &&
340 SpaceMangler::is_mangled((HeapWord*) Chunk_t::prev_addr()) &&
341 SpaceMangler::is_mangled((HeapWord*) Chunk_t::next_addr())) ||
342 (size() == 0 && prev() == NULL && next() == NULL),
343 "Space should be clear or mangled");
344 }
345
346 template <class Chunk_t, template <class> class FreeList_t>
347 TreeChunk<Chunk_t, FreeList_t>* TreeList<Chunk_t, FreeList_t>::head_as_TreeChunk() {
348 assert(head() == NULL || (TreeChunk<Chunk_t, FreeList_t>::as_TreeChunk(head())->list() == this),
349 "Wrong type of chunk?");
350 return TreeChunk<Chunk_t, FreeList_t>::as_TreeChunk(head());
351 }
|
273 retTL == retTL->parent()->left() ||
274 retTL == retTL->parent()->right(),
275 "list is inconsistent");
276 )
277 retTL->decrement_count();
278
279 assert(tc->is_free(), "Should still be a free chunk");
280 assert(retTL->head() == NULL || retTL->head()->prev() == NULL,
281 "list invariant");
282 assert(retTL->tail() == NULL || retTL->tail()->next() == NULL,
283 "list invariant");
284 return retTL;
285 }
286
287 template <class Chunk_t, template <class> class FreeList_t>
288 void TreeList<Chunk_t, FreeList_t>::return_chunk_at_tail(TreeChunk<Chunk_t, FreeList_t>* chunk) {
289 assert(chunk != NULL, "returning NULL chunk");
290 assert(chunk->list() == this, "list should be set for chunk");
291 assert(tail() != NULL, "The tree list is embedded in the first chunk");
292 // which means that the list can never be empty.
293 assert(! this->verify_chunk_in_free_list(chunk), "Double entry");
294 assert(head() == NULL || head()->prev() == NULL, "list invariant");
295 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
296
297 Chunk_t* fc = tail();
298 fc->link_after(chunk);
299 this->link_tail(chunk);
300
301 assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list");
302 FreeList_t<Chunk_t>::increment_count();
303 debug_only(this->increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
304 assert(head() == NULL || head()->prev() == NULL, "list invariant");
305 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
306 }
307
308 // Add this chunk at the head of the list. "At the head of the list"
309 // is defined to be after the chunk pointer to by head(). This is
310 // because the TreeList<Chunk_t, FreeList_t> is embedded in the first TreeChunk<Chunk_t, FreeList_t> in the
311 // list. See the definition of TreeChunk<Chunk_t, FreeList_t>.
312 template <class Chunk_t, template <class> class FreeList_t>
313 void TreeList<Chunk_t, FreeList_t>::return_chunk_at_head(TreeChunk<Chunk_t, FreeList_t>* chunk) {
314 assert(chunk->list() == this, "list should be set for chunk");
315 assert(head() != NULL, "The tree list is embedded in the first chunk");
316 assert(chunk != NULL, "returning NULL chunk");
317 assert(! this->verify_chunk_in_free_list(chunk), "Double entry");
318 assert(head() == NULL || head()->prev() == NULL, "list invariant");
319 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
320
321 Chunk_t* fc = head()->next();
322 if (fc != NULL) {
323 chunk->link_after(fc);
324 } else {
325 assert(tail() == NULL, "List is inconsistent");
326 this->link_tail(chunk);
327 }
328 head()->link_after(chunk);
329 assert(!head() || size() == head()->size(), "Wrong sized chunk in list");
330 FreeList_t<Chunk_t>::increment_count();
331 debug_only(this->increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
332 assert(head() == NULL || head()->prev() == NULL, "list invariant");
333 assert(tail() == NULL || tail()->next() == NULL, "list invariant");
334 }
335
336 template <class Chunk_t, template <class> class FreeList_t>
337 void TreeChunk<Chunk_t, FreeList_t>::assert_is_mangled() const {
338 assert((ZapUnusedHeapArea &&
339 SpaceMangler::is_mangled((HeapWord*) Chunk_t::size_addr()) &&
340 SpaceMangler::is_mangled((HeapWord*) Chunk_t::prev_addr()) &&
341 SpaceMangler::is_mangled((HeapWord*) Chunk_t::next_addr())) ||
342 (size() == 0 && prev() == NULL && next() == NULL),
343 "Space should be clear or mangled");
344 }
345
346 template <class Chunk_t, template <class> class FreeList_t>
347 TreeChunk<Chunk_t, FreeList_t>* TreeList<Chunk_t, FreeList_t>::head_as_TreeChunk() {
348 assert(head() == NULL || (TreeChunk<Chunk_t, FreeList_t>::as_TreeChunk(head())->list() == this),
349 "Wrong type of chunk?");
350 return TreeChunk<Chunk_t, FreeList_t>::as_TreeChunk(head());
351 }
|