| Age | Commit message (Collapse) | Author |
|
All but 2 test cases now pass (tested on x86_64 Linux, native only). The
remaining two signify an issue requiring a larger refactor, which I will
do in a separate commit.
Notable changes:
* Fix uninitialized memory when allocating objects from free lists
* Implement TypedValue printing for pointers
* Fix some TypedValue printing logic
* Work around non-existence of InternPool.remove implementation
|
|
|
|
This is a workaround for InternPool currently not handling
non-null-terminated strings. It avoids using the `bytes` storage for
aggregates if there are any null bytes.
In the future this should be changed so that the `bytes` storage can be
used regardless of whether there are any null bytes. This is important
for use cases such as `@embedFile`.
However, this fixes a bug for now, and after this commit, stage2
self-hosts again.
mlugg: stage5 passes all enabled behavior tests on my system.
Commit message edited by Andrew Kelley <andrew@ziglang.org>
|
|
In an effort to delete `Value.hashUncoerced`, generic instantiation has
been redesigned. Instead of just storing instantiations in
`monomorphed_funcs`, partially instantiated generic argument types are
also cached. This isn't quite the single `getOrPut` that it used to be,
but one `get` per generic argument plus one get for the instantiation,
with an equal number of `put`s per unique instantiation isn't bad.
|
|
|
|
InternPool is nice in some ways but it also comes with its own set of
footguns. This commit fixes 5 instances. I see quite a few Valgrind
warnings remaining when running the behavior tests.
Perhaps the solution is to have stringToSlice return a struct with start
and length as indexes, which has a format function?
|
|
The main motivation for this commit is eliminating Decl.value_arena.
Everything else is dominoes.
Decl.name used to be stored in the GPA, now it is stored in InternPool.
It ended up being simpler to migrate other strings to be interned as
well, such as struct field names, union field names, and a few others.
This ended up requiring a big diff, sorry about that. But the changes
are pretty nice, we finally start to take advantage of InternPool's
existence.
global_error_set and error_name_list are simplified. Now it is a single
ArrayHashMap(NullTerminatedString, void) and the index is the error tag
value.
Module.tmp_hack_arena is re-introduced (it was removed in
eeff407941560ce8eb5b737b2436dfa93cfd3a0c) in order to deal with
comptime_args, optimized_order, and struct and union fields. After
structs and unions get moved into InternPool properly, tmp_hack_arena
can be deleted again.
|
|
This is necessary with the upcoming removal of Decl.value_arena to
prevent UAF of these values.
|
|
This eliminates the last major use of value_arena, in preparation to
remove it.
|
|
This is neither a type nor a value. Simplifies `addStrLit` as well as
the many places that switch on `InternPool.Key`.
This is a partial revert of bec29b9e498e08202679aa29a45dab2a06a69a1e.
|
|
Key.PtrType is now an extern struct so that hashing it can be done by
reinterpreting bytes directly. It also uses the same representation for
type_pointer Tag encoding and the Key. Accessing pointer attributes now
requires packed struct access, however, many operations are now a copy
of a u32 rather than several independent fields.
This function moves the top two most used Key variants - pointer types
and pointer values - to use a single-shot hash function that branches
for small keys instead of calling memcpy.
As a result, perf against merge-base went from 1.17x ± 0.04 slower to
1.12x ± 0.04 slower. After the pointer value hashing was changed, total
CPU instructions spent in memcpy went from 4.40% to 4.08%, and after
additionally improving pointer type hashing, it further decreased to
3.72%.
|
|
The Zig language allows the compiler to make this optimization
automatically. We should definitely make the compiler do that, and
revert this commit. However, that will not happen in this branch, and I
want to continue to explore achieving performance parity with
merge-base. So, this commit changes all InternPool parameters to be
passed by const pointer rather than by value.
I measured a 1.03x ± 0.03 speedup vs the previous commit compiling the
(set of passing) behavior tests. Against merge-base, this commit is
1.17x ± 0.04 slower, which is an improvement from the previous
measurement of 1.22x ± 0.02.
Related issue: #13510
Related issue: #14129
Related issue: #15688
|
|
|
|
|
|
|
|
|
|
|
|
This avoids memory management bugs with the previous implementation.
|
|
|
|
|
|
|
|
This makes the difference between `decl.getOwnedFunction` and
`decl.val.getFunction` more clear when reading the code.
|
|
|
|
|
|
|
|
I'm not sure if this is the right place for this to happen, and
it should become obsolete when comptime mutation is rewritten
and the remaining legacy value tags are remove, so keeping this
as a separate revertable commit.
|
|
Some uses have been moved to their own tag, the rest use interned.
Also, finish porting comptime mutation to be more InternPool aware.
|
|
Reinstate some tags that will be needed for comptime init.
|
|
|
|
Store `InternPool.Index` as the key instead which means that an AIR
instruction no longer needs to be burned to store the type, and also
that we can use AutoArrayHashMap instead of an ArrayList, which avoids
storing duplicates into the set, potentially saving CPU time.
|
|
|
|
|
|
Now, all types are migrated to use `InternPool`. The `Type.Tag` enum is
deleted in this commit.
|
|
This was only needed when pointers were not fully migrated to InternPool
yet.
|
|
This allows some code (like struct initializers) to use interned types
while other code (such as comptime mutation) continues to use legacy
types.
With these changes, an `zig build-obj empty.zig` gets to a crash on
missing interned error union types.
|
|
One change worth noting in this commit is that `module.global_error_set`
is no longer kept strictly up-to-date. The previous code reserved
integer error values when dealing with error set types, but this is no
longer needed because the integer values are not needed for semantic
analysis unless `@errorToInt` or `@intToError` are used and therefore
may be assigned lazily.
|
|
Now pointer types are stored only in InternPool.
|
|
Also I moved `anyframe` from being represented by `SimpleType` to being
represented by the `none` tag of `anyframe_type` because most code wants
to handle these two types together.
|
|
|
|
I'm seeing a new assertion trip: the call to `enumTagFieldIndex` in the
implementation of `@Type` is attempting to query the field index of an
union's enum tag, but the type of the enum tag value provided is not the
same as the union's tag type. Most likely this is a problem with type
coercion, since values are now typed.
Another problem is that I added some hacks in std.builtin because I
didn't see any convenient way to access them from Sema. That should
definitely be cleaned up before merging this branch.
|
|
These are now handled by the InternPool.
|
|
|
|
Unlike unions and structs, enums are actually *encoded* into the
InternPool directly, rather than using the SegmentedList trick. This
results in them being quite compact, and greatly improved the ergonomics
of using enum types throughout the compiler.
It did however require introducing a new concept to the InternPool which
is an "incomplete" item - something that is added to gain a permanent
Index, but which is then mutated in place. This was necessary because
enum tag values and tag types may reference the namespaces created by
the enum itself, which required constructing the namespace, decl, and
calling analyzeDecl on the decl, which required the decl value, which
required the enum type, which required an InternPool index to be
assigned and for it to be meaningful.
The API for updating enums in place turned out to be quite slick and
efficient - the methods directly populate pre-allocated arrays and
return the information necessary to output the same compilation errors
as before.
|
|
|
|
|
|
|
|
|
|
Also modify coercion in Sema to be InternPool-aware by calling
getCoerced.
The unnecessary comptime logic in mod.intValue is deleted too
|
|
|
|
This commit changes a lot of `*const Module` to `*Module` to make it
work, since accessing the integer tag type of an enum might need to
mutate the InternPool by adding a new integer type into it.
An alternate strategy would be to pre-heat the InternPool with the
integer tag type when creating an enum type, which would make it so that
intTagType could accept a const Module instead of a mutable one,
asserting that the InternPool already had the integer tag type.
|