Skip to content

Simplify GDType by storing all properties in a single unified map. Save ~12mb runtime RAM - #122751

Open
Ivorforce wants to merge 1 commit into
godotengine:masterfrom
Ivorforce:gdtype-simplify-props
Open

Simplify GDType by storing all properties in a single unified map. Save ~12mb runtime RAM#122751
Ivorforce wants to merge 1 commit into
godotengine:masterfrom
Ivorforce:gdtype-simplify-props

Conversation

@Ivorforce

@Ivorforce Ivorforce commented Aug 23, 2026

Copy link
Copy Markdown
Member

What problem(s) does this PR solve?

Reduces RAM usage of the editor by ~13mb.
This was done in follow-up to #122596, where a ~25mb increase was deemed acceptable for the performance improvement. This PR brings it back down by ~13mb (to around +12mb net plus).

Additional information

The reduction was achieved by consolidating all property information into a single map (or rather, one self + one aggregated) such that keyvalues are deduplicated.

As a side benefit (or if I'm being honest, perhaps the main benefit long term), the new code makes it structurally impossible to have colliding property names, which decreases the risk of bugs as this code evolves or is used.
It's also arguably more predictable, since all properties are accessed in the same way.

This also fixes a regression from earlier GDType PRs where disabled classes' methods are not hidden as expected.

Enums are now also part of an object's namespace: Object.Enum.Value resolves, so clearly Object claims the member Enum. Since enums are not types, there's nothing logical to return, but it IS handled in the same way that other non-existing namespaces are (e.g. Object.property when property has no getter is also handled, though notably without erroring (which is also kind of odd)).

Tests

I tested the RAM decrease with the test from #122596.

@Ivorforce Ivorforce added this to the 4.x milestone Aug 23, 2026
@Ivorforce
Ivorforce requested review from a team as code owners August 23, 2026 22:00
@Ivorforce
Ivorforce force-pushed the gdtype-simplify-props branch from c0c7c22 to ab7d862 Compare August 23, 2026 22:13
@Ivorforce
Ivorforce requested a review from a team as a code owner August 23, 2026 22:13
@Ivorforce
Ivorforce force-pushed the gdtype-simplify-props branch 7 times, most recently from c142860 to 21544be Compare August 24, 2026 11:13
@Ivorforce
Ivorforce requested a review from a team as a code owner August 24, 2026 11:13
Comment thread core/object/gdtype.h
bool is_bitfield = false;
};

struct Property {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems weird to call a method "property". Shouldn't the struct be called Member? Then SETGET could be changed to PROPERTY, because that's what it is.
#bikeshedding

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming was adopted from several earlier pieces of code referring to this concept as "property".

However, i agree it's a little confusing, especially since that means the "actual" properties ended up being called "setgets".

I'm open to changing it (e.g. members and properties) but I'd rather address that in a separate PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll admit I doubted myself for a second when I saw methods being registered as a property in the previous PR. Had to search online to make sure I wasn't going crazy thinking that methods aren't properties.
I'd more than welcome a style PR to fix this naming "quirk".

@Ivorforce
Ivorforce force-pushed the gdtype-simplify-props branch from 21544be to ca88ee0 Compare August 24, 2026 11:23
@Ivorforce
Ivorforce force-pushed the gdtype-simplify-props branch from ca88ee0 to 7bdffae Compare August 24, 2026 12:01

@StarryWorm StarryWorm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks mostly good to me, some minor concerns/comments below.

Comment thread core/object/class_db.cpp
Locker::Lock lock(Locker::STATE_READ);

ClassInfo *type = classes.getptr(p_class);
for (const KeyValue<StringName, const MethodBind *> &kv : type->gdtype->get_method_map(p_no_inheritance)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change (and similar ones below), which restores the behavior for disabled types from before #117599, should be listed in the additional information in the PR description imo, since it is a technically unnecessary functional change.
See comment thread here: #117599 (review)
I agree with the change, as it restores lost behavior; however, it may come with a slight performance cost because it needs to iterate up the inheritance tree. In the future, the type disabling system should be taken a good look at (and likely removed entirely; I haven't been able to find users yet).

@Ivorforce Ivorforce Aug 24, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, I noted this bug while coding but ended up uploading the PR a few days later so I forgot to mention it.

Good thing you brought it up!

Comment thread core/object/object.cpp
Comment thread core/object/object.cpp
*r_valid = false;
}
r_value = Variant();
return true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the behavior for enums from returning false to returning true. Looking at callers of this method, it doesn't seem like it would pose an issue anywhere. It might actually give a slight performance boost to Object::get() in the enum case.
Someone more experienced with it would need to double-check that the resulting GDScript VM's OPCODE(OPCODE_GET_MEMBER) behavior change does not have any negative downstream impacts, as it would have returned an error and triggered OPCODE_BREAK in the past for enums in the DEBUG_ENABLED case (since this method would return false).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was an intentional decision: Object.Enum.Value resolves, so clearly Object.Enum is a claimed namespace. I'd consider the fact that it's not handled right now to be a bug, or at least an inconsistency in the program's logic.

But yea, good to highlight it!

StarryWorm

This comment was marked as duplicate.

@Repiteo Repiteo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated tests look good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants