Repository navigation
Add new fields to tables without a metatable directly in the SETFIELD slow path - #49
Merged
Merged
Conversation
…directly A SETFIELD that adds a key, as every field of a table just built, missed the loop's hint and went through newindex, which looked the key up twice, hashed it at run time and measured the table before and after. constSet probes with the constant's compile-time hash and inserts when no resize is needed; other cases still go to newindex. The loop itself is unchanged: an inline insert there pushes fast past the inliner's big-function threshold.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A SETFIELD that adds a key misses the loop's site hint, because the key is not in the table yet. That is every field written into a table just built, as in
setmetatable({x = x, y = y}, Point), orself.z = zin a constructor. The miss went tonewindex, which:Get, thenfindNodeinset),constSethandles these writes in the slow path when the table has no metatable, is not frozen or guarded, and the key does not start with__. It probes with the constant's hash computed at compile time, asconstFielddoes for reads. It sets the key if it is there, or adds it withinsertwhen no resize is needed, then learns the hint. Every other case still goes tonewindex. With no resize, the table's size doesn't change, so nothing needs to be charged.insertnow returns the node index.The insert is not done inside the loop. Doing it there makes
fastlarger than the inliner's big-function threshold. Small helpers likesetIntandsetBoolthen become calls, and every opcode spills; asmgate catches this.Effect, fast loop unless noted:
A new case in
testdata/meta.lua, with its expected output from C Lua, covers:__newindexon absent and present keys,__key added to a table that is in use as a metatable.