| 444 | } |
| 445 | |
| 446 | Error CodeHolder::grow_buffer(CodeBuffer* cb, size_t n) noexcept { |
| 447 | // The size of the section must be valid. |
| 448 | size_t size = cb->size(); |
| 449 | if (ASMJIT_UNLIKELY(n > std::numeric_limits<uintptr_t>::max() - size)) { |
| 450 | return make_error(Error::kOutOfMemory); |
| 451 | } |
| 452 | |
| 453 | // We can now check if growing the buffer is really necessary. It's unlikely |
| 454 | // that this function is called while there is still room for `n` bytes. |
| 455 | size_t capacity = cb->capacity(); |
| 456 | size_t required = cb->size() + n; |
| 457 | |
| 458 | if (ASMJIT_UNLIKELY(required <= capacity)) { |
| 459 | return Error::kOk; |
| 460 | } |
| 461 | |
| 462 | if (cb->is_fixed()) { |
| 463 | return make_error(Error::kTooLarge); |
| 464 | } |
| 465 | |
| 466 | size_t kInitialCapacity = 8192u - Globals::kAllocOverhead; |
| 467 | if (capacity < kInitialCapacity) { |
| 468 | capacity = kInitialCapacity; |
| 469 | } |
| 470 | else { |
| 471 | capacity += Globals::kAllocOverhead; |
| 472 | } |
| 473 | |
| 474 | do { |
| 475 | size_t old = capacity; |
| 476 | size_t capacity_increase = capacity < Globals::kGrowThreshold ? capacity : Globals::kGrowThreshold; |
| 477 | |
| 478 | capacity += capacity_increase; |
| 479 | |
| 480 | // Overflow. |
| 481 | if (ASMJIT_UNLIKELY(old > capacity)) { |
| 482 | return make_error(Error::kOutOfMemory); |
| 483 | } |
| 484 | } while (capacity - Globals::kAllocOverhead < required); |
| 485 | |
| 486 | return CodeHolder_reserve_internal(this, cb, capacity - Globals::kAllocOverhead); |
| 487 | } |
| 488 | |
| 489 | Error CodeHolder::reserve_buffer(CodeBuffer* cb, size_t n) noexcept { |
| 490 | size_t capacity = cb->capacity(); |
no test coverage detected