Conversation
There was a problem hiding this comment.
Review: static itab for known T2I conversions
This is a clean, well-scoped change. staticItab now emits a compile-time itab global for known T2I conversions (interface with methods + assignable concrete type) and unsafeInterface uses it directly instead of always calling runtime.NewItab. Because I2I still goes through NewItab, the two representations of the same dynamic type can hold different tab pointers, so interequal correctly gains a type-pair fallback.
Correctness verified:
interequalfast path (x.tab == y.tab) is preserved; the new branch runs only on pointer mismatch and is nil-safe (thex.tab == nil || y.tab == nilguard precedes the field access atalg.go:265).- The fallback compares canonical descriptor pointers (
inter,_type).abiType/abiIntfglobals are name-canonicalized withWeakODRLinkage, so the static itab'sinter/_typeare the same pointersNewItabstores — pointer equality holds within a binary. It still callsifaceeq, so data comparison is retained. interhash(alg.go:103) andTypeAssert(interface.go:422) key ontab._type, not the itab pointer, so map hashing and type assertions stay consistent across both representations.- The static itab
hashfield matchesabiCommonFields(sha256(typeName)[:4]), so type-switch/hash paths agree — the added comment atinterface.go:88is accurate.
Findings (all non-blocking):
-
Test coverage gap for the
interequalfallback — inline oncl/_testrt/staticitab/in.go. The new fallback branch (alg.go:262-265) is the reason for this PR, but the new test only exercises the fast path. -
Stale comment in
cl/_testlto/globaldce_static_itab_devirt/in.go:50-52(outside the diff hunk, so noted here). The comment still reads:// Interface equality relies on canonical runtime itab identity. The static template is analysis-only; the direct conversion must still agree with an interface assembled through reflection.
Both claims now describe the old behavior. Equality no longer relies on itab-pointer identity (the whole point of theinterequalchange), and the static itab is used directly for T2I rather than being "analysis-only". This is the same stale wording removed elsewhere in the PR ("compile-time certificate", "template disappears before GlobalDCE") — this occurrence was missed. The adjacent SYMBOL check on line 8 was correctly flipped fromSYMBOL-NOTtoSYMBOL-DAG: _llgo_itab, so only the prose is out of date. -
Minor (compile-time only): in
staticItab, the twoabi.TypeNamelookups +sha256+ base64 that build the global name run on every call before theVarOf(name)dedup check (interface.go:67-73). For repeated T2I sites of the same (interface, type) pair this is redundant work per site. Optional: key a fast in-memory map on(rawIntf, concrete)before hashing. No runtime or binary-size impact.
No correctness or security defects found.
| panic(i.M()) | ||
| } | ||
| j := boxed(T(41)) | ||
| if i != j { |
There was a problem hiding this comment.
The interequal change in runtime/internal/runtime/alg.go adds a fallback branch (comparing inter/_type when itab pointers differ) specifically to handle a T2I static-itab value compared against an I2I NewItab value. But this test never exercises that branch: both i (var i I = T(41)) and j (boxed(T(41))) are T2I conversions, and the static-itab global name is a hash of (intfName, typeName), so both resolve to the same global. x.tab == y.tab holds and the comparison takes the fast path — a regression in the fallback would still pass here.
Consider adding a case where one operand is produced via I2I (e.g. through ChangeInterface / assigning via a second interface type so unsafeInterface is reached with a nil concrete and routes to newItab) so the two operands have different tab pointers, plus an inequality check against a different concrete type.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
Timer runtime benchmarks
Compared with |
LLGo WebAssembly build benchmarks
WebAssembly output sizes
LLGo WebAssembly build measurements
Compared with |
22abddd to
916df42
Compare
Known concrete-to-interface conversions emit a read-only _llgo_itab$ global (Inter, Type, Hash, Fun) with weak_odr linkage, matching cmd/compile's go:itab symbols. Ordinary builds use that global as the runtime vtable. After function bodies compile, path.init$itabs registers those itabs with RegisterStaticItab, after runtime.init and before package init (gc itabsinit). LTO and deadcode-drop keep calling NewItab so unused interface methods can be dropped; Fun[] would pin them. LTO still emits the static template for de-virt. Hash is copied from the type descriptor when present. interequal compares the (inter, _type) pair so a static itab and a dynamically allocated itab for the same conversion compare equal.
916df42 to
8336268
Compare
Summary
Known concrete-to-interface (
T2I) conversions emit a read-only_llgo_itab$global ({Inter, Type, Hash, Fun[]}) withweak_odrlinkage, matching cmd/compile'sgo:itabsymbols. Identification is by type: the method set is complete andtypes.AssignableToholds.Ordinary builds use that global as the runtime vtable. After function bodies compile,
path.init$itabsregisters those itabs withRegisterStaticItab, afterruntime.initand before packageinit(gcitabsinit). LTO and deadcode-drop keep callingNewItabso unused interface methods can be dropped (Fun[]would pin them). LTO still emits the static template for de-virt.NewItabremains forI2Iand for types only known at runtime. Hash is copied from the type descriptor when present.interequalcompares the(inter, _type)pair so a static itab and a dynamically allocated itab for the same conversion compare equal.Stack: first of four. Independent of the later PRs.
Test plan
go test ./ssacl/_testrt/staticitab(includingany(T).(I)equality)go test ./cl -run TestRunAndTestFromTestmetago test -tags=devLTO plugin tests (TestBuildAndCheckSymbolsFromTestltoLTOPlugin,TestLTOPluginAggregateStaticItabDevirt)go test -tags=dev -run TestBuildAndCheckSymbolsFromTestdrop ./cl(includinginterface_match)TestTypeHashFromGlobal,TestRuntimeStaticItabUsesVtableAndInitItabs,TestDeclareStaticItabInits