Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Register
  • Sign in
  • G GLib
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 877
    • Issues 877
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 60
    • Merge requests 60
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Artifacts
    • Schedules
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Container Registry
    • Model experiments
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • GNOMEGNOME
  • GLib
  • Issues
  • #1437

New properties for GObject

The existing property machinery for GObject is inefficient in various ways:

  • GValue boxing and unboxing all over the place
    • data is copied and freed
    • locks are held
    • even va_list paths end up into GValue, though we already know the final type
  • entry points duplication
    • massive switch inside GObject implementations for set and get
    • the set_property() and get_property() code ends up calling into public API
    • double the validation, double the fun
    • g_object_set() ends up notifying even without state change, unless the class explicitly opts out
  • GParamSpec
    • weird API full of special cases
    • does value validation separately from the GObject instance that installed the property
    • value validation is separate from C types, and always explicit instead of being tied to the type itself (e.g. uint8 needs a uint + [0, 255] GParamSpec)
  • GParamSpecPool
    • singleton instance shared by all classes
    • lock ALL the things
    • run time introspection is expensive
    • decoupled from GObject
  • properties installed at class initialization requires creating classes
    • bad for GObject introspection
    • bad for documentation
    • real library code needs to run, instead of simply using the type system
    • side effects (open display server connections; network; type instantiation; locks)
  • properties on interfaces require playing games with overrides, instead of tying a property to a set/get pair of virtual functions on the interface itself, to be overridden by implementations

Issue #408 (closed) outlined a new API for declaring GObject properties that dealt with validation, value boxing and unboxing, and added automatic generation of accessors to reduce duplication.

Unfortunately it's still missing a solution to avoid a costly property metaclass look up, and it got stuck there. Over the years, we identified a way forward to eliminate the global GParamSpec pool and replace it with per-class GProperty pointers, stored in the class private data structure using a constant offset. This would turn property look up into a cheaper operation than the current implementation.

Blockers

The missing pieces to land this work are:

  • ensure that private data for a GTypeClass is allocated in the same way as the private data for a GTypeInstance, and can be retrieved via pointer arithmetic
  • every time a new property is installed on a class, it gets installed into the private data for the class
  • property accessors generator macros can use the property id and the class private offset to access the GProperty instance from an instance pointer

Issues

  • ideally, we'd really like to have all the property metadata known by the type we register a GType; this would allow us to store the property metadata at a known offset from the start of the class pointer; in practice, this may not really possible because of mixed old-style/new-style inheritance hierarchies. We will need to create a per-class storage pointer to the actual property metaclass storage. New style classes could make it easier by declaring the number and type of properties to be created at type registration time, while old-style classes without properties would pay at most a sizeof(void*) cost in storage.
Edited Jul 27, 2021 by Emmanuele Bassi
Assignee
Assign to
Time tracking