Skip to content
Open
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/Compute/Attribute/AnyAttribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ func IAGGraphMutateAttribute(
_ attribute: AnyAttribute,
type: Metadata,
invalidating: Bool,
modify: (UnsafeMutableRawPointer) -> Void
modify: @escaping (UnsafeMutableRawPointer) -> Void
)

@_silgen_name("IAGGraphSearch")
func IAGGraphSearch(
attribute: AnyAttribute,
options: SearchOptions,
predicate: (AnyAttribute) -> Bool
predicate: @escaping (AnyAttribute) -> Bool
) -> Bool

extension AnyAttribute {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Compute/Attribute/AttributeType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension String {

@_silgen_name("IAGRetainClosure")
func IAGRetainClosure(
_ closure: (UnsafeMutableRawPointer, AnyAttribute) -> Void
_ closure: @escaping (UnsafeMutableRawPointer, AnyAttribute) -> Void
) -> _IAGClosureStorage

extension _AttributeType {
Expand Down
6 changes: 4 additions & 2 deletions Sources/Compute/Attribute/RuleContext/AnyRuleContext.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ComputeCxx

@_silgen_name("IAGGraphWithUpdate")
func IAGGraphWithUpdate(_ attribute: AnyAttribute, body: () -> Void)
func IAGGraphWithUpdate(_ attribute: AnyAttribute, body: @escaping () -> Void)

@frozen
public struct AnyRuleContext {
Expand All @@ -21,7 +21,9 @@ public struct AnyRuleContext {
}

public func update(body: () -> Void) {
IAGGraphWithUpdate(attribute, body: body)
withoutActuallyEscaping(body) { escapingBody in
IAGGraphWithUpdate(attribute, body: escapingBody)
}
}

public func changedValue<Value>(
Expand Down
26 changes: 15 additions & 11 deletions Sources/Compute/Graph/Graph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ extension Graph {
pointer.initialize(to: attributeType)
return UnsafePointer(pointer)
}
return internAttributeType(
ctx: ctx,
body: Metadata(body),
makeAttributeType: makeAttributeType
)
return withoutActuallyEscaping(makeAttributeType) { escapingMakeAttributeType in
return internAttributeType(
ctx: ctx,
body: Metadata(body),
makeAttributeType: escapingMakeAttributeType
)
}
}
}

Expand Down Expand Up @@ -81,7 +83,7 @@ func IAGGraphSetInvalidationCallback(
@_silgen_name("IAGGraphWithMainThreadHandler")
func IAGGraphWithMainThreadHandler(
_ graph: UnsafeRawPointer,
body: () -> Void,
body: @escaping () -> Void,
mainThreadHandler: (() -> Void) -> Void
)

Expand Down Expand Up @@ -118,11 +120,13 @@ extension Graph {
}

public func withMainThreadHandler(_ mainThreadHandler: (() -> Void) -> Void, do body: () -> Void) {
IAGGraphWithMainThreadHandler(
unsafeBitCast(self, to: UnsafeRawPointer.self),
body: body,
mainThreadHandler: mainThreadHandler
)
withoutActuallyEscaping(body) { escapingBody in
IAGGraphWithMainThreadHandler(
unsafeBitCast(self, to: UnsafeRawPointer.self),
body: escapingBody,
mainThreadHandler: mainThreadHandler
)
}
}
}

Expand Down
8 changes: 5 additions & 3 deletions Sources/Compute/Graph/Subgraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ComputeCxx
@_silgen_name("IAGSubgraphAddObserver")
func IAGSubgraphAddObserver(
_ subgraph: UnsafeRawPointer,
observer: () -> Void
observer: @escaping () -> Void
) -> Int

extension Subgraph {
Expand All @@ -16,7 +16,7 @@ extension Subgraph {
func IAGSubgraphApply(
_ subgraph: UnsafeRawPointer,
_ flags: Subgraph.Flags,
_ body: (AnyAttribute) -> Void
_ body: @escaping (AnyAttribute) -> Void
)

extension Subgraph {
Expand All @@ -36,7 +36,9 @@ extension Subgraph {
_ flags: Subgraph.Flags,
_ body: (AnyAttribute) -> Void
) {
IAGSubgraphApply(unsafeBitCast(self, to: UnsafeRawPointer.self), flags, body)
withoutActuallyEscaping(body) { escapingBody in
IAGSubgraphApply(unsafeBitCast(self, to: UnsafeRawPointer.self), flags, escapingBody)
}
}

}
Expand Down
9 changes: 6 additions & 3 deletions Sources/Compute/Runtime/Metadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public func forEachField(of type: Any.Type, do body: (UnsafePointer<Int8>, Int,
func IAGTypeApplyFields2(
_ type: Metadata,
options: Metadata.ApplyOptions,
body: (UnsafePointer<CChar>, Int, Metadata) -> Bool
body: @escaping (UnsafePointer<CChar>, Int, Metadata) -> Bool
) -> Bool

extension Metadata {
Expand All @@ -32,8 +32,11 @@ extension Metadata {
)
-> Bool
{
return IAGTypeApplyFields2(self, options: options) { fieldName, fieldOffset, fieldType in
return body(fieldName, fieldOffset, fieldType.type)
return withoutActuallyEscaping(body) { escapingBody in
let apply: (UnsafePointer<CChar>, Int, Metadata) -> Bool = { fieldName, fieldOffset, fieldType in
return escapingBody(fieldName, fieldOffset, fieldType.type)
}
return IAGTypeApplyFields2(self, options: options, body: apply)
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/ComputeCxx/Attribute/AttributeID/AttributeID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ OffsetAttributeID AttributeID::resolve_slow(TraversalOptions options) const {
}
}

if (options && TraversalOptions::EvaluateWeakReferences) {
if (indirect_node->source().expired()) {
if (options & TraversalOptions::EvaluateWeakReferences) {
if (indirect_node->source().is_freed()) {
if (options & TraversalOptions::AssertNotNil) {
precondition_failure("invalid indirect ref: %u", _value);
}
Expand Down
15 changes: 13 additions & 2 deletions Sources/ComputeCxx/Attribute/AttributeID/WeakAttributeID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace IAG {

bool WeakAttributeID::expired() const {
bool WeakAttributeID::is_expired() const {
uint64_t raw_page_seed = data::table::shared().raw_page_seed(_identifier.page_ptr());
if (raw_page_seed & 0xff00000000) {
auto zone_info = data::zone::info::from_raw_value(uint32_t(raw_page_seed));
Expand All @@ -17,8 +17,19 @@ bool WeakAttributeID::expired() const {
return true;
}

bool WeakAttributeID::is_freed() const {
uint64_t raw_page_seed = data::table::shared().raw_page_seed(_identifier.page_ptr());
if (raw_page_seed & 0xff00000000) {
auto zone_info = data::zone::info::from_raw_value(uint32_t(raw_page_seed));
if (zone_info.zone_id() == _seed) {
return false;
}
}
return true;
}

const AttributeID WeakAttributeID::evaluate() const {
return _identifier && !expired() ? _identifier : AttributeID(IAGAttributeNil);
return _identifier && !is_expired() ? _identifier : AttributeID(IAGAttributeNil);
};

} // namespace IAG
11 changes: 9 additions & 2 deletions Sources/ComputeCxx/Attribute/AttributeID/WeakAttributeID.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ class WeakAttributeID {
const AttributeID identifier() const { return _identifier; };
uint32_t seed() const { return _seed; }

bool expired() const;
/// Returns true if the attribute can no longer be evaluated.
bool is_expired() const;

/// Returns the attribute it is has not expired, otherwise returns the nil
/// Returns true when the attribute's subgraph has been freed (or reused).
///
/// This method may return false if the attribute's subgraph has been
/// invalidated but not yet destroyed.
bool is_freed() const;

/// Returns the attribute if it has not expired, otherwise returns the nil
/// attribute.
const AttributeID evaluate() const;
};
Expand Down
32 changes: 18 additions & 14 deletions Sources/ComputeCxx/Comparison/LayoutDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,9 @@ Partial find_partial(ValueLayout layout, size_t range_location, size_t range_siz
}
};

return {reader.layout, accumulated_size};
// The compared values already start at the requested range.
size_t location = accumulated_size - range_location;
return {reader.layout, location < range_size ? location : range_size};
}

void print(std::string &output, ValueLayout layout) {
Expand Down Expand Up @@ -1143,23 +1145,25 @@ bool Builder::visit_case(const swift::metadata &type, const swift::field_record
};
enum_item.cases.push_back(std::move(enum_case));

bool result;

_enum_case_depth += 1;
EnumItem::Case *prev_enum_case = _current_enum_case;
_current_enum_case = &enum_item.cases.back();

if (field.isIndirectCase() && _current_comparison_mode == 0) {
add_field(sizeof(void *));
result = true;
} else {
auto mangled_type_name = field.MangledTypeName.get();
auto field_type =
mangled_type_name != nullptr ? type.mangled_type_name_ref(mangled_type_name, false, nullptr) : nullptr;
if (field_type == nullptr) {
// bail out if we can't get a type for the enum case payload
// bail out if we can't get a type for the enum case payload. The enum item and its cases are destroyed, so
// return without touching them again.
items.pop_back();
result = false;

_enum_case_depth -= 1;
_current_enum_case = prev_enum_case;

return false;
} else if (field.isIndirectCase()) {
if (auto field_size = field_type->vw_size()) {
IndirectItem item = {
Expand All @@ -1169,7 +1173,6 @@ bool Builder::visit_case(const swift::metadata &type, const swift::field_record
};
_current_enum_case->children.push_back(item);
}
result = true;
} else {
IAGComparisonMode prev_comparison_mode = _current_comparison_mode;
_current_comparison_mode = mode_for_type(&type, _current_comparison_mode);
Expand All @@ -1178,6 +1181,7 @@ bool Builder::visit_case(const swift::metadata &type, const swift::field_record

// same as visit_element
auto &items = get_items();
auto num_items = items.size();
size_t prev_offset = -1;
size_t prev_size = 0;
if (auto data_item = items.size() > 0 ? std::get_if<DataItem>(&items.back()) : nullptr) {
Expand All @@ -1187,7 +1191,7 @@ bool Builder::visit_case(const swift::metadata &type, const swift::field_record

if (!field_type->visit(*this)) {
RevertItemsInfo info = {
items.size(),
num_items,
{
prev_offset,
prev_size,
Expand All @@ -1207,8 +1211,6 @@ bool Builder::visit_case(const swift::metadata &type, const swift::field_record
}

_current_comparison_mode = prev_comparison_mode;

result = true;
}
}

Expand All @@ -1219,7 +1221,7 @@ bool Builder::visit_case(const swift::metadata &type, const swift::field_record
_enum_case_depth -= 1;
_current_enum_case = prev_enum_case;

return result;
return true;
}

bool Builder::visit_existential(const swift::existential_type_metadata &type) {
Expand Down Expand Up @@ -1383,16 +1385,18 @@ void Builder::Emitter<vector<unsigned char, 512, uint64_t>>::operator()(const En
emit_value((void *)item.type);
}

// Case items have offsets in the same space as the enum item, and the
// comparison starts each case at the enum's offset.
auto children_emitter = Emitter<vector<unsigned char, 512, uint64_t>>(_data);
children_emitter._emitted_size = item.offset;
for (auto &&child : enum_case.children) {
std::visit(children_emitter, child);
}

is_first = false;

if (!_invalid && !children_emitter.is_invalid()) {
_invalid = _emitted_size + item.type->vw_size() < children_emitter.emitted_size();
}
_invalid = _invalid || children_emitter.is_invalid() ||
_emitted_size + item.type->vw_size() < children_emitter.emitted_size();
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/ComputeCxx/Data/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ vector<T>::iterator vector<T>::insert(zone *zone, const_iterator pos, const T &v
template <typename T>
vector<T>::iterator vector<T>::insert(zone *zone, const_iterator pos, T &&value) {
if (pos == end()) {
push_back(zone, value);
push_back(zone, std::move(value));
return end() - 1;
}
auto offset = pos - begin();
Expand Down
10 changes: 5 additions & 5 deletions Sources/ComputeCxx/Graph/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ void Graph::remove_indirect_node(data::ptr<IndirectNode> indirect_node) {
return;
}

if (indirect_node->source().expired()) {
if (indirect_node->source().is_freed()) {
return;
}

Expand Down Expand Up @@ -556,7 +556,7 @@ void Graph::remove_indirect_node(data::ptr<IndirectNode> indirect_node) {
}
break;
} else {
if (source_indirect_node->source().expired()) {
if (source_indirect_node->source().is_freed()) {
break;
}

Expand Down Expand Up @@ -624,7 +624,7 @@ bool Graph::remove_removed_output(AttributeID attribute, AttributeID output, boo
if (output_indirect_node->is_mutable()) {
auto &mutable_output_indirect_node = output_indirect_node->to_mutable();
auto initial_source = mutable_output_indirect_node.initial_source();
if (initial_source.identifier() && !initial_source.identifier().is_nil() && !initial_source.expired()) {
if (initial_source.identifier() && !initial_source.identifier().is_nil() && !initial_source.is_expired()) {
new_source = initial_source;
new_offset = mutable_output_indirect_node.initial_offset();
}
Expand All @@ -636,7 +636,7 @@ bool Graph::remove_removed_output(AttributeID attribute, AttributeID output, boo

output_indirect_node->modify(new_source, new_offset);

if (new_source.identifier() && !new_source.identifier().is_nil() && !new_source.expired()) {
if (new_source.identifier() && !new_source.identifier().is_nil() && !new_source.is_expired()) {
add_input_dependencies(output, new_source.identifier());
}

Expand Down Expand Up @@ -917,7 +917,7 @@ bool Graph::indirect_attribute_reset(data::ptr<IndirectNode> indirect_node, bool

auto initial_source = indirect_node->to_mutable().initial_source();
auto initial_offset = indirect_node->to_mutable().initial_offset();
if (!initial_source.expired()) {
if (!initial_source.is_expired()) {
new_source = initial_source;
new_offset = initial_offset;
} else {
Expand Down
Loading
Loading