180 assert(tail() != prevFC || prevFC->next() == NULL, 181 "Next of tail should be NULL"); 182 } 183 decrement_count(); 184 assert(((head() == NULL) + (tail() == NULL) + (count() == 0)) % 3 == 0, 185 "H/T/C Inconsistency"); 186 // clear next and prev fields of fc, debug only 187 NOT_PRODUCT( 188 fc->link_prev(NULL); 189 fc->link_next(NULL); 190 ) 191 assert(fc->is_free(), "Should still be a free chunk"); 192 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 193 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 194 assert(head() == NULL || head()->size() == size(), "wrong item on list"); 195 assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); 196 } 197 198 // Add this chunk at the head of the list. 199 template <class Chunk> 200 void FreeList<Chunk>::return_chunk_at_head(Chunk* chunk, bool record_return) { 201 assert_proper_lock_protection(); 202 assert(chunk != NULL, "insert a NULL chunk"); 203 assert(size() == chunk->size(), "Wrong size"); 204 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 205 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 206 207 Chunk* oldHead = head(); 208 assert(chunk != oldHead, "double insertion"); 209 chunk->link_after(oldHead); 210 link_head(chunk); 211 if (oldHead == NULL) { // only chunk in list 212 assert(tail() == NULL, "inconsistent FreeList"); 213 link_tail(chunk); 214 } 215 increment_count(); // of # of chunks in list 216 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 217 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 218 assert(head() == NULL || head()->size() == size(), "wrong item on list"); 219 assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); 220 } 221 222 template <class Chunk> 223 void FreeList<Chunk>::return_chunk_at_head(Chunk* chunk) { 224 assert_proper_lock_protection(); 225 return_chunk_at_head(chunk, true); 226 } 227 228 // Add this chunk at the tail of the list. 229 template <class Chunk> 230 void FreeList<Chunk>::return_chunk_at_tail(Chunk* chunk, bool record_return) { 231 assert_proper_lock_protection(); 232 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 233 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 234 assert(chunk != NULL, "insert a NULL chunk"); 235 assert(size() == chunk->size(), "wrong size"); 236 237 Chunk* oldTail = tail(); 238 assert(chunk != oldTail, "double insertion"); 239 if (oldTail != NULL) { 240 oldTail->link_after(chunk); 241 } else { // only chunk in list 242 assert(head() == NULL, "inconsistent FreeList"); 243 link_head(chunk); 244 } 245 link_tail(chunk); 246 increment_count(); // of # of chunks in list 247 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 248 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 249 assert(head() == NULL || head()->size() == size(), "wrong item on list"); 250 assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); 251 } 252 253 template <class Chunk> 254 void FreeList<Chunk>::return_chunk_at_tail(Chunk* chunk) { 255 return_chunk_at_tail(chunk, true); 256 } 257 258 template <class Chunk> 259 void FreeList<Chunk>::prepend(FreeList<Chunk>* fl) { 260 assert_proper_lock_protection(); 261 if (fl->count() > 0) { 262 if (count() == 0) { 263 set_head(fl->head()); 264 set_tail(fl->tail()); 265 set_count(fl->count()); 266 } else { 267 // Both are non-empty. 268 Chunk* fl_tail = fl->tail(); 269 Chunk* this_head = head(); 270 assert(fl_tail->next() == NULL, "Well-formedness of fl"); 271 fl_tail->link_next(this_head); 272 this_head->link_prev(fl_tail); 273 set_head(fl->head()); 274 set_count(count() + fl->count()); 275 } | 180 assert(tail() != prevFC || prevFC->next() == NULL, 181 "Next of tail should be NULL"); 182 } 183 decrement_count(); 184 assert(((head() == NULL) + (tail() == NULL) + (count() == 0)) % 3 == 0, 185 "H/T/C Inconsistency"); 186 // clear next and prev fields of fc, debug only 187 NOT_PRODUCT( 188 fc->link_prev(NULL); 189 fc->link_next(NULL); 190 ) 191 assert(fc->is_free(), "Should still be a free chunk"); 192 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 193 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 194 assert(head() == NULL || head()->size() == size(), "wrong item on list"); 195 assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); 196 } 197 198 // Add this chunk at the head of the list. 199 template <class Chunk> 200 void FreeList<Chunk>::return_chunk_at_head(Chunk* chunk, bool record_return, bool deallocate_pages) { 201 assert_proper_lock_protection(); 202 assert(chunk != NULL, "insert a NULL chunk"); 203 assert(size() == chunk->size(), "Wrong size"); 204 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 205 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 206 207 Chunk* oldHead = head(); 208 assert(chunk != oldHead, "double insertion"); 209 chunk->link_after(oldHead); 210 link_head(chunk); 211 if (oldHead == NULL) { // only chunk in list 212 assert(tail() == NULL, "inconsistent FreeList"); 213 link_tail(chunk); 214 } 215 increment_count(); // of # of chunks in list 216 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 217 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 218 assert(head() == NULL || head()->size() == size(), "wrong item on list"); 219 assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); 220 if (DeallocateHeapPages && deallocate_pages) { 221 chunk->deallocate_pages(); 222 } 223 } 224 225 template <class Chunk> 226 void FreeList<Chunk>::return_chunk_at_head(Chunk* chunk) { 227 assert_proper_lock_protection(); 228 return_chunk_at_head(chunk, true, true); 229 } 230 231 // Add this chunk at the tail of the list. 232 template <class Chunk> 233 void FreeList<Chunk>::return_chunk_at_tail(Chunk* chunk, bool record_return, bool deallocate_pages) { 234 assert_proper_lock_protection(); 235 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 236 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 237 assert(chunk != NULL, "insert a NULL chunk"); 238 assert(size() == chunk->size(), "wrong size"); 239 240 Chunk* oldTail = tail(); 241 assert(chunk != oldTail, "double insertion"); 242 if (oldTail != NULL) { 243 oldTail->link_after(chunk); 244 } else { // only chunk in list 245 assert(head() == NULL, "inconsistent FreeList"); 246 link_head(chunk); 247 } 248 link_tail(chunk); 249 increment_count(); // of # of chunks in list 250 assert(head() == NULL || head()->prev() == NULL, "list invariant"); 251 assert(tail() == NULL || tail()->next() == NULL, "list invariant"); 252 assert(head() == NULL || head()->size() == size(), "wrong item on list"); 253 assert(tail() == NULL || tail()->size() == size(), "wrong item on list"); 254 if (DeallocateHeapPages && deallocate_pages) { 255 chunk->deallocate_pages(); 256 } 257 } 258 259 template <class Chunk> 260 void FreeList<Chunk>::return_chunk_at_tail(Chunk* chunk) { 261 return_chunk_at_tail(chunk, true, true); 262 } 263 264 template <class Chunk> 265 void FreeList<Chunk>::prepend(FreeList<Chunk>* fl) { 266 assert_proper_lock_protection(); 267 if (fl->count() > 0) { 268 if (count() == 0) { 269 set_head(fl->head()); 270 set_tail(fl->tail()); 271 set_count(fl->count()); 272 } else { 273 // Both are non-empty. 274 Chunk* fl_tail = fl->tail(); 275 Chunk* this_head = head(); 276 assert(fl_tail->next() == NULL, "Well-formedness of fl"); 277 fl_tail->link_next(this_head); 278 this_head->link_prev(fl_tail); 279 set_head(fl->head()); 280 set_count(count() + fl->count()); 281 } |