silly little mutation now uses direct stack moving.
parent
3e698b86eb
commit
253f4f1fdf
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(blt-gp VERSION 0.0.114)
|
project(blt-gp VERSION 0.0.115)
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,102 @@ namespace blt::gp
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void insert(stack_allocator stack)
|
||||||
|
{
|
||||||
|
if (stack.empty())
|
||||||
|
return;
|
||||||
|
// take a copy of the pointer to this stack's blocks
|
||||||
|
auto old_head = stack.head;
|
||||||
|
// stack is now empty, we have the last reference to it.
|
||||||
|
stack.head = nullptr;
|
||||||
|
// we don't have any nodes to search through or re-point, we can just assign the head
|
||||||
|
if (head == nullptr)
|
||||||
|
{
|
||||||
|
head = old_head;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the beginning of the stack
|
||||||
|
auto begin = old_head;
|
||||||
|
while (begin->metadata.prev != nullptr)
|
||||||
|
begin = begin->metadata.prev;
|
||||||
|
|
||||||
|
// move along blocks with free space, attempt to insert bytes from one stack to another
|
||||||
|
auto insert = head;
|
||||||
|
while (insert->metadata.next != nullptr && begin != nullptr)
|
||||||
|
{
|
||||||
|
if (begin->used_bytes_in_block() <= insert->remaining_bytes_in_block())
|
||||||
|
{
|
||||||
|
std::memcpy(insert->metadata.offset, begin->buffer, begin->used_bytes_in_block());
|
||||||
|
insert->metadata.offset += begin->used_bytes_in_block();
|
||||||
|
auto old_begin = begin;
|
||||||
|
begin = begin->metadata.next;
|
||||||
|
free_block(old_begin);
|
||||||
|
}
|
||||||
|
head = insert;
|
||||||
|
insert = insert->metadata.next;
|
||||||
|
}
|
||||||
|
if (begin == nullptr)
|
||||||
|
return;
|
||||||
|
while (insert->metadata.next != nullptr)
|
||||||
|
insert = insert->metadata.next;
|
||||||
|
// if here is space left we can move the pointers around
|
||||||
|
insert->metadata.next = begin;
|
||||||
|
begin->metadata.prev = insert;
|
||||||
|
// find where the head is now and set the head to this new point.
|
||||||
|
auto new_head = begin;
|
||||||
|
while (new_head->metadata.next != nullptr)
|
||||||
|
new_head = new_head->metadata.next;
|
||||||
|
head = new_head;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bytes must be the number of bytes to move, all types must have alignment accounted for
|
||||||
|
*/
|
||||||
|
void copy_from(const stack_allocator& stack, blt::size_t bytes)
|
||||||
|
{
|
||||||
|
if (stack.empty())
|
||||||
|
{
|
||||||
|
BLT_WARN("This stack is empty, we will copy no bytes from it!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto start_block = stack.head;
|
||||||
|
auto bytes_left = static_cast<blt::ptrdiff_t>(bytes);
|
||||||
|
blt::u8* start_point = nullptr;
|
||||||
|
while (bytes_left > 0)
|
||||||
|
{
|
||||||
|
if (start_block == nullptr)
|
||||||
|
{
|
||||||
|
BLT_WARN("This stack doesn't contain enough space to copy %ld bytes!", bytes);
|
||||||
|
BLT_WARN_STREAM << "State: " << size() << "\n";
|
||||||
|
BLT_ABORT("Stack doesn't contain enough data for this copy operation!");
|
||||||
|
}
|
||||||
|
if (start_block->used_bytes_in_block() < bytes_left)
|
||||||
|
{
|
||||||
|
bytes_left -= start_block->used_bytes_in_block();
|
||||||
|
start_block = start_block->metadata.prev;
|
||||||
|
} else if (start_block->used_bytes_in_block() == bytes_left)
|
||||||
|
{
|
||||||
|
start_point = start_block->buffer;
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
start_point = start_block->metadata.offset - bytes_left;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we can copy the bytes directly, no special allocation
|
||||||
|
if (head->remaining_bytes_in_block() >= bytes_left)
|
||||||
|
{
|
||||||
|
std::memcpy(head->metadata.offset, start_point, bytes_left);
|
||||||
|
head->metadata.offset += bytes_left;
|
||||||
|
start_block = start_block->metadata.next;
|
||||||
|
}
|
||||||
|
while (start_block != nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pushes an instance of an object on to the stack
|
* Pushes an instance of an object on to the stack
|
||||||
|
@ -337,7 +433,7 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
auto ptr = blk;
|
auto ptr = blk;
|
||||||
blk = blk->metadata.next;
|
blk = blk->metadata.next;
|
||||||
std::free(ptr);
|
free_block(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free_chain(head);
|
free_chain(head);
|
||||||
|
@ -496,11 +592,16 @@ namespace blt::gp
|
||||||
{
|
{
|
||||||
block* ptr = current;
|
block* ptr = current;
|
||||||
current = current->metadata.prev;
|
current = current->metadata.prev;
|
||||||
std::free(ptr);
|
free_block(ptr);
|
||||||
//get_allocator().deallocate(ptr);
|
//get_allocator().deallocate(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_block(block* ptr)
|
||||||
|
{
|
||||||
|
std::free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool move_back()
|
inline bool move_back()
|
||||||
{
|
{
|
||||||
auto old = head;
|
auto old = head;
|
||||||
|
@ -511,11 +612,6 @@ namespace blt::gp
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
//free_chain(old);
|
|
||||||
// required to prevent silly memory :3
|
|
||||||
// if (head != nullptr)
|
|
||||||
// head->metadata.next = nullptr;
|
|
||||||
// std::free(old);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
2
lib/blt
2
lib/blt
|
@ -1 +1 @@
|
||||||
Subproject commit befd5e0ca1135c467f194d1d0e5691d301f93a34
|
Subproject commit 79ad108fab60159461d4c78ffb97b910d446cc11
|
|
@ -195,7 +195,7 @@ namespace blt::gp
|
||||||
auto& new_vals_r = new_tree.get_values();
|
auto& new_vals_r = new_tree.get_values();
|
||||||
|
|
||||||
stack_allocator stack_after;
|
stack_allocator stack_after;
|
||||||
stack_allocator new_vals_flip; // this is annoying.
|
//stack_allocator new_vals_flip; // this is annoying.
|
||||||
transfer_backward(vals_r, stack_after, ops_r.end() - 1, end_itr - 1);
|
transfer_backward(vals_r, stack_after, ops_r.end() - 1, end_itr - 1);
|
||||||
for (auto it = end_itr - 1; it != begin_itr - 1; it--)
|
for (auto it = end_itr - 1; it != begin_itr - 1; it--)
|
||||||
{
|
{
|
||||||
|
@ -203,8 +203,7 @@ namespace blt::gp
|
||||||
vals_r.pop_bytes(static_cast<blt::ptrdiff_t>(stack_allocator::aligned_size(it->type_size)));
|
vals_r.pop_bytes(static_cast<blt::ptrdiff_t>(stack_allocator::aligned_size(it->type_size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
transfer_backward(new_vals_r, new_vals_flip, new_ops_r.end() - 1, new_ops_r.begin() - 1);
|
vals_r.insert(std::move(new_vals_r));
|
||||||
transfer_forward(new_vals_flip, vals_r, new_ops_r.begin(), new_ops_r.end());
|
|
||||||
transfer_forward(stack_after, vals_r, end_itr, ops_r.end());
|
transfer_forward(stack_after, vals_r, end_itr, ops_r.end());
|
||||||
|
|
||||||
auto before = begin_itr - 1;
|
auto before = begin_itr - 1;
|
||||||
|
@ -225,7 +224,9 @@ namespace blt::gp
|
||||||
|
|
||||||
if (bytes_expected != bytes_size)
|
if (bytes_expected != bytes_size)
|
||||||
{
|
{
|
||||||
BLT_WARN("Child tree bytes %ld vs expected %ld", bytes_size, bytes_expected);
|
BLT_WARN_STREAM << "Stack state: " << vals_r.size() << "\n";
|
||||||
|
BLT_WARN("Child tree bytes %ld vs expected %ld, difference: %ld", bytes_size, bytes_expected,
|
||||||
|
static_cast<blt::ptrdiff_t>(bytes_expected) - static_cast<blt::ptrdiff_t>(bytes_size));
|
||||||
BLT_ABORT("Amount of bytes in stack doesn't match the number of bytes expected for the operations");
|
BLT_ABORT("Amount of bytes in stack doesn't match the number of bytes expected for the operations");
|
||||||
}
|
}
|
||||||
auto copy = c;
|
auto copy = c;
|
||||||
|
@ -236,7 +237,8 @@ namespace blt::gp
|
||||||
} catch (...)
|
} catch (...)
|
||||||
{
|
{
|
||||||
std::cout << "This occurred at point " << begin_point << " ending at (old) " << end_point << "\n";
|
std::cout << "This occurred at point " << begin_point << " ending at (old) " << end_point << "\n";
|
||||||
std::cout << "our root type is " << ops_r[begin_point].id << " with size " << stack_allocator::aligned_size(ops_r[begin_point].type_size) << "\n";
|
std::cout << "our root type is " << ops_r[begin_point].id << " with size " << stack_allocator::aligned_size(ops_r[begin_point].type_size)
|
||||||
|
<< "\n";
|
||||||
std::cout << "now Named: " << (program.get_name(ops_r[begin_point].id) ? *program.get_name(ops_r[begin_point].id) : "Unnamed") << "\n";
|
std::cout << "now Named: " << (program.get_name(ops_r[begin_point].id) ? *program.get_name(ops_r[begin_point].id) : "Unnamed") << "\n";
|
||||||
std::cout << "Was named: " << (program.get_name(begin_operator_id) ? *program.get_name(begin_operator_id) : "Unnamed") << "\n";
|
std::cout << "Was named: " << (program.get_name(begin_operator_id) ? *program.get_name(begin_operator_id) : "Unnamed") << "\n";
|
||||||
std::cout << "Parent:" << std::endl;
|
std::cout << "Parent:" << std::endl;
|
||||||
|
|
Loading…
Reference in New Issue