Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(25)

Unified Diff: src/pkg/reflect/value.go

Issue 129090043: code review 129090043: cmd/gc, runtime: refactor interface inlining decision i... (Closed)
Patch Set: diff -r 5856eae43c269fc32cdf2cfca0c9412ee4a5969c https://code.google.com/p/go/ Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pkg/reflect/type.go ('k') | src/pkg/runtime/alg.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pkg/reflect/value.go
===================================================================
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -82,7 +82,7 @@
// This repeats typ.Kind() except for method values.
// The remaining 23+ bits give a method number for method values.
// If flag.kind() != Func, code can assume that flagMethod is unset.
- // If typ.size > ptrSize, code can assume that flagIndir is set.
+ // If !isDirectIface(typ), code can assume that flagIndir is set.
flag
// A method value represents a curried method invocation
@@ -128,7 +128,10 @@
e := (*emptyInterface)(unsafe.Pointer(&i))
// First, fill in the data portion of the interface.
switch {
- case t.size > ptrSize:
+ case !isDirectIface(t):
+ if v.flag&flagIndir == 0 {
+ panic("bad indir")
+ }
// Value is indirect, and so is the interface we're making.
ptr := v.ptr
if v.flag&flagAddr != 0 {
@@ -172,7 +175,7 @@
return Value{}
}
f := flag(t.Kind()) << flagKindShift
- if t.size > ptrSize {
+ if !isDirectIface(t) {
return Value{t, unsafe.Pointer(e.word), 0, f | flagIndir}
}
if t.pointers() {
@@ -607,8 +610,8 @@
off += -off & uintptr(typ.align-1)
addr := unsafe.Pointer(uintptr(ptr) + off)
v := Value{typ, nil, 0, flag(typ.Kind()) << flagKindShift}
- if typ.size > ptrSize {
- // value does not fit in word.
+ if !isDirectIface(typ) {
+ // value cannot be inlined in interface data.
// Must make a copy, because f might keep a reference to it,
// and we cannot let f keep a reference to the stack frame
// after this function returns, not even a read-only reference.
@@ -714,7 +717,7 @@
iface := (*nonEmptyInterface)(v.ptr)
*(*unsafe.Pointer)(p) = unsafe.Pointer(iface.word)
} else if v.flag&flagIndir != 0 {
- if t.size > ptrSize {
+ if !isDirectIface(t) {
*(*unsafe.Pointer)(p) = v.ptr
} else if t.pointers() {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
@@ -987,7 +990,13 @@
val = unsafe.Pointer(uintptr(v.ptr) + offset)
case typ.pointers():
if offset != 0 {
- panic("can't Index(i) with i!=0 on ptrLike value")
+ // This is an array stored inline in an interface value.
+ // And the array element type has pointers.
+ // Since the inline storage space is only a single word,
+ // this implies we must be holding an array of length 1
+ // with an element type that is a single pointer.
+ // If the offset is not 0, something has gone wrong.
+ panic("reflect: internal error: unexpected array index")
}
val = v.ptr
case bigEndian:
@@ -1014,14 +1023,13 @@
return Value{typ, val, 0, fl}
case String:
- fl := v.flag&flagRO | flag(Uint8<<flagKindShift)
+ fl := v.flag&flagRO | flag(Uint8<<flagKindShift) | flagIndir
s := (*stringHeader)(v.ptr)
if i < 0 || i >= s.Len {
panic("reflect: string index out of range")
}
- b := uintptr(0)
- *(*byte)(unsafe.Pointer(&b)) = *(*byte)(unsafe.Pointer(uintptr(s.Data) + uintptr(i)))
- return Value{uint8Type, nil, b, fl}
+ p := unsafe.Pointer(uintptr(s.Data) + uintptr(i))
+ return Value{uint8Type, p, 0, fl}
}
panic(&ValueError{"reflect.Value.Index", k})
}
@@ -1209,7 +1217,7 @@
typ := tt.elem
fl := (v.flag | key.flag) & flagRO
fl |= flag(typ.Kind()) << flagKindShift
- if typ.size > ptrSize {
+ if !isDirectIface(typ) {
// Copy result so future changes to the map
// won't change the underlying value.
c := unsafe_New(typ)
@@ -1249,7 +1257,7 @@
// we can do about it.
break
}
- if keyType.size > ptrSize {
+ if !isDirectIface(keyType) {
// Copy result so future changes to the map
// won't change the underlying value.
c := unsafe_New(keyType)
@@ -1448,7 +1456,7 @@
t := tt.elem
val = Value{t, nil, 0, flag(t.Kind()) << flagKindShift}
var p unsafe.Pointer
- if t.size > ptrSize {
+ if !isDirectIface(t) {
p = unsafe_New(t)
val.ptr = p
val.flag |= flagIndir
@@ -2190,7 +2198,7 @@
t := tt.elem
p := runcases[chosen].val
fl := flag(t.Kind()) << flagKindShift
- if t.size > ptrSize {
+ if !isDirectIface(t) {
recv = Value{t, p, 0, fl | flagIndir}
} else if t.pointers() {
recv = Value{t, *(*unsafe.Pointer)(p), 0, fl}
@@ -2291,7 +2299,7 @@
}
t := typ.common()
fl := flag(t.Kind()) << flagKindShift
- if t.size <= ptrSize {
+ if isDirectIface(t) {
return Value{t, nil, 0, fl}
}
return Value{t, unsafe_New(typ.(*rtype)), 0, fl | flagIndir}
@@ -2450,10 +2458,18 @@
// where t is a signed or unsigned int type.
func makeInt(f flag, bits uint64, t Type) Value {
typ := t.common()
- if typ.size > ptrSize {
- // Assume ptrSize >= 4, so this must be uint64.
+ if !isDirectIface(typ) {
ptr := unsafe_New(typ)
- *(*uint64)(unsafe.Pointer(ptr)) = bits
+ switch typ.size {
+ case 1:
+ *(*uint8)(unsafe.Pointer(ptr)) = uint8(bits)
+ case 2:
+ *(*uint16)(unsafe.Pointer(ptr)) = uint16(bits)
+ case 4:
+ *(*uint32)(unsafe.Pointer(ptr)) = uint32(bits)
+ case 8:
+ *(*uint64)(unsafe.Pointer(ptr)) = bits
+ }
return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flagKindShift}
}
var s uintptr
@@ -2474,10 +2490,14 @@
// where t is a float32 or float64 type.
func makeFloat(f flag, v float64, t Type) Value {
typ := t.common()
- if typ.size > ptrSize {
- // Assume ptrSize >= 4, so this must be float64.
+ if !isDirectIface(typ) {
ptr := unsafe_New(typ)
- *(*float64)(unsafe.Pointer(ptr)) = v
+ switch typ.size {
+ case 4:
+ *(*float32)(unsafe.Pointer(ptr)) = float32(v)
+ case 8:
+ *(*float64)(unsafe.Pointer(ptr)) = v
+ }
return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flagKindShift}
}
@@ -2495,7 +2515,7 @@
// where t is a complex64 or complex128 type.
func makeComplex(f flag, v complex128, t Type) Value {
typ := t.common()
- if typ.size > ptrSize {
+ if !isDirectIface(typ) {
ptr := unsafe_New(typ)
switch typ.size {
case 8:
@@ -2506,9 +2526,13 @@
return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flagKindShift}
}
- // Assume ptrSize <= 8 so this must be complex64.
var s uintptr
- *(*complex64)(unsafe.Pointer(&s)) = complex64(v)
+ switch typ.size {
+ case 8:
+ *(*complex64)(unsafe.Pointer(&s)) = complex64(v)
+ case 16:
+ *(*complex128)(unsafe.Pointer(&s)) = v
+ }
return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift}
}
« no previous file with comments | « src/pkg/reflect/type.go ('k') | src/pkg/runtime/alg.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b