diff options
author | Joshua Haberman <joshua@reverberate.org> | 2009-12-05 18:06:50 -0800 |
---|---|---|
committer | Joshua Haberman <joshua@reverberate.org> | 2009-12-05 18:06:50 -0800 |
commit | 651c92ab33187b34d7878ac57427bbbc062662fa (patch) | |
tree | 1049aebdaf255ddd344237fb972ac8d39fa7d353 /src/upb_def.h | |
parent | 18291eedc3cb6bf4386698620ad9d02ad367126a (diff) |
Scheme for collecting circular refs.
"make descriptorgen" is now valgrind-clean again.
Diffstat (limited to 'src/upb_def.h')
-rw-r--r-- | src/upb_def.h | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/src/upb_def.h b/src/upb_def.h index 7c8cf80..09ae5d2 100644 --- a/src/upb_def.h +++ b/src/upb_def.h @@ -46,21 +46,36 @@ enum upb_def_type { UPB_DEF_UNRESOLVED }; +// This typedef is more space-efficient than declaring an enum var directly. +typedef uint8_t upb_def_type_t; + // Common members. struct upb_def { struct upb_string *fqname; // Fully qualified. - enum upb_def_type type; + upb_def_type_t type; + + // These members that pertain to cyclic collection could technically go in + // upb_msgdef instead of here, because only messages can be involved in + // cycles. However, putting them here is free from a space perspective + // because structure alignment will otherwise leave three bytes empty between + // type and refcount. It is also makes ref and unref more efficient, because + // we don't have to downcast to msgdef before checking the is_cyclic flag. + bool is_cyclic; // Is this def part of a cycle? + upb_field_count_t visiting_submsg; // Helper for depth-first search. + + // See .c file for description of refcounting scheme. upb_atomic_refcount_t refcount; + upb_atomic_refcount_t cycle_refcount; }; -void _upb_def_free(struct upb_def *def); // Must not be called directly! +void _upb_def_reftozero(struct upb_def *def); // Must not be called directly! // Call to ref/deref a def. INLINE void upb_def_ref(struct upb_def *def) { upb_atomic_ref(&def->refcount); } INLINE void upb_def_unref(struct upb_def *def) { - if(upb_atomic_unref(&def->refcount)) _upb_def_free(def); + if(upb_atomic_unref(&def->refcount)) _upb_def_reftozero(def); } // Downcasts. They are checked only if asserts are enabled. @@ -93,8 +108,8 @@ struct upb_fielddef { struct upb_string *name; // These are set only when this fielddef is part of a msgdef. - uint32_t byte_offset; // Where in a upb_msg to find the data. - uint16_t field_index; // Indicates set bit. + uint32_t byte_offset; // Where in a upb_msg to find the data. + upb_field_count_t field_index; // Indicates set bit. // For the case of an enum or a submessage, points to the def for that type. // We own a ref on this def. @@ -156,7 +171,7 @@ struct upb_msgdef { struct upb_def base; struct upb_msg *default_msg; // Message with all default values set. size_t size; - uint32_t num_fields; + upb_field_count_t num_fields; uint32_t set_flags_bytes; uint32_t num_required_fields; // Required fields have the lowest set bytemasks. struct upb_fielddef *fields; // We have exclusive ownership of these. |