UnlinkedMetadataTable: hold only the offset table while no CodeBlock is linked
Split out of the startup-snapshot branch (#397's description: "the UnlinkedMetadataTable compaction that used to be here is unrelated to snapshots and will be proposed separately"). Independent of #494/#495.
What
UnlinkedMetadataTable::finalize() allocated valueProfiles + LinkingData + offset table + all metadata entries as one buffer, and the bytecode-cache decoder (CachedMetadataTable::decode → the 3-argument constructor) allocated the same full-size buffer for every function it decoded. The UnlinkedCodeBlock then owned that buffer for its lifetime: the first link() shared it, later ones copied, and when the sharing MetadataTable died unlink() only cleared m_isLinked — the value-profile/metadata bytes stayed allocated with no CodeBlock using them. For executables generated from a bytecode cache the UnlinkedCodeBlock edge is strong, so that is the life of the process.
Now the unlinked state holds only the offset table (s_offset16TableSize, plus the 32-bit table when needed). link() always allocates a fresh zeroed LinkingData + totalSize buffer and copies the offset table in (the first link previously reused the finalize-time buffer and memset it; same cost). unlink() of the owning table frees it and keeps a compact copy of the offset table. buffer()/offsetTable16()/offsetTable32() go through prefixSize(), which is 0 while unlinked. The cache decoder's constructor loses its now-unused lastOffset parameter.
MetadataTable::destroy already documents that unlink frees the table's memory and destroys LinkingData first; sizeInBytesForGC(MetadataTable&) still only compares pointers.
Measured
jsc shell, x64 Linux, decoding every function of a 75 MB cache built from a 12 MB minified bundle (48,040 UnlinkedCodeBlocks, none linked): peak RSS 217.4 MB → 174.8 MB (−42.6 MB, ~890 B per unlinked code block). For a running program the same bytes come back whenever a CodeBlock is collected while its UnlinkedCodeBlock survives (aging window, CodeCache, or cache-generated executables).
JSTests/stress (default run + disk-cache run, 5,259 tests): identical pass/fail to main.