Conversation
This PR is a sketch of an alternative approach to supporting
faster dispatch of calls to built-in methods by avoiding the
allocation ordinarily performed by Builtin.BindReceiver when
a method is accessed and then immediately called as in x.f().
The bound Builtin is still created for g=x.f; g(), or for
values of x that do not implement the new HasBuiltinMethods
interface.
Details:
- Adds HasBuiltinMethods interface implemented by all the
interpreter's built-in types.
- Builtin now has two constructors: the legacy NewBuiltin, and a new
one (NewBuiltinMethod) that takes a function of this form
func(thread *Thread, name string, recv Value, args Tuple, kwargs []Tuple) (Value, error)
-----------------------
avoiding the need to allocate a Builtin with BindReceiver.
The legacy one wraps the newone, possibly at an unacceptable allocation cost
since it calls BindReceiver on every legacy call.
The recv argument is nil for non-method calls.
- x.f(...) is compiled to
recv, callable = ATTR_METHOD(x, "f")
res = CALL(recv, callable, ...)
with a special CALL flag indicating that a receiver is provided
because we used ATTR_METHOD. If callable is an unbound Builtin,
the recv operand is used; otherwise the Builtin supplies the
receiver.
WORK IN PROGRESS. Some parts are slop.
Collaborator
Author
|
Here's the benchstat delta. The big gains are on very unnatural microbenchmarks, so it seems like a lot of trouble for little gain. |
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.
This PR is a sketch of an alternative approach to supporting faster dispatch of calls to built-in methods by avoiding the allocation ordinarily performed by Builtin.BindReceiver when a method is accessed and then immediately called as in x.f().
The bound Builtin is still created for g=x.f; g(), or for values of x that do not implement the new HasBuiltinMethods interface.
Details:
Adds HasBuiltinMethods interface implemented by all the interpreter's built-in types.
Builtin now has two constructors: the legacy NewBuiltin, and a new one (NewBuiltinMethod) that takes a function of this form
func(thread *Thread, name string, recv Value, args Tuple, kwargs []Tuple) (Value, error)
-----------------------
avoiding the need to allocate a Builtin with BindReceiver. The legacy one wraps the newone, possibly at an unacceptable allocation cost since it calls BindReceiver on every legacy call. The recv argument is nil for non-method calls.
x.f(...) is compiled to recv, callable = ATTR_METHOD(x, "f") res = CALL(recv, callable, ...) with a special CALL flag indicating that a receiver is provided because we used ATTR_METHOD. If callable is an unbound Builtin, the recv operand is used; otherwise the Builtin supplies the receiver.
WORK IN PROGRESS. Some parts are slop.