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

Delta Between Two Patch Sets: src/pkg/reflect/value.go

Issue 4954043: code review 4954043: gc: tweak and enable escape analysis (Closed)
Left Patch Set: Created 12 years, 7 months ago
Right Patch Set: diff -r 5e1053337103 https://go.googlecode.com/hg/ Created 12 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/gc/walk.c ('k') | test/escape2.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package reflect 5 package reflect
6 6
7 import ( 7 import (
8 "math" 8 "math"
9 "runtime" 9 "runtime"
10 "strconv" 10 "strconv"
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 func packValue(flag uint32, typ *runtime.Type, word iword) Value { 315 func packValue(flag uint32, typ *runtime.Type, word iword) Value {
316 if typ == nil { 316 if typ == nil {
317 panic("packValue") 317 panic("packValue")
318 } 318 }
319 t := uintptr(unsafe.Pointer(typ)) 319 t := uintptr(unsafe.Pointer(typ))
320 t |= uintptr(flag) 320 t |= uintptr(flag)
321 eface := emptyInterface{(*runtime.Type)(unsafe.Pointer(t)), word} 321 eface := emptyInterface{(*runtime.Type)(unsafe.Pointer(t)), word}
322 return Value{Internal: *(*interface{})(unsafe.Pointer(&eface))} 322 return Value{Internal: *(*interface{})(unsafe.Pointer(&eface))}
323 } 323 }
324 324
325 var dummy struct {
326 b bool
327 x interface{}
328 }
329
330 // Dummy annotation marking that the value x escapes,
331 // for use in cases where the reflect code is so clever that
332 // the compiler cannot follow.
333 func escapes(x interface{}) {
334 if dummy.b {
335 dummy.x = x
336 }
337 }
338
325 // valueFromAddr returns a Value using the given type and address. 339 // valueFromAddr returns a Value using the given type and address.
326 func valueFromAddr(flag uint32, typ Type, addr unsafe.Pointer) Value { 340 func valueFromAddr(flag uint32, typ Type, addr unsafe.Pointer) Value {
341 // TODO(rsc): Eliminate this terrible hack.
342 // The escape analysis knows that addr is a pointer
343 // but it doesn't see addr get passed to anything
344 // that keeps it. packValue keeps it, but packValue
345 // takes a uintptr (iword(addr)), and integers (non-pointers)
346 // are assumed not to matter. The escapes function works
347 // because return values always escape (for now).
348 escapes(addr)
349
327 if flag&flagAddr != 0 { 350 if flag&flagAddr != 0 {
328 // Addressable, so the internal value is 351 // Addressable, so the internal value is
329 // an interface containing a pointer to the real value. 352 // an interface containing a pointer to the real value.
330 return packValue(flag, PtrTo(typ).runtimeType(), iword(addr)) 353 return packValue(flag, PtrTo(typ).runtimeType(), iword(addr))
331 } 354 }
332 355
333 var w iword 356 var w iword
334 if n := typ.Size(); n <= ptrSize { 357 if n := typ.Size(); n <= ptrSize {
335 // In line, so the interface word is the actual value. 358 // In line, so the interface word is the actual value.
336 w = loadIword(addr, n) 359 w = loadIword(addr, n)
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 } 1694 }
1672 return v.Elem() 1695 return v.Elem()
1673 } 1696 }
1674 1697
1675 // ValueOf returns a new Value initialized to the concrete value 1698 // ValueOf returns a new Value initialized to the concrete value
1676 // stored in the interface i. ValueOf(nil) returns the zero Value. 1699 // stored in the interface i. ValueOf(nil) returns the zero Value.
1677 func ValueOf(i interface{}) Value { 1700 func ValueOf(i interface{}) Value {
1678 if i == nil { 1701 if i == nil {
1679 return Value{} 1702 return Value{}
1680 } 1703 }
1704
1705 // TODO(rsc): Eliminate this terrible hack.
1706 // In the call to packValue, eface.typ doesn't escape,
1707 // and eface.word is an integer. So it looks like
1708 // i (= eface) doesn't escape. But really it does,
1709 // because eface.word is actually a pointer.
1710 escapes(i)
1711
1681 // For an interface value with the noAddr bit set, 1712 // For an interface value with the noAddr bit set,
1682 // the representation is identical to an empty interface. 1713 // the representation is identical to an empty interface.
1683 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1714 eface := *(*emptyInterface)(unsafe.Pointer(&i))
1684 return packValue(0, eface.typ, eface.word) 1715 return packValue(0, eface.typ, eface.word)
1685 } 1716 }
1686 1717
1687 // Zero returns a Value representing a zero value for the specified type. 1718 // Zero returns a Value representing a zero value for the specified type.
1688 // The result is different from the zero value of the Value struct, 1719 // The result is different from the zero value of the Value struct,
1689 // which represents no value at all. 1720 // which represents no value at all.
1690 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0. 1721 // For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 func makemap(t *runtime.Type) iword 1783 func makemap(t *runtime.Type) iword
1753 func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool) 1784 func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool)
1754 func mapassign(t *runtime.Type, m iword, key, val iword, ok bool) 1785 func mapassign(t *runtime.Type, m iword, key, val iword, ok bool)
1755 func mapiterinit(t *runtime.Type, m iword) *byte 1786 func mapiterinit(t *runtime.Type, m iword) *byte
1756 func mapiterkey(it *byte) (key iword, ok bool) 1787 func mapiterkey(it *byte) (key iword, ok bool)
1757 func mapiternext(it *byte) 1788 func mapiternext(it *byte)
1758 func maplen(m iword) int32 1789 func maplen(m iword) int32
1759 1790
1760 func call(fn, arg unsafe.Pointer, n uint32) 1791 func call(fn, arg unsafe.Pointer, n uint32)
1761 func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer) 1792 func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer)
LEFTRIGHT

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