268 } 269 270 inline void ZPage::object_iterate(ObjectClosure* cl) { 271 _livemap.iterate(cl, ZAddress::good(start()), object_alignment_shift()); 272 } 273 274 inline uintptr_t ZPage::alloc_object(size_t size) { 275 assert(is_allocating(), "Invalid state"); 276 277 const size_t aligned_size = align_up(size, object_alignment()); 278 const uintptr_t addr = top(); 279 const uintptr_t new_top = addr + aligned_size; 280 281 if (new_top > end()) { 282 // Not enough space left 283 return 0; 284 } 285 286 _top = new_top; 287 288 // Fill alignment padding if needed 289 if (aligned_size != size) { 290 ZUtils::insert_filler_object(addr + size, aligned_size - size); 291 } 292 293 return ZAddress::good(addr); 294 } 295 296 inline uintptr_t ZPage::alloc_object_atomic(size_t size) { 297 assert(is_allocating(), "Invalid state"); 298 299 const size_t aligned_size = align_up(size, object_alignment()); 300 uintptr_t addr = top(); 301 302 for (;;) { 303 const uintptr_t new_top = addr + aligned_size; 304 if (new_top > end()) { 305 // Not enough space left 306 return 0; 307 } 308 309 const uintptr_t prev_top = Atomic::cmpxchg(new_top, &_top, addr); 310 if (prev_top == addr) { 311 // Fill alignment padding if needed 312 if (aligned_size != size) { 313 ZUtils::insert_filler_object(addr + size, aligned_size - size); 314 } 315 316 // Success 317 return ZAddress::good(addr); 318 } 319 320 // Retry 321 addr = prev_top; 322 } 323 } 324 325 inline bool ZPage::undo_alloc_object(uintptr_t addr, size_t size) { 326 assert(is_allocating(), "Invalid state"); 327 328 const uintptr_t offset = ZAddress::offset(addr); 329 const size_t aligned_size = align_up(size, object_alignment()); 330 const uintptr_t old_top = top(); 331 const uintptr_t new_top = old_top - aligned_size; 332 333 if (new_top != offset) { 334 // Failed to undo allocation, not the last allocated object 335 return false; | 268 } 269 270 inline void ZPage::object_iterate(ObjectClosure* cl) { 271 _livemap.iterate(cl, ZAddress::good(start()), object_alignment_shift()); 272 } 273 274 inline uintptr_t ZPage::alloc_object(size_t size) { 275 assert(is_allocating(), "Invalid state"); 276 277 const size_t aligned_size = align_up(size, object_alignment()); 278 const uintptr_t addr = top(); 279 const uintptr_t new_top = addr + aligned_size; 280 281 if (new_top > end()) { 282 // Not enough space left 283 return 0; 284 } 285 286 _top = new_top; 287 288 return ZAddress::good(addr); 289 } 290 291 inline uintptr_t ZPage::alloc_object_atomic(size_t size) { 292 assert(is_allocating(), "Invalid state"); 293 294 const size_t aligned_size = align_up(size, object_alignment()); 295 uintptr_t addr = top(); 296 297 for (;;) { 298 const uintptr_t new_top = addr + aligned_size; 299 if (new_top > end()) { 300 // Not enough space left 301 return 0; 302 } 303 304 const uintptr_t prev_top = Atomic::cmpxchg(new_top, &_top, addr); 305 if (prev_top == addr) { 306 // Success 307 return ZAddress::good(addr); 308 } 309 310 // Retry 311 addr = prev_top; 312 } 313 } 314 315 inline bool ZPage::undo_alloc_object(uintptr_t addr, size_t size) { 316 assert(is_allocating(), "Invalid state"); 317 318 const uintptr_t offset = ZAddress::offset(addr); 319 const size_t aligned_size = align_up(size, object_alignment()); 320 const uintptr_t old_top = top(); 321 const uintptr_t new_top = old_top - aligned_size; 322 323 if (new_top != offset) { 324 // Failed to undo allocation, not the last allocated object 325 return false; |