| 360 | } |
| 361 | |
| 362 | void* BFCAllocator::AllocateRawInternal(size_t unused_alignment, |
| 363 | size_t num_bytes, |
| 364 | bool dump_log_on_failure, |
| 365 | uint64 freed_before) { |
| 366 | if (num_bytes == 0) { |
| 367 | VLOG(2) << "tried to allocate 0 bytes"; |
| 368 | return nullptr; |
| 369 | } |
| 370 | // First, always allocate memory of at least kMinAllocationSize |
| 371 | // bytes, and always allocate multiples of kMinAllocationSize bytes |
| 372 | // so all memory addresses are nicely byte aligned. |
| 373 | size_t rounded_bytes = RoundedBytes(num_bytes); |
| 374 | |
| 375 | // The BFC allocator tries to find the best fit first. |
| 376 | BinNum bin_num = BinNumForSize(rounded_bytes); |
| 377 | |
| 378 | mutex_lock l(lock_); |
| 379 | if (!timestamped_chunks_.empty()) { |
| 380 | // Merge timestamped chunks whose counts have become safe for general use. |
| 381 | MergeTimestampedChunks(0); |
| 382 | } |
| 383 | void* ptr = FindChunkPtr(bin_num, rounded_bytes, num_bytes, freed_before); |
| 384 | if (ptr != nullptr) { |
| 385 | return ptr; |
| 386 | } |
| 387 | |
| 388 | // Try to extend |
| 389 | if (Extend(unused_alignment, rounded_bytes)) { |
| 390 | ptr = FindChunkPtr(bin_num, rounded_bytes, num_bytes, freed_before); |
| 391 | if (ptr != nullptr) { |
| 392 | return ptr; |
| 393 | } |
| 394 | } |
| 395 | |
| 396 | if ((freed_before == 0) && (!timestamped_chunks_.empty())) { |
| 397 | // We're unable to satisfy an allocation request without a specific |
| 398 | // timestamp requirement. Rather than fail, try merging any held-out |
| 399 | // timestamped chunks more aggressively until a free chunk of the necessary |
| 400 | // size is formed. |
| 401 | if (MergeTimestampedChunks(rounded_bytes)) { |
| 402 | ptr = FindChunkPtr(bin_num, rounded_bytes, num_bytes, freed_before); |
| 403 | if (ptr != nullptr) { |
| 404 | return ptr; |
| 405 | } |
| 406 | } |
| 407 | } |
| 408 | |
| 409 | // Reaching this point means that no chunks can satisfy the request. Also, |
| 410 | // the unallocated bytes cannot satisfy the request. Before giving up, let's |
| 411 | // try deallocating free regions so that suballocator can combine them with |
| 412 | // the unallocated bytes and form a larger region. |
| 413 | if (DeallocateFreeRegions(rounded_bytes) && |
| 414 | Extend(unused_alignment, rounded_bytes)) { |
| 415 | ptr = FindChunkPtr(bin_num, rounded_bytes, num_bytes, freed_before); |
| 416 | if (ptr != nullptr) { |
| 417 | return ptr; |
| 418 | } |
| 419 | } |
nothing calls this directly
no test coverage detected