internal/impl: optimize oneof unmarshaling and serialization by precomputing itabs

Precompute the canonical interface itab for oneof wrapper structs during
coder initialization. This enables oneof field unmarshaling and serialization
to inspect and assign interface values directly via [2]unsafe.Pointer without
reflection (reflect.ValueOf, reflect.New, reflect.Value.Set) overhead.

If the interface already holds an instance of the target oneof wrapper struct,
the existing wrapper pointer is reused to preserve merge semantics and eliminate
reallocations.

Internal production-shaped micro-benchmarks show significant improvements on
workloads with oneofs:
- Workload 1 (metric oneofs): -35% unmarshal wall time / -25% user CPU
- Workload 2 (request oneofs): -18% unmarshal wall time / -10% user CPU
- Workload 3 (response oneofs): -12% unmarshal wall time / -7% user CPU
Workloads without oneofs remain statistically unchanged.

Change-Id: Ifb9a33c9421aa53a1e6485b576c3dc6c8474e652
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/820341
Reviewed-by: Michael Stapelberg <stapelberg@google.com>
Reviewed-by: Mike Kruskal <mkruskal@google.com>
Reviewed-by: Cassondra Foesch <cfoesch@gmail.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sandy Zhang <sandyzhang@google.com>
diff --git a/internal/impl/codec_field.go b/internal/impl/codec_field.go
index d14d7d9..226dcd1 100644
--- a/internal/impl/codec_field.go
+++ b/internal/impl/codec_field.go
@@ -6,6 +6,7 @@
 
 import (
 	"reflect"
+	"unsafe"
 
 	"google.golang.org/protobuf/encoding/protowire"
 	"google.golang.org/protobuf/internal/errors"
@@ -30,7 +31,7 @@
 func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si structInfo) {
 	fs := si.oneofsByName[od.Name()]
 	ft := fs.Type
-	oneofFields := make(map[reflect.Type]*coderFieldInfo)
+	oneofFieldsByItab := make(map[unsafe.Pointer]*coderFieldInfo)
 	needIsInit := false
 	fields := od.Fields()
 	for i, lim := 0, fields.Len(); i < lim; i++ {
@@ -38,47 +39,57 @@
 		num := fd.Number()
 		// Make a copy of the original coderFieldInfo for use in unmarshaling.
 		//
-		// oneofFields[oneofType].funcs.marshal is the field-specific marshal function.
+		// oneofFieldsByItab[itab].funcs.marshal is the field-specific marshal function.
 		//
 		// mi.coderFields[num].marshal is set on only the first field in the oneof,
-		// and dispatches to the field-specific marshaler in oneofFields.
+		// and dispatches to the field-specific marshaler in oneofFieldsByItab.
 		cf := *mi.coderFields[num]
 		ot := si.oneofWrappersByNumber[num]
 		cf.ft = ot.Field(0).Type
 		cf.mi, cf.funcs = fieldCoder(fd, cf.ft)
-		oneofFields[ot] = &cf
 		if cf.funcs.isInit != nil {
 			needIsInit = true
 		}
+
+		// Precompute interface itab for direct assignment without reflection overhead.
+		sampleIfacePtr := reflect.New(ft)
+		sampleIfacePtr.Elem().Set(reflect.New(ot))
+		itab := pointerOfValue(sampleIfacePtr).asIfaceHeader().Type
+		oneofFieldsByItab[itab] = &cf
+
 		mi.coderFields[num].funcs.unmarshal = func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) {
-			var vw reflect.Value         // pointer to wrapper type
-			vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
-			if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
-				vw = vi.Elem()
+			hdr := p.asIfaceHeader()
+			var ptr pointer
+
+			// If the interface already holds an instance of this oneof variant, reuse it.
+			// This is for correctness to get merge-semantics when seeing the same message twice
+			// in a row, but also slightly helps with efficiency otherwise.
+			// Otherwise, allocate a new wrapper and store both itab and data pointer
+			// directly into the interface without reflection overhead.
+			if hdr.Type == itab && hdr.Data != nil {
+				ptr = pointer{p: hdr.Data}
 			} else {
-				vw = reflect.New(ot)
+				ptr = pointerOfValue(reflect.New(ot))
+				*hdr = ifaceHeader{Type: itab, Data: ptr.p}
 			}
-			out, err := cf.funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, &cf, opts)
+
+			out, err := cf.funcs.unmarshal(b, ptr, wtyp, &cf, opts)
 			if err != nil {
 				return out, err
 			}
 			if cf.funcs.isInit == nil {
 				out.initialized = true
 			}
-			vi.Set(vw)
 			return out, nil
 		}
 	}
 	getInfo := func(p pointer) (pointer, *coderFieldInfo) {
-		v := p.AsValueOf(ft).Elem()
-		if v.IsNil() {
+		// Fast non-reflective extraction of oneof wrapper pointer and coderFieldInfo via itab.
+		hdr := p.asIfaceHeader()
+		if hdr.Type == nil || hdr.Data == nil {
 			return pointer{}, nil
 		}
-		v = v.Elem() // interface -> *struct
-		if v.IsNil() {
-			return pointer{}, nil
-		}
-		return pointerOfValue(v).Apply(zeroOffset), oneofFields[v.Elem().Type()]
+		return pointer{p: hdr.Data}, oneofFieldsByItab[hdr.Type]
 	}
 	first := mi.coderFields[od.Fields().Get(0).Number()]
 	first.funcs.size = func(p pointer, _ *coderFieldInfo, opts marshalOptions) int {
diff --git a/internal/impl/pointer_unsafe.go b/internal/impl/pointer_unsafe.go
index 62f8bf6..2672210 100644
--- a/internal/impl/pointer_unsafe.go
+++ b/internal/impl/pointer_unsafe.go
@@ -48,15 +48,24 @@
 	return pointer{p: unsafe.Pointer(v.Pointer())}
 }
 
+// ifaceHeader is the memory layout of an interface (both iface and eface).
+// For a non-empty interface (iface), Type is *runtime.itab.
+// For an empty interface (eface / any), Type is *runtime._type.
+type ifaceHeader struct {
+	Type unsafe.Pointer
+	Data unsafe.Pointer
+}
+
 // pointerOfIface returns the pointer portion of an interface.
 func pointerOfIface(v any) pointer {
-	type ifaceHeader struct {
-		Type unsafe.Pointer
-		Data unsafe.Pointer
-	}
 	return pointer{p: (*ifaceHeader)(unsafe.Pointer(&v)).Data}
 }
 
+// asIfaceHeader returns p as a pointer to an interface header.
+func (p pointer) asIfaceHeader() *ifaceHeader {
+	return (*ifaceHeader)(p.p)
+}
+
 // IsNil reports whether the pointer is nil.
 func (p pointer) IsNil() bool {
 	return p.p == nil