-
-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Specialize generic types and methods #604
Merged
Merged
Conversation
This file contains 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
9bef3af
to
217bc04
Compare
Note to self: disallow trait types anywhere but in type parameter requirements, meaning any method using traits in arguments must be turned into a generic method. This makes things more consistent, and solves the age old discussion of "Should I use generics, or force dynamic dispatch using trait types?". This should also solve some outstanding covariance soundness issues (e.g. #502). |
4693392
to
0d4d064
Compare
dcd5aaa
to
bc8fa2b
Compare
4c902a9
to
284a9bb
Compare
805ad87
to
20a91cb
Compare
7d601a9
to
93d8f57
Compare
93d8f57
to
6f132cd
Compare
ae3d42b
to
6e4bff0
Compare
This commit implements type and method specialization. This removes the need for runtime pointer tagging and allows unboxed Int and Float values. In addition, the use of specialization may allow for more optimizations in the future. The implementation is a little different from other languages. Instead of specializing generics over every type assigned to a generic type parameter, types are grouped into "shapes", and we specialize over shapes. Int, Float, Bool, Nil, String, and atomic types (channels and processes) get their own shapes, so we can generate slightly different code for each. Other owned values are all grouped into the "owned" shape, while immutable and mutable references go in the "ref" and "mut" shapes respectively. This is done because such values are always addressed through pointers, and thus specializing every type/method over such types results in many types/methods with virtually identical code. The nice thing about this setup is that we can provide a better balance between fast compile times and good runtime performance. In addition, a future version of the compiler could be extended to dynamically create shapes for types where this makes sense (e.g. if we at some point decide to stack allocate certain types). For generics that are assigned the "owned", "ref" or "mut" shape we use dynamic dispatch, while for Int, Float, etc we use static dispatch. Our dynamic dispatch strategy is generally fast enough to permit this, and it means you don't have to decide between using generics and explicit dynamic dispatch; instead you use generics most of the time and leave it up to the compiler to compile the code efficiently. This does require some restrictions to be put in place. Most notably, Int, Float and String can no longer be cast to traits, and types are no longer implicitly compatible with traits and instead require explicit casts. Int and Float can't be used in dynamic dispatch contexts because they are unboxed values, and thus there's no header/class we can use for dynamic dispatch. String isn't allowed because of its use of atomic reference counting, and supporting that would incur an additional cost for every dynamic dispatch call site. In practise none of this should be an issue, as these types are rarely used in dynamic dispatch contexts. This commit also includes various smaller tweaks to the standard and runtime library, such as the removal of `std.channel.wait` (because it's a performance trap), and the ability to use generics with raw pointers (i.e. `Pointer[T]` and `Pointer[String]` are now valid). These changes are less interesting though, and were needed in response to/to facilitate the specialization changes. This fixes #502. Changelog: changed
6e4bff0
to
3057ba7
Compare
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 implements specialization of generics as outlined in #525. See the commit(s) for more details.
This fixes #525