diff --git a/Sources/ComputeCxx/Attribute/AttributeData/Edge/InputEdge.h b/Sources/ComputeCxx/Attribute/AttributeData/Edge/InputEdge.h index aa91c1d..417a43b 100644 --- a/Sources/ComputeCxx/Attribute/AttributeData/Edge/InputEdge.h +++ b/Sources/ComputeCxx/Attribute/AttributeData/Edge/InputEdge.h @@ -6,8 +6,8 @@ namespace IAG { struct InputEdge { - AttributeID attribute; - IAGInputOptions options; + AttributeID attribute = AttributeID(nullptr); + IAGInputOptions options = IAGInputOptions(0); struct Comparator { AttributeID attribute; diff --git a/Sources/ComputeCxx/Attribute/AttributeData/Edge/OutputEdge.h b/Sources/ComputeCxx/Attribute/AttributeData/Edge/OutputEdge.h index 4ea4999..0c38917 100644 --- a/Sources/ComputeCxx/Attribute/AttributeData/Edge/OutputEdge.h +++ b/Sources/ComputeCxx/Attribute/AttributeData/Edge/OutputEdge.h @@ -6,7 +6,7 @@ namespace IAG { struct OutputEdge { - AttributeID attribute; + AttributeID attribute = AttributeID(nullptr); }; using ConstOutputEdgeArrayRef = ArrayRef; diff --git a/Sources/ComputeCxx/Attribute/AttributeData/Node/IndirectNode.h b/Sources/ComputeCxx/Attribute/AttributeData/Node/IndirectNode.h index d0504af..7d02810 100644 --- a/Sources/ComputeCxx/Attribute/AttributeData/Node/IndirectNode.h +++ b/Sources/ComputeCxx/Attribute/AttributeData/Node/IndirectNode.h @@ -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: @@ -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) - : _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 diff --git a/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.cpp b/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.cpp index 9b24b13..52121fd 100644 --- a/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.cpp +++ b/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.cpp @@ -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().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); diff --git a/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.h b/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.h index 2617691..456298a 100644 --- a/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.h +++ b/Sources/ComputeCxx/Attribute/AttributeData/Node/Node.h @@ -39,7 +39,7 @@ inline NodeState operator~(NodeState a) { return static_cast(~static_ class Node { private: - NodeState _state; + NodeState _state = NodeState(0); // Attribute type unsigned int _type_id : 24 = 0; diff --git a/Sources/ComputeCxx/Closure/ClosureFunction.h b/Sources/ComputeCxx/Closure/ClosureFunction.h index 55a6d30..cad809d 100644 --- a/Sources/ComputeCxx/Closure/ClosureFunction.h +++ b/Sources/ComputeCxx/Closure/ClosureFunction.h @@ -1,8 +1,11 @@ #pragma once -#include +#include +#include +#include #include "ComputeCxx/IAGBase.h" +#include "Swift/HeapObject.h" namespace IAG { @@ -17,18 +20,16 @@ template 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(_context); - ::swift::swift_retain(reinterpret_cast<::swift::HeapObject *>(mutable_context)); + _context = swift::retain(_context); } } inline ~ClosureFunction() { if (_context) { - void *mutable_context = const_cast(_context); - ::swift::swift_release(reinterpret_cast<::swift::HeapObject *>(mutable_context)); + swift::release(_context); } } @@ -36,8 +37,7 @@ template class ClosureFunction { ClosureFunction(const ClosureFunction &other) noexcept : _function(other._function), _context(other._context) { if (_context) { - void *mutable_context = const_cast(_context); - ::swift::swift_retain(reinterpret_cast<::swift::HeapObject *>(mutable_context)); + _context = swift::retain(_context); } }; @@ -45,13 +45,13 @@ template class ClosureFunction { 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; @@ -70,7 +70,7 @@ template class ClosureFunction { other._function = nullptr; other._context = nullptr; if (old_context) { - ::swift::swift_release((::swift::HeapObject *)old_context); + swift::release(old_context); } } return *this; @@ -78,9 +78,7 @@ template class ClosureFunction { explicit operator bool() { return _function != nullptr; } - const Result operator()(Args... args) const noexcept { - return _function(std::forward(args)..., _context); - } + const Result operator()(Args... args) const noexcept { return _function(std::forward(args)..., _context); } }; template diff --git a/Sources/ComputeCxx/Closure/IAGClosure.cpp b/Sources/ComputeCxx/Closure/IAGClosure.cpp index cc06871..a3cabf4 100644 --- a/Sources/ComputeCxx/Closure/IAGClosure.cpp +++ b/Sources/ComputeCxx/Closure/IAGClosure.cpp @@ -1,19 +1,14 @@ #include "ComputeCxx/IAGClosure.h" -#include +#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(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(closure.context); - ::swift::swift_release(reinterpret_cast<::swift::HeapObject *>(mutable_context)); + IAG::swift::release(closure.context); } } diff --git a/Sources/ComputeCxx/Data/Table.cpp b/Sources/ComputeCxx/Data/Table.cpp index ce1d178..817eebb 100644 --- a/Sources/ComputeCxx/Data/Table.cpp +++ b/Sources/ComputeCxx/Data/Table.cpp @@ -167,14 +167,15 @@ ptr 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(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(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; @@ -185,12 +186,13 @@ ptr 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; @@ -202,6 +204,9 @@ ptr table::alloc_page(zone *zone, uint32_t needed_size) { break; } } + if (found) { + break; + } } } diff --git a/Sources/ComputeCxx/Data/Vector.h b/Sources/ComputeCxx/Data/Vector.h index 28ba5b2..fd07fa3 100644 --- a/Sources/ComputeCxx/Data/Vector.h +++ b/Sources/ComputeCxx/Data/Vector.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "ComputeCxx/IAGBase.h" #include "Pointer.h" #include "Zone.h" @@ -33,7 +35,7 @@ template 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::digits - std::countl_zero(new_cap - 1); } size_type old_capacity = sizeof(T) * capacity(); diff --git a/Sources/ComputeCxx/Data/Zone.cpp b/Sources/ComputeCxx/Data/Zone.cpp index 0978275..276e9c1 100644 --- a/Sources/ComputeCxx/Data/Zone.cpp +++ b/Sources/ComputeCxx/Data/Zone.cpp @@ -1,6 +1,6 @@ #include "Zone.h" -#include +#include #include #include @@ -27,32 +27,36 @@ void zone::clear() { } void zone::realloc_bytes(ptr *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 new_buffer = alloc_bytes_recycle(new_size, alignment_mask); - if (*buffer) { - memcpy(new_buffer.get(), (*buffer).get(), size); + ptr new_buffer = alloc_bytes_recycle(new_size, alignment_mask); + if (*buffer) { + memcpy(new_buffer.get(), (*buffer).get(), size); - ptr old_bytes = (*buffer).aligned(); - uint32_t remaining_size = size + (*buffer - old_bytes); + ptr aligned_old_bytes = (*buffer).aligned(); + 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 zone::alloc_bytes(uint32_t size, uint32_t alignment_mask) { @@ -60,8 +64,11 @@ ptr zone::alloc_bytes(uint32_t size, uint32_t alignment_mask) { 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(aligned_in_use); + auto candidate = _first_page.advanced(aligned_in_use); + if (candidate.page_ptr() == _first_page) { + _first_page->in_use = new_used_size; + return candidate; + } } } @@ -96,10 +103,9 @@ ptr 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(size); - if ((aligned_bytes.offset() ^ end.offset()) <= page_alignment_mask) { - ptr aligned_end = end.aligned(); - uint32_t remaining_size = usable_size - size + (end - aligned_end); + ptr aligned_end = aligned_bytes.advanced(size).aligned(); + 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; @@ -117,16 +123,18 @@ ptr zone::alloc_bytes_recycle(uint32_t size, uint32_t alignment_mask) { ptr 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 next_bytes = _first_page.advanced(_first_page->in_use); if (next_bytes.page_ptr() == _first_page) { ptr aligned_next_bytes = next_bytes.aligned(); - 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 diff --git a/Sources/ComputeCxx/Data/Zone.h b/Sources/ComputeCxx/Data/Zone.h index 99572c6..78cebc2 100644 --- a/Sources/ComputeCxx/Data/Zone.h +++ b/Sources/ComputeCxx/Data/Zone.h @@ -41,7 +41,9 @@ class zone { ptr _first_page; ptr _free_bytes; info _info; - + + ptr alloc_bytes(uint32_t size, uint32_t alignment_mask); + ptr alloc_bytes_recycle(uint32_t size, uint32_t alignment_mask); ptr alloc_slow(uint32_t size, uint32_t alignment_mask); public: @@ -58,8 +60,13 @@ class zone { void realloc_bytes(ptr *buffer, uint32_t size, uint32_t new_size, uint32_t alignment_mask); // Paged memory - ptr alloc_bytes(uint32_t size, uint32_t alignment_mask); - ptr alloc_bytes_recycle(uint32_t size, uint32_t alignment_mask); + ptr 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); diff --git a/Sources/ComputeCxx/Graph/Graph.cpp b/Sources/ComputeCxx/Graph/Graph.cpp index 8225839..73c2d10 100644 --- a/Sources/ComputeCxx/Graph/Graph.cpp +++ b/Sources/ComputeCxx/Graph/Graph.cpp @@ -373,13 +373,7 @@ data::ptr Graph::add_attribute(Subgraph &subgraph, uint32_t type_id, const size_t total_size = ((sizeof(Node) + alignment_mask) & ~alignment_mask) + body_size; - data::ptr node_ptr; - if (total_size <= 0x10) { - node_ptr = subgraph.alloc_bytes_recycle(uint32_t(total_size), uint32_t(alignment_mask | 3)).unsafe_cast(); - } else { - node_ptr = (data::ptr)subgraph.alloc_bytes(uint32_t(total_size), uint32_t(alignment_mask | 3)) - .unsafe_cast(); - } + data::ptr node_ptr = subgraph.alloc(uint32_t(total_size), uint32_t(alignment_mask | 3)).unsafe_cast(); bool main_thread = type.flags() & IAGAttributeTypeFlagsMainThread; new (node_ptr.get()) Node(type_id, main_thread); @@ -458,7 +452,7 @@ data::ptr Graph::add_indirect_attribute(Subgraph &subgraph, Attrib if (is_mutable) { data::ptr indirect_node_ptr = - subgraph.alloc_bytes(sizeof(MutableIndirectNode), 3).unsafe_cast(); + subgraph.alloc(sizeof(MutableIndirectNode), 3).unsafe_cast(); uint64_t subgraph_id = attribute && !attribute.is_nil() ? attribute.subgraph()->subgraph_id() : 0; auto source = WeakAttributeID(attribute, uint32_t(subgraph_id)); @@ -469,8 +463,7 @@ data::ptr Graph::add_indirect_attribute(Subgraph &subgraph, Attrib subgraph.add_indirect(indirect_node_ptr.unsafe_cast(), true); return indirect_node_ptr.unsafe_cast(); } else { - data::ptr indirect_node_ptr = - subgraph.alloc_bytes_recycle(sizeof(IndirectNode), 3).unsafe_cast(); + data::ptr indirect_node_ptr = subgraph.alloc(sizeof(IndirectNode), 3).unsafe_cast(); uint64_t subgraph_id = attribute && !attribute.is_nil() ? attribute.subgraph()->subgraph_id() : 0; auto source = WeakAttributeID(attribute, uint32_t(subgraph_id)); @@ -726,9 +719,9 @@ template <> void Graph::remove_output_edge(data::ptr node, Attribute node->output_edges().erase(iter); } - // if (node->outputs().empty() && node->flags().cacheable()) { - // AttributeID(node).subgraph()->cache_insert(node); - // } + if (node->output_edges().empty() && node->is_cached()) { + AttributeID(node).subgraph()->cache_insert(node); + } } template <> diff --git a/Sources/ComputeCxx/Graph/Graph.h b/Sources/ComputeCxx/Graph/Graph.h index 4fed1c8..5f2cc06 100644 --- a/Sources/ComputeCxx/Graph/Graph.h +++ b/Sources/ComputeCxx/Graph/Graph.h @@ -45,7 +45,7 @@ class Graph { private: vector _nodes; - bool _sorted; + bool _sorted = false; public: vector &nodes() { @@ -72,8 +72,8 @@ class Graph { static Graph *_Nullable _all_graphs; static platform_lock _all_graphs_lock; - Graph *_Nullable _next; - Graph *_Nullable _previous; + Graph *_Nullable _next = nullptr; + Graph *_Nullable _previous = nullptr; util::Heap _heap; // Attribute types diff --git a/Sources/ComputeCxx/Subgraph/Subgraph.cpp b/Sources/ComputeCxx/Subgraph/Subgraph.cpp index d8920f2..6591fdd 100644 --- a/Sources/ComputeCxx/Subgraph/Subgraph.cpp +++ b/Sources/ComputeCxx/Subgraph/Subgraph.cpp @@ -6,7 +6,6 @@ #include -#include "IAGSubgraph-Private.h" #include "Attribute/AttributeData/Node/IndirectNode.h" #include "Attribute/AttributeData/Node/Node.h" #include "Attribute/AttributeID/OffsetAttributeID.h" @@ -14,6 +13,7 @@ #include "Graph/Context.h" #include "Graph/Tree/TreeElement.h" #include "Graph/UpdateStack.h" +#include "IAGSubgraph-Private.h" #include "NodeCache.h" #include "Trace/Trace.h" @@ -90,10 +90,8 @@ void Subgraph::set_current_subgraph(Subgraph *subgraph) { pthread_setspecific(_c IAGUniqueID Subgraph::add_observer(ClosureFunctionVV callback) { if (!_observers) { - _observers = - alloc_bytes(sizeof(vector *), 7).unsafe_cast *>(); + _observers = alloc(sizeof(vector *), 7).unsafe_cast *>(); *_observers = new vector(); - ; } auto observer_id = IAGMakeUniqueID(); @@ -249,7 +247,6 @@ void Subgraph::invalidate_now(Graph &graph) { } } - // TODO: destroy nodes for (auto removed_subgraph : removed_subgraphs) { for (auto page : removed_subgraph->pages()) { // store previous node so we can iterate past it before destroying @@ -260,6 +257,7 @@ void Subgraph::invalidate_now(Graph &graph) { if (previous_node) { previous_node->destroy(*_graph); _graph->did_destroy_node(); + previous_node = nullptr; } if (auto node = attribute.get_node()) { previous_node = node; @@ -271,6 +269,7 @@ void Subgraph::invalidate_now(Graph &graph) { if (previous_node) { previous_node->destroy(*_graph); _graph->did_destroy_node(); + previous_node = nullptr; } if (found_nil_attribute) { break; @@ -303,6 +302,7 @@ void Subgraph::graph_destroyed() { if (previous_node) { previous_node->destroy(*_graph); _graph->did_destroy_node(); + previous_node = nullptr; } if (auto node = attribute.get_node()) { previous_node = node; @@ -313,6 +313,7 @@ void Subgraph::graph_destroyed() { if (previous_node) { previous_node->destroy(*_graph); _graph->did_destroy_node(); + previous_node = nullptr; } if (found_nil_attribute) { break; @@ -726,7 +727,7 @@ void Subgraph::update(IAGAttributeFlags mask) { data::ptr Subgraph::cache_fetch(size_t hash, const swift::metadata &metadata, const void *body, ClosureFunctionCI get_attribute_type_id) { if (_cache == nullptr) { - _cache = alloc_bytes(sizeof(NodeCache), 7).unsafe_cast(); + _cache = alloc(sizeof(NodeCache), 7).unsafe_cast(); new (_cache.get()) NodeCache(); } @@ -737,7 +738,7 @@ data::ptr Subgraph::cache_fetch(size_t hash, const swift::metadata &metada precondition_failure("cache key must be equatable: %s", metadata.name(false)); } - type = alloc_bytes(sizeof(NodeCache::Type), 7).unsafe_cast(); + type = alloc(sizeof(NodeCache::Type), 7).unsafe_cast(); type->type = &metadata; type->equatable = equatable; type->mru = nullptr; @@ -771,7 +772,7 @@ data::ptr Subgraph::cache_fetch(size_t hash, const swift::metadata &metada return nullptr; } - // try reusing a lru item, only if it has been collected at least once to prevent trashing + // try reusing a lru item, only if it has been collected at least once to prevent thrashing if (type->lru && type->lru->age() >= 2) { item = type->lru; @@ -895,7 +896,7 @@ void Subgraph::cache_collect() { #pragma mark - Tree void Subgraph::begin_tree(AttributeID value, const swift::metadata *type, uint32_t flags) { - data::ptr tree = alloc_bytes(sizeof(Graph::TreeElement), 7).unsafe_cast(); + data::ptr tree = alloc(sizeof(Graph::TreeElement), 7).unsafe_cast(); tree->type = type; tree->value = value; tree->flags = flags; @@ -936,7 +937,7 @@ void Subgraph::add_tree_value(AttributeID value, const swift::metadata *type, co auto key_id = graph()->intern_key(key); - data::ptr tree_value = alloc_bytes(sizeof(Graph::TreeValue), 7).unsafe_cast(); + data::ptr tree_value = alloc(sizeof(Graph::TreeValue), 7).unsafe_cast(); tree_value->type = type; tree_value->value = value; tree_value->key_id = key_id; diff --git a/Sources/ComputeCxx/Swift/HeapObject.cpp b/Sources/ComputeCxx/Swift/HeapObject.cpp new file mode 100644 index 0000000..54a0494 --- /dev/null +++ b/Sources/ComputeCxx/Swift/HeapObject.cpp @@ -0,0 +1,19 @@ +#include "HeapObject.h" + +#include + +namespace IAG { +namespace swift { + +IAG_NOINLINE IAG_OPTNONE void *retain(const void *object) noexcept { + void *mutable_object = const_cast(object); + return ::swift::swift_retain(reinterpret_cast<::swift::HeapObject *>(mutable_object)); +} + +IAG_NOINLINE IAG_OPTNONE void release(const void *object) noexcept { + void *mutable_object = const_cast(object); + ::swift::swift_release(reinterpret_cast<::swift::HeapObject *>(mutable_object)); +} + +} // namespace swift +} // namespace IAG diff --git a/Sources/ComputeCxx/Swift/HeapObject.h b/Sources/ComputeCxx/Swift/HeapObject.h new file mode 100644 index 0000000..6022706 --- /dev/null +++ b/Sources/ComputeCxx/Swift/HeapObject.h @@ -0,0 +1,13 @@ +#pragma once + +#include "ComputeCxx/IAGBase.h" + +namespace IAG { +namespace swift { + +IAG_NOINLINE IAG_OPTNONE void *_Nullable retain(const void *_Nullable object) noexcept; + +IAG_NOINLINE IAG_OPTNONE void release(const void *_Nullable object) noexcept; + +} // namespace swift +} // namespace IAG diff --git a/Sources/ComputeCxx/include/ComputeCxx/IAGBase.h b/Sources/ComputeCxx/include/ComputeCxx/IAGBase.h index eec69d3..eb4edc1 100644 --- a/Sources/ComputeCxx/include/ComputeCxx/IAGBase.h +++ b/Sources/ComputeCxx/include/ComputeCxx/IAGBase.h @@ -43,6 +43,22 @@ #define IAG_INLINE static inline #endif +#ifndef IAG_NOINLINE +#if __has_attribute(noinline) +#define IAG_NOINLINE __attribute__((noinline)) +#else +#define IAG_NOINLINE +#endif +#endif + +#ifndef IAG_OPTNONE +#if __has_attribute(optnone) +#define IAG_OPTNONE __attribute__((optnone)) +#else +#define IAG_OPTNONE +#endif +#endif + #ifndef IAG_RETURNS_RETAINED #if __has_feature(attribute_cf_returns_retained) #define IAG_RETURNS_RETAINED __attribute__((cf_returns_retained))