This isn't causing any functional problem today, but technically
`mapped[tls_offset..]` runs past the tls part of `mapped` and into
the `Instance` storage, and currently `prepareArea()` memsets its
entire argument to zero. It is only the current layout and
initialization order of `mapped` that prevents this from being a
problem. Being more precise here avoids future footguns if any of
that changes.
MachO has a mechanism where symbols can introduce "subsections", which
(as I understand it) allows a linker to garbage-collect parts of
sections without pulling in the heavy machinery of `-fdata-sections` and
`-ffunction-sections`. Essentially, symbols can be considered to
partition a section, and these boundaries are not allowed to be crossed
by memory accesses, so the linker can detect symbols which are unused
and drop the corresponding input section regions.
However, the symbol flag `N_ALT_ENTRY` indicates that a symbol should
not participate in this "splitting", and is instead an "alternate entry
point" to the previous subsection, which should continue through this
symbol.
The Mach-O linker was failing to ignore `N_ALT_ENTRY` symbols when
creating subsections, which meant that for certain link inputs, it would
create additional subsection splits, and then garbage collect the extra
sections (due to the `N_ALT_ENTRY` symbol being unused). Naturally, this
silent dropping of parts of input sections led to miscompilations.
The changes to the LLVM backend here changed the compiler_rt object
which LLVM emits, and exposed some buggy behavior in the self-hosted
WASM linker when parsing that object.
These all pass now! I have also removed the warning about the LLVM
backend not supporting incremental compilation; I expect it will work
sort of okay in practice by now.
The main goal here is to make incremental compilation work a bit better.
I also slightly expanded some `std.zig.llvm.Builder` APIs so that we
don't need to pointlessly create new `Global`s whenever e.g. a function
turns into a variable or vice versa.
Also, lean into aliases for exports! If we just use aliases for every
export, everything becomes simpler. Besides, we can't just go around
renaming the globals of `Nav`s: the export could disappear on a future
update, in which case we'd have to somehow revert that change, which is
easier said than done.
Avoid directly querying `Builder.Type`s in favour of `lowerType` calls
in a couple of places. The idea here is to avoid querying state stored
in the `Builder` to try and move towards a world where codegen
(essentially the logic in `codegen.llvm.FuncGen`) can happen on a
separate thread to "linking" (which actually interacts with shared state
on `codegen.llvm.Object` and `std.zig.llvm.Builder`).
Don't clear the `Builder` state during `emit`; this is clearly
incompatible with incremental compilation. With that line of code
removed, incremental compilation is actually already somewhat functional
with the LLVM backend.
Also, don't use `c_uint` for source location state---I have no idea
where this came from but it definitely isn't correct.
Also, notably, remove `Air.value`! The `onePossibleValue` check was
actually dead code, because it is a bug if Sema ever emits code which
considers a value of OPV type to be runtime-known---and at that point
`Air.value` is just a thin wrapper around `Air.Ref.toInterned`.
LLVM is gradually transitioning from the `getelementptr` instruction to
a new `ptradd` instruction. The latter instruction doesn't actually
exist yet, but for now, LLVM is considering `getelementptr i8` to be
equivalent. LLVM is already internally canonicalizing `getelementptr`
usages to this pattern in many cases, and it's far easier for us to emit
that, so... let's do so!
For runtime indexing this does sometimes require an explicit
multiplication to scale an index to a byte offset. The helper function
`llvm.FuncGen.ptraddScaled` makes this common pattern more convenient.
A particularly nice side effect from this is that after removing some
dead code (left over from before we made all `struct`s etc by-ref), it
has eliminated the need to maintain that nasty mapping between Zig field
indices and LLVM field indices. `FuncGen` no longer cares at all how
aggregate types are lowered!
Slices are still by-val at least for now, but they never lived in that
mapping because their structure is simple and consistent (they always
have a pointer at field index 0 and a usize at field index 1, with no
explicit padding necessary).
This mostly just moves `FuncGen` into its own file, but there are also a
few more cleanups, such as removing `NavGen` (it no longer served any
purpose) and slightly simplifying the logic for emitting codegen errors.
Users can proceed by telling the build system how much memory to assume
the system has. I have improved the failure message to communicate this.
Partially reverts 87f8f47ba5
Even if we wanted to unrevert this reverted commit, it's not sufficient
to merely downgrade the failure to a warning, because the main
scheduling logic will fail to schedule steps that have a max_rss
exceeding the detected system value, causing some steps to never get
executed, eventually tripping an assert. Such a change would need to
also override the max_rss value to be equal to the greatest value across
all steps.
closes#31510
This number should never be raised. If the value is exceeded, then it is
considered a bug in the Zig project that building the compiler takes
more than 8G of memory.
Partial revert of 1293f080fd
Deprioritizes #31510
RFC 9110 says
> It is RECOMMENDED that all senders and recipients support, at a minimum,
> URIs with lengths of 8000 octets in protocol elements.
closes#30207
Previously, each message requires an unseekable error to be returned
from a syscall before proceeding. Ideally, the code would just pass
around `*std.Io.Writer` instead of `std.Io.File` in the first place, but
even then, you could argue for saving a syscall with `writerStreaming`.