Skip to content

Commit

Permalink
refactor(container): push try_grow_array_in_place up class hierarchy
Browse files Browse the repository at this point in the history
Allow other Memory_Resource-s to implement in-place allocation growth.
  • Loading branch information
strager committed Nov 5, 2023
1 parent 1933fe4 commit f8fab2a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 24 deletions.
7 changes: 4 additions & 3 deletions src/quick-lint-js/container/linked-bump-allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,13 @@ void Linked_Bump_Allocator::do_deallocate(void* p, std::size_t bytes,
this->deallocate_bytes(p, bytes);
}

bool Linked_Bump_Allocator::try_grow_array_in_place_impl(
char* array, std::size_t old_byte_size, std::size_t new_byte_size) {
bool Linked_Bump_Allocator::do_try_grow_in_place(void* array,
std::size_t old_byte_size,
std::size_t new_byte_size) {
this->assert_not_disabled();
QLJS_ASSERT(new_byte_size > old_byte_size);
bool array_is_last_allocation =
array + old_byte_size == this->next_allocation_;
reinterpret_cast<char*>(array) + old_byte_size == this->next_allocation_;
if (!array_is_last_allocation) {
// We can't grow because something else was already allocated.
return false;
Expand Down
23 changes: 2 additions & 21 deletions src/quick-lint-js/container/linked-bump-allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,6 @@ class Linked_Bump_Allocator final : public Memory_Resource {
// destruction.
[[nodiscard]] Rewind_Guard make_rewind_guard() { return Rewind_Guard(this); }

// Given previously-allocated space for old_size instances of T, allocate
// adjacent space for (new_size-old_size) instances of T after the old
// allocation and return true.
//
// If adjacent space is not available, do nothing and return false.
template <class T>
bool try_grow_array_in_place(T* array, std::size_t old_size,
std::size_t new_size) {
return this->try_grow_array_in_place_impl(reinterpret_cast<char*>(array),
old_size * sizeof(T),
new_size * sizeof(T));
}

// For testing only.
std::size_t remaining_bytes_in_current_chunk() const {
return narrow_cast<std::size_t>(this->chunk_end_ - this->next_allocation_);
Expand Down Expand Up @@ -123,6 +110,8 @@ class Linked_Bump_Allocator final : public Memory_Resource {
void* do_allocate(std::size_t bytes, std::size_t align) override;
void do_deallocate(void* p, std::size_t bytes,
[[maybe_unused]] std::size_t align) override;
bool do_try_grow_in_place(void* p, std::size_t old_byte_size,
std::size_t new_byte_size) override;

private:
struct alignas(alignof(void*)) Chunk_Header {
Expand All @@ -133,14 +122,6 @@ class Linked_Bump_Allocator final : public Memory_Resource {

static inline constexpr std::size_t default_chunk_size = 4096 - sizeof(Chunk);

// Given previously-allocated space of old_byte_size bytes, allocate adjacent
// space for (new_byte_size-old_byte_size) bytes after the old allocation and
// return true.
//
// If adjacent space is not available, do nothing and return false.
bool try_grow_array_in_place_impl(char* array, std::size_t old_byte_size,
std::size_t new_byte_size);

[[nodiscard]] void* allocate_bytes(std::size_t size, std::size_t align);

void deallocate_bytes([[maybe_unused]] void* p,
Expand Down
27 changes: 27 additions & 0 deletions src/quick-lint-js/port/memory-resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,37 @@ class Memory_Resource {
return items;
}

// Given previously-allocated space for old_size instances of T, allocate
// adjacent space for (new_size-old_size) instances of T after the old
// allocation and return true.
//
// If adjacent space is not available, do nothing and return false.
template <class T>
QLJS_FORCE_INLINE bool try_grow_array_in_place(T* array, std::size_t old_size,
std::size_t new_size) {
return this->try_grow_in_place(array, old_size * sizeof(T),
new_size * sizeof(T));
}

// Given previously-allocated space of old_byte_size bytes, allocate adjacent
// space for (new_byte_size-old_byte_size) bytes after the old allocation and
// return true.
//
// If adjacent space is not available, do nothing and return false.
QLJS_FORCE_INLINE bool try_grow_in_place(void* p, std::size_t old_byte_size,
std::size_t new_byte_size) {
return this->do_try_grow_in_place(p, old_byte_size, new_byte_size);
}

protected:
virtual void* do_allocate(std::size_t bytes, std::size_t alignment) = 0;
virtual void do_deallocate(void* p, std::size_t bytes,
std::size_t alignment) = 0;
virtual bool do_try_grow_in_place(
[[maybe_unused]] void* p, [[maybe_unused]] std::size_t old_byte_size,
[[maybe_unused]] std::size_t new_byte_size) {
return false;
}
};

// Like std::pmr::new_delete_resource.
Expand Down

0 comments on commit f8fab2a

Please sign in to comment.