From a1616d4a3271e54d119221c2d263949fae1d4509 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 15 Oct 2014 14:24:18 -0400 Subject: [PATCH] reflect: shorten value to 3 words scalar is no longer needed, now that interfaces always hold pointers. Comparing best of 5 with TurboBoost turned off, on a 2012 Retina MacBook Pro Core i5. Still not completely confident in these numbers, but the gob and template improvements seem real. benchmark old ns/op new ns/op delta BenchmarkBinaryTree17 3819892491 3803008185 -0.44% BenchmarkFannkuch11 3623876405 3611776426 -0.33% BenchmarkFmtFprintfEmpty 119 118 -0.84% BenchmarkFmtFprintfString 294 292 -0.68% BenchmarkFmtFprintfInt 310 304 -1.94% BenchmarkFmtFprintfIntInt 513 507 -1.17% BenchmarkFmtFprintfPrefixedInt 427 426 -0.23% BenchmarkFmtFprintfFloat 562 554 -1.42% BenchmarkFmtManyArgs 1873 1832 -2.19% BenchmarkGobDecode 15824504 14746565 -6.81% BenchmarkGobEncode 14347378 14208743 -0.97% BenchmarkGzip 537229271 537973492 +0.14% BenchmarkGunzip 134996775 135406149 +0.30% BenchmarkHTTPClientServer 119065 116937 -1.79% BenchmarkJSONEncode 29134359 28928099 -0.71% BenchmarkJSONDecode 106867289 105770161 -1.03% BenchmarkMandelbrot200 5798475 5791433 -0.12% BenchmarkGoParse 5299169 5379201 +1.51% BenchmarkRegexpMatchEasy0_32 195 195 +0.00% BenchmarkRegexpMatchEasy0_1K 477 477 +0.00% BenchmarkRegexpMatchEasy1_32 170 170 +0.00% BenchmarkRegexpMatchEasy1_1K 1412 1397 -1.06% BenchmarkRegexpMatchMedium_32 336 337 +0.30% BenchmarkRegexpMatchMedium_1K 109025 108977 -0.04% BenchmarkRegexpMatchHard_32 5854 5856 +0.03% BenchmarkRegexpMatchHard_1K 184914 184748 -0.09% BenchmarkRevcomp 829233526 836598734 +0.89% BenchmarkTemplate 142055312 137016166 -3.55% BenchmarkTimeParse 598 597 -0.17% BenchmarkTimeFormat 564 568 +0.71% Fixes #7425. LGTM=r R=golang-codereviews, r CC=golang-codereviews, iant, khr https://golang.org/cl/158890043 --- src/reflect/makefunc.go | 6 +- src/reflect/type.go | 10 +- src/reflect/value.go | 365 +++++++++------------------------------- 3 files changed, 91 insertions(+), 290 deletions(-) diff --git a/src/reflect/makefunc.go b/src/reflect/makefunc.go index bdb8c21d76..1072c7fabe 100644 --- a/src/reflect/makefunc.go +++ b/src/reflect/makefunc.go @@ -60,7 +60,7 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { impl := &makeFuncImpl{code: code, stack: stack, typ: ftyp, fn: fn} - return Value{t, unsafe.Pointer(impl), 0, flag(Func) << flagKindShift} + return Value{t, unsafe.Pointer(impl), flag(Func) << flagKindShift} } // makeFuncStub is an assembly function that is the code half of @@ -92,7 +92,7 @@ func makeMethodValue(op string, v Value) Value { // Ignoring the flagMethod bit, v describes the receiver, not the method type. fl := v.flag & (flagRO | flagAddr | flagIndir) fl |= flag(v.typ.Kind()) << flagKindShift - rcvr := Value{v.typ, v.ptr, v.scalar, fl} + rcvr := Value{v.typ, v.ptr, fl} // v.Type returns the actual type of the method value. funcType := v.Type().(*rtype) @@ -118,7 +118,7 @@ func makeMethodValue(op string, v Value) Value { // but we want Interface() and other operations to fail early. methodReceiver(op, fv.rcvr, fv.method) - return Value{funcType, unsafe.Pointer(fv), 0, v.flag&flagRO | flag(Func)<> (field.offset * 8) } - return Value{typ, ptr, scalar, fl} + return Value{typ, ptr, fl} } // FieldByIndex returns the nested field corresponding to index. @@ -904,15 +798,9 @@ func (v Value) Float() float64 { k := v.kind() switch k { case Float32: - if v.flag&flagIndir != 0 { - return float64(*(*float32)(v.ptr)) - } - return float64(*(*float32)(unsafe.Pointer(&v.scalar))) + return float64(*(*float32)(v.ptr)) case Float64: - if v.flag&flagIndir != 0 { - return *(*float64)(v.ptr) - } - return *(*float64)(unsafe.Pointer(&v.scalar)) + return *(*float64)(v.ptr) } panic(&ValueError{"reflect.Value.Float", k}) } @@ -935,12 +823,10 @@ func (v Value) Index(i int) Value { offset := uintptr(i) * typ.size var val unsafe.Pointer - var scalar uintptr - switch { - case fl&flagIndir != 0: + if fl&flagIndir != 0 { // Indirect. Just bump pointer. val = unsafe.Pointer(uintptr(v.ptr) + offset) - case typ.pointers(): + } else { if offset != 0 { // This is an array stored inline in an interface value. // And the array element type has pointers. @@ -951,14 +837,8 @@ func (v Value) Index(i int) Value { panic("reflect: internal error: unexpected array index") } val = v.ptr - case bigEndian: - // Direct. Discard leading bytes. - scalar = v.scalar << (offset * 8) - default: - // Direct. Discard leading bytes. - scalar = v.scalar >> (offset * 8) } - return Value{typ, val, scalar, fl} + return Value{typ, val, fl} case Slice: // Element flag same as Elem of Ptr. @@ -972,7 +852,7 @@ func (v Value) Index(i int) Value { typ := tt.elem fl |= flag(typ.Kind()) << flagKindShift val := unsafe.Pointer(uintptr(s.Data) + uintptr(i)*typ.size) - return Value{typ, val, 0, fl} + return Value{typ, val, fl} case String: fl := v.flag&flagRO | flag(Uint8< cap { @@ -1708,7 +1565,7 @@ func (v Value) Slice(i, j int) Value { } fl := v.flag&flagRO | flagIndir | flag(Slice)< interface @@ -2618,7 +2419,7 @@ func cvtT2I(v Value, typ Type) Value { } else { ifaceE2I(typ.(*rtype), x, unsafe.Pointer(target)) } - return Value{typ.common(), unsafe.Pointer(target), 0, v.flag&flagRO | flagIndir | flag(Interface)< interface -- 2.50.0