@@ -36,6 +36,28 @@ platform_lock Graph::_all_graphs_lock = PLATFORM_LOCK_INIT;
3636
3737pthread_key_t Graph::_current_update_key = 0 ;
3838
39+ namespace {
40+
41+ bool attribute_page_is_allocated (AttributeID attribute) {
42+ if (!attribute || attribute.is_nil ()) {
43+ return false ;
44+ }
45+ return data::table::shared ().raw_page_seed (attribute.page_ptr ()) & 0xff00000000 ;
46+ }
47+
48+ bool attribute_zone_is_live (AttributeID attribute) {
49+ if (!attribute || attribute.is_nil ()) {
50+ return false ;
51+ }
52+ auto raw_page_seed = data::table::shared ().raw_page_seed (attribute.page_ptr ());
53+ if (!(raw_page_seed & 0xff00000000 )) {
54+ return false ;
55+ }
56+ return !data::zone::info::from_raw_value (uint32_t (raw_page_seed)).is_deleted ();
57+ }
58+
59+ } // namespace
60+
3961Graph::Graph ()
4062 : _heap(nullptr , 0 , 0 ), _interned_types(nullptr , nullptr , nullptr , nullptr , &_heap),
4163 _contexts_by_id (nullptr , nullptr , nullptr , nullptr , &_heap), _id(IAGMakeUniqueID()) {
@@ -552,23 +574,40 @@ void Graph::remove_indirect_node(data::ptr<IndirectNode> indirect_node) {
552574}
553575
554576void Graph::remove_removed_input (AttributeID attribute, AttributeID input) {
577+ // An indirect input in the current invalidation batch can have a deleted
578+ // zone while still resolving to a live source, so only require its page to
579+ // remain allocated until after resolution.
580+ if (!attribute_page_is_allocated (input)) {
581+ return ;
582+ }
583+
555584 auto resolved_input =
556585 input.resolve (TraversalOptions::SkipMutableReference | TraversalOptions::EvaluateWeakReferences).attribute ();
586+ if (!attribute_zone_is_live (resolved_input)) {
587+ return ;
588+ }
589+
590+ auto input_subgraph = resolved_input.subgraph ();
591+ if (!input_subgraph || input_subgraph->graph () != this || !input_subgraph->is_valid ()) {
592+ return ;
593+ }
594+
557595 if (auto input_node = resolved_input.get_node ()) {
558- if (!resolved_input.subgraph ()->is_invalidated ()) {
559- remove_output_edge (input_node, attribute);
560- }
596+ remove_output_edge (input_node, attribute);
561597 } else if (auto input_indirect_node = resolved_input.get_indirect_node ()) {
562- if (!resolved_input.subgraph ()->is_invalidated ()) {
563- if (input_indirect_node->is_mutable ()) {
564- remove_output_edge (input_indirect_node.unsafe_cast <MutableIndirectNode>(), attribute);
565- }
598+ if (input_indirect_node->is_mutable ()) {
599+ remove_output_edge (input_indirect_node.unsafe_cast <MutableIndirectNode>(), attribute);
566600 }
567601 }
568602}
569603
570604bool Graph::remove_removed_output (AttributeID attribute, AttributeID output, bool option) {
571- if (output.subgraph ()->is_invalidated ()) {
605+ if (!attribute_zone_is_live (output)) {
606+ return false ;
607+ }
608+
609+ auto output_subgraph = output.subgraph ();
610+ if (!output_subgraph || output_subgraph->graph () != this || !output_subgraph->is_valid ()) {
572611 return false ;
573612 }
574613
0 commit comments