Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/ComputeCxx/Attribute/AttributeData/Edge/InputEdge.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
namespace IAG {

struct InputEdge {
AttributeID attribute;
IAGInputOptions options;
AttributeID attribute = AttributeID(nullptr);
IAGInputOptions options = IAGInputOptions(0);

struct Comparator {
AttributeID attribute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace IAG {

struct OutputEdge {
AttributeID attribute;
AttributeID attribute = AttributeID(nullptr);
};

using ConstOutputEdgeArrayRef = ArrayRef<const OutputEdge>;
Expand Down
10 changes: 5 additions & 5 deletions Sources/ComputeCxx/Attribute/AttributeData/Node/IndirectNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ class IndirectNode {
static constexpr uint32_t InvalidSize = 0xffff;

WeakAttributeID _source;
unsigned int _mutable : 1;
unsigned int _traverses_contexts : 1;
unsigned int _offset : 30;
unsigned int _mutable : 1 = 0;
unsigned int _traverses_contexts : 1 = 0;
unsigned int _offset : 30 = 0;

uint16_t _size;
uint16_t _size = InvalidSize;
RelativeAttributeID _next_attribute;

protected:
Expand All @@ -35,7 +35,7 @@ class IndirectNode {
static constexpr uint32_t MaximumOffset = 0x3ffffffe; // 30 bits - 1

IndirectNode(WeakAttributeID source, bool traverses_contexts, uint32_t offset, std::optional<size_t> size)
: _source(source), _traverses_contexts(traverses_contexts), _offset(offset),
: _source(source), _mutable(false), _traverses_contexts(traverses_contexts), _offset(offset),
_size(size.has_value() && size.value() < InvalidSize ? uint16_t(size.value()) : InvalidSize) {}

// Non-copyable
Expand Down
8 changes: 2 additions & 6 deletions Sources/ComputeCxx/Attribute/AttributeData/Node/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,11 @@ void Node::allocate_value(Graph &graph, data::zone &zone) {
size_t alignment_mask = type.value_metadata().getValueWitnesses()->getAlignmentMask();

if (_has_indirect_value) {
_value = zone.alloc_bytes_recycle(sizeof(void *), sizeof(void *) - 1);
_value = zone.alloc(sizeof(void *), sizeof(void *) - 1);
void *persistent_buffer = zone.alloc_persistent(size);
*_value.unsafe_cast<void *>().get() = persistent_buffer;
} else {
if (size <= 0x10) {
_value = zone.alloc_bytes_recycle(uint32_t(size), uint32_t(alignment_mask));
} else {
_value = zone.alloc_bytes(uint32_t(size), uint32_t(alignment_mask));
}
_value = zone.alloc(uint32_t(size), uint32_t(alignment_mask));
}

graph.did_allocate_value(size);
Expand Down
2 changes: 1 addition & 1 deletion Sources/ComputeCxx/Attribute/AttributeData/Node/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ inline NodeState operator~(NodeState a) { return static_cast<NodeState>(~static_

class Node {
private:
NodeState _state;
NodeState _state = NodeState(0);

// Attribute type
unsigned int _type_id : 24 = 0;
Expand Down
26 changes: 12 additions & 14 deletions Sources/ComputeCxx/Closure/ClosureFunction.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#pragma once

#include <swift/Runtime/HeapObject.h>
#include <concepts>
#include <cstddef>
#include <utility>

#include "ComputeCxx/IAGBase.h"
#include "Swift/HeapObject.h"

namespace IAG {

Expand All @@ -17,41 +20,38 @@ template <typename Result, typename... Args> class ClosureFunction {
Context _context;

public:
inline ClosureFunction(std::nullptr_t): _function(nullptr), _context(nullptr) {}
inline ClosureFunction(std::nullptr_t) : _function(nullptr), _context(nullptr) {}
inline ClosureFunction(Function function, Context context) noexcept : _function(function), _context(context) {
if (_context) {
void *mutable_context = const_cast<void *>(_context);
::swift::swift_retain(reinterpret_cast<::swift::HeapObject *>(mutable_context));
_context = swift::retain(_context);
}
}

inline ~ClosureFunction() {
if (_context) {
void *mutable_context = const_cast<void *>(_context);
::swift::swift_release(reinterpret_cast<::swift::HeapObject *>(mutable_context));
swift::release(_context);
}
}

// Copyable

ClosureFunction(const ClosureFunction &other) noexcept : _function(other._function), _context(other._context) {
if (_context) {
void *mutable_context = const_cast<void *>(_context);
::swift::swift_retain(reinterpret_cast<::swift::HeapObject *>(mutable_context));
_context = swift::retain(_context);
}
};

ClosureFunction &operator=(const ClosureFunction &other) noexcept {
if (this != &other) {
Context new_context = other._context;
if (new_context) {
new_context = ::swift::swift_retain((::swift::HeapObject *)new_context);
new_context = swift::retain(new_context);
}
Context old_context = _context;
_function = other._function;
_context = new_context;
if (old_context) {
::swift::swift_release((::swift::HeapObject *)old_context);
swift::release(old_context);
}
}
return *this;
Expand All @@ -70,17 +70,15 @@ template <typename Result, typename... Args> class ClosureFunction {
other._function = nullptr;
other._context = nullptr;
if (old_context) {
::swift::swift_release((::swift::HeapObject *)old_context);
swift::release(old_context);
}
}
return *this;
}

explicit operator bool() { return _function != nullptr; }

const Result operator()(Args... args) const noexcept {
return _function(std::forward<Args>(args)..., _context);
}
const Result operator()(Args... args) const noexcept { return _function(std::forward<Args>(args)..., _context); }
};

template <typename Result>
Expand Down
11 changes: 3 additions & 8 deletions Sources/ComputeCxx/Closure/IAGClosure.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
#include "ComputeCxx/IAGClosure.h"

#include <swift/Runtime/HeapObject.h>
#include "Swift/HeapObject.h"

IAGClosureStorage IAGRetainClosure(const void *thunk, const void *_Nullable context) {
const void *retained_context = context;
if (context) {
void *mutable_context = const_cast<void *>(context);
retained_context = ::swift::swift_retain(reinterpret_cast<::swift::HeapObject *>(mutable_context));
}
const void *retained_context = context ? IAG::swift::retain(context) : nullptr;
return IAGClosureStorage((void *)thunk, retained_context);
}

void IAGReleaseClosure(IAGClosureStorage closure) {
if (closure.context) {
void *mutable_context = const_cast<void *>(closure.context);
::swift::swift_release(reinterpret_cast<::swift::HeapObject *>(mutable_context));
IAG::swift::release(closure.context);
}
}
25 changes: 15 additions & 10 deletions Sources/ComputeCxx/Data/Table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,15 @@ ptr<page> table::alloc_page(zone *zone, uint32_t needed_size) {
}

auto map_copy = std::bitset(_page_maps[map_index]);
page_map_type free_pages_map = map_copy.flip();
while (free_pages_map.any()) {

int candidate_bit = std::countr_zero(static_cast<uint64_t>(free_pages_map.to_ullong()));

// scan ahead to find enough consecutive free pages
bool found = false;
page_map_type candidate_pages_map = map_copy.flip();

bool found = false;
while (candidate_pages_map.any()) {
int candidate_bit = std::countr_zero(static_cast<uint64_t>(candidate_pages_map.to_ullong()));

if (needed_pages > 1) {
// scan ahead to find enough consecutive free pages
bool sufficient_consecutive_pages = true;
for (int j = 1; j < needed_pages; j++) {
int next_page_index = (map_index * pages_per_map) + candidate_bit + j;
int next_map_index = next_page_index / pages_per_map;
Expand All @@ -185,12 +186,13 @@ ptr<page> table::alloc_page(zone *zone, uint32_t needed_size) {
break;
}
if (_page_maps[next_map_index].test(next_page_index % pages_per_map)) {
// next page is used, remove this page from free_pages_map
free_pages_map.reset(candidate_bit);
// next page is used, remove this page from candidate_pages_map
candidate_pages_map.reset(candidate_bit);
sufficient_consecutive_pages = false;
break;
}
}
found = true;
found = sufficient_consecutive_pages;
} else {
// only need one page
found = true;
Expand All @@ -202,6 +204,9 @@ ptr<page> table::alloc_page(zone *zone, uint32_t needed_size) {
break;
}
}
if (found) {
break;
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion Sources/ComputeCxx/Data/Vector.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <limits>

#include "ComputeCxx/IAGBase.h"
#include "Pointer.h"
#include "Zone.h"
Expand Down Expand Up @@ -33,7 +35,7 @@ template <typename T> class vector {
void reserve_slow(zone *zone, size_type new_cap) {
size_type new_capacity_exponent = 1;
if (new_cap >= 2) {
new_capacity_exponent = 32 - std::countl_zero(new_cap - 1);
new_capacity_exponent = std::numeric_limits<size_type>::digits - std::countl_zero(new_cap - 1);
}

size_type old_capacity = sizeof(T) * capacity();
Expand Down
74 changes: 41 additions & 33 deletions Sources/ComputeCxx/Data/Zone.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "Zone.h"

#include <cstring>
#include <cstring>
#include <stdio.h>

#include <platform/malloc.h>
Expand All @@ -27,41 +27,48 @@ void zone::clear() {
}

void zone::realloc_bytes(ptr<void> *buffer, uint32_t size, uint32_t new_size, uint32_t alignment_mask) {
if (new_size > size) {
// check if we don't have to reallocate any memory
if (*buffer) {
auto page = buffer->page_ptr();
uint32_t buffer_offset_from_page = buffer->offset() - page.offset();
if ((page->in_use == buffer_offset_from_page + size && page->total >= buffer_offset_from_page + new_size)) {
// reuse the same buffer pointer, just update the used bytes
page->in_use += new_size - size;
return;
}
if (new_size <= size) {
return;
}

// check if we don't have to reallocate any memory
if (*buffer) {
auto page = buffer->page_ptr();
uint32_t buffer_offset_from_page = buffer->offset() - page.offset();
if ((page->in_use == buffer_offset_from_page + size && page->total >= buffer_offset_from_page + new_size)) {
// reuse the same buffer pointer, just update the used bytes
page->in_use += new_size - size;
return;
}
}

ptr<void> new_buffer = alloc_bytes_recycle(new_size, alignment_mask);
if (*buffer) {
memcpy(new_buffer.get(), (*buffer).get(), size);
ptr<void> new_buffer = alloc_bytes_recycle(new_size, alignment_mask);
if (*buffer) {
memcpy(new_buffer.get(), (*buffer).get(), size);

ptr<bytes_info> old_bytes = (*buffer).aligned<bytes_info>();
uint32_t remaining_size = size + (*buffer - old_bytes);
ptr<bytes_info> aligned_old_bytes = (*buffer).aligned<bytes_info>();
if ((*buffer).page_ptr() == aligned_old_bytes.page_ptr()) {
uint32_t remaining_size = size - (aligned_old_bytes - *buffer);
if (remaining_size >= sizeof(bytes_info)) {
old_bytes->next = _free_bytes;
old_bytes->size = remaining_size;
_free_bytes = old_bytes;
aligned_old_bytes->next = _free_bytes;
aligned_old_bytes->size = remaining_size;
_free_bytes = aligned_old_bytes;
}
}
*buffer = new_buffer;
}
*buffer = new_buffer;
}

ptr<void> zone::alloc_bytes(uint32_t size, uint32_t alignment_mask) {
if (_first_page) {
uint32_t aligned_in_use = (_first_page->in_use + alignment_mask) & ~alignment_mask;
uint32_t new_used_size = aligned_in_use + size;
if (new_used_size <= _first_page->total) {
_first_page->in_use = new_used_size;
return _first_page.advanced<void>(aligned_in_use);
auto candidate = _first_page.advanced<void>(aligned_in_use);
if (candidate.page_ptr() == _first_page) {
_first_page->in_use = new_used_size;
return candidate;
}
}
}

Expand Down Expand Up @@ -96,10 +103,9 @@ ptr<void> zone::alloc_bytes_recycle(uint32_t size, uint32_t alignment_mask) {
*indirect_bytes = bytes->next;

// check if there will be some bytes remaining within the same page
auto end = aligned_bytes.advanced<void>(size);
if ((aligned_bytes.offset() ^ end.offset()) <= page_alignment_mask) {
ptr<bytes_info> aligned_end = end.aligned<bytes_info>();
uint32_t remaining_size = usable_size - size + (end - aligned_end);
ptr<bytes_info> aligned_end = aligned_bytes.advanced<void>(size).aligned<bytes_info>();
if (aligned_bytes.page_ptr() == aligned_end.page_ptr()) {
uint32_t remaining_size = usable_size - (aligned_end - aligned_bytes);
if (remaining_size >= sizeof(bytes_info)) {
bytes_info *remaining_bytes = aligned_end.get();
remaining_bytes->next = _free_bytes;
Expand All @@ -117,16 +123,18 @@ ptr<void> zone::alloc_bytes_recycle(uint32_t size, uint32_t alignment_mask) {
ptr<void> zone::alloc_slow(uint32_t size, uint32_t alignment_mask) {
if (_first_page) {

// check if we can use remaining bytes in this page
// check if we can recycle any remaining bytes in this page
ptr<void> next_bytes = _first_page.advanced<void>(_first_page->in_use);
if (next_bytes.page_ptr() == _first_page) {
ptr<bytes_info> aligned_next_bytes = next_bytes.aligned<bytes_info>();
int32_t remaining_size = _first_page->total - _first_page->in_use + (next_bytes - aligned_next_bytes);
if (remaining_size >= sizeof(bytes_info)) {
bytes_info *remaining_bytes = aligned_next_bytes.get();
remaining_bytes->next = _free_bytes;
remaining_bytes->size = remaining_size;
_free_bytes = aligned_next_bytes;
if (aligned_next_bytes.page_ptr() == _first_page) {
uint32_t remaining_size = _first_page->total - _first_page->in_use - (aligned_next_bytes - next_bytes);
if (remaining_size >= sizeof(bytes_info)) {
bytes_info *remaining_bytes = aligned_next_bytes.get();
remaining_bytes->next = _free_bytes;
remaining_bytes->size = remaining_size;
_free_bytes = aligned_next_bytes;
}
}

// consume this entire page
Expand Down
13 changes: 10 additions & 3 deletions Sources/ComputeCxx/Data/Zone.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ class zone {
ptr<page> _first_page;
ptr<bytes_info> _free_bytes;
info _info;


ptr<void> alloc_bytes(uint32_t size, uint32_t alignment_mask);
ptr<void> alloc_bytes_recycle(uint32_t size, uint32_t alignment_mask);
ptr<void> alloc_slow(uint32_t size, uint32_t alignment_mask);

public:
Expand All @@ -58,8 +60,13 @@ class zone {
void realloc_bytes(ptr<void> *buffer, uint32_t size, uint32_t new_size, uint32_t alignment_mask);

// Paged memory
ptr<void> alloc_bytes(uint32_t size, uint32_t alignment_mask);
ptr<void> alloc_bytes_recycle(uint32_t size, uint32_t alignment_mask);
ptr<void> alloc(uint32_t size, uint32_t alignment_mask) {
if (size <= 0x10) {
return alloc_bytes_recycle(size, alignment_mask);
} else {
return alloc_bytes(size, alignment_mask);
}
}

// Persistent memory
void *alloc_persistent(size_t size);
Expand Down
Loading