Commit 1dbe4c50 authored by Martin Möhrmann's avatar Martin Möhrmann

reflect: avoid calling common if type is known to be *rtype

If the type of Type is known to be *rtype than the common
function is a no-op and does not need to be called.

name  old time/op  new time/op  delta
New   31.0ns ± 5%  30.2ns ± 4%  -2.74%  (p=0.008 n=20+20)

Change-Id: I5d00346dbc782e34c530166d1ee0499b24068b51
Reviewed-on: https://go-review.googlesource.com/96115Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent f4c3072c
...@@ -2102,7 +2102,7 @@ func MakeSlice(typ Type, len, cap int) Value { ...@@ -2102,7 +2102,7 @@ func MakeSlice(typ Type, len, cap int) Value {
} }
s := sliceHeader{unsafe_NewArray(typ.Elem().(*rtype), cap), len, cap} s := sliceHeader{unsafe_NewArray(typ.Elem().(*rtype), cap), len, cap}
return Value{typ.common(), unsafe.Pointer(&s), flagIndir | flag(Slice)} return Value{typ.(*rtype), unsafe.Pointer(&s), flagIndir | flag(Slice)}
} }
// MakeChan creates a new channel with the specified type and buffer size. // MakeChan creates a new channel with the specified type and buffer size.
...@@ -2116,8 +2116,9 @@ func MakeChan(typ Type, buffer int) Value { ...@@ -2116,8 +2116,9 @@ func MakeChan(typ Type, buffer int) Value {
if typ.ChanDir() != BothDir { if typ.ChanDir() != BothDir {
panic("reflect.MakeChan: unidirectional channel type") panic("reflect.MakeChan: unidirectional channel type")
} }
ch := makechan(typ.(*rtype), buffer) t := typ.(*rtype)
return Value{typ.common(), ch, flag(Chan)} ch := makechan(t, buffer)
return Value{t, ch, flag(Chan)}
} }
// MakeMap creates a new map with the specified type. // MakeMap creates a new map with the specified type.
...@@ -2131,8 +2132,9 @@ func MakeMapWithSize(typ Type, n int) Value { ...@@ -2131,8 +2132,9 @@ func MakeMapWithSize(typ Type, n int) Value {
if typ.Kind() != Map { if typ.Kind() != Map {
panic("reflect.MakeMapWithSize of non-map type") panic("reflect.MakeMapWithSize of non-map type")
} }
m := makemap(typ.(*rtype), n) t := typ.(*rtype)
return Value{typ.common(), m, flag(Map)} m := makemap(t, n)
return Value{t, m, flag(Map)}
} }
// Indirect returns the value that v points to. // Indirect returns the value that v points to.
...@@ -2170,10 +2172,10 @@ func Zero(typ Type) Value { ...@@ -2170,10 +2172,10 @@ func Zero(typ Type) Value {
if typ == nil { if typ == nil {
panic("reflect: Zero(nil)") panic("reflect: Zero(nil)")
} }
t := typ.common() t := typ.(*rtype)
fl := flag(t.Kind()) fl := flag(t.Kind())
if ifaceIndir(t) { if ifaceIndir(t) {
return Value{t, unsafe_New(typ.(*rtype)), fl | flagIndir} return Value{t, unsafe_New(t), fl | flagIndir}
} }
return Value{t, nil, fl} return Value{t, nil, fl}
} }
...@@ -2184,16 +2186,18 @@ func New(typ Type) Value { ...@@ -2184,16 +2186,18 @@ func New(typ Type) Value {
if typ == nil { if typ == nil {
panic("reflect: New(nil)") panic("reflect: New(nil)")
} }
ptr := unsafe_New(typ.(*rtype)) t := typ.(*rtype)
ptr := unsafe_New(t)
fl := flag(Ptr) fl := flag(Ptr)
return Value{typ.common().ptrTo(), ptr, fl} return Value{t.ptrTo(), ptr, fl}
} }
// NewAt returns a Value representing a pointer to a value of the // NewAt returns a Value representing a pointer to a value of the
// specified type, using p as that pointer. // specified type, using p as that pointer.
func NewAt(typ Type, p unsafe.Pointer) Value { func NewAt(typ Type, p unsafe.Pointer) Value {
fl := flag(Ptr) fl := flag(Ptr)
return Value{typ.common().ptrTo(), p, fl} t := typ.(*rtype)
return Value{t.ptrTo(), p, fl}
} }
// assignTo returns a value v that can be assigned directly to typ. // assignTo returns a value v that can be assigned directly to typ.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment