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

Side by Side Diff: src/pkg/reflect/type.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
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:
View unified diff | Download patch
« no previous file with comments | « src/pkg/reflect/all_test.go ('k') | src/pkg/reflect/value.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 implements run-time reflection, allowing a program to 5 // Package reflect implements run-time reflection, allowing a program to
6 // manipulate objects with arbitrary types. The typical use is to take a value 6 // manipulate objects with arbitrary types. The typical use is to take a value
7 // with static type interface{} and extract its dynamic type information by 7 // with static type interface{} and extract its dynamic type information by
8 // calling TypeOf, which returns a Type. 8 // calling TypeOf, which returns a Type.
9 // 9 //
10 // A call to ValueOf returns a Value representing the run-time data. 10 // A call to ValueOf returns a Value representing the run-time data.
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 // in a method set. 376 // in a method set.
377 // See http://golang.org/ref/spec#Uniqueness_of_identifiers 377 // See http://golang.org/ref/spec#Uniqueness_of_identifiers
378 Name string 378 Name string
379 PkgPath string 379 PkgPath string
380 380
381 Type Type // method type 381 Type Type // method type
382 Func Value // func with receiver as first argument 382 Func Value // func with receiver as first argument
383 Index int // index for Type.Method 383 Index int // index for Type.Method
384 } 384 }
385 385
386 // High bit says whether type has
387 // embedded pointers,to help garbage collector.
388 const ( 386 const (
389 » kindMask = 0x3f 387 » kindDirectIface = 1 << 5
390 » kindGCProg = 0x40 388 » kindGCProg = 1 << 6 // Type.gc points to GC program
391 » kindNoPointers = 0x80 389 » kindNoPointers = 1 << 7
390 » kindMask = (1 << 5) - 1
392 ) 391 )
393 392
394 func (k Kind) String() string { 393 func (k Kind) String() string {
395 if int(k) < len(kindNames) { 394 if int(k) < len(kindNames) {
396 return kindNames[k] 395 return kindNames[k]
397 } 396 }
398 return "kind" + strconv.Itoa(int(k)) 397 return "kind" + strconv.Itoa(int(k))
399 } 398 }
400 399
401 var kindNames = []string{ 400 var kindNames = []string{
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 func (gc *gcProg) appendProg(t *rtype) { 1495 func (gc *gcProg) appendProg(t *rtype) {
1497 gc.align(uintptr(t.align)) 1496 gc.align(uintptr(t.align))
1498 if !t.pointers() { 1497 if !t.pointers() {
1499 gc.size += t.size 1498 gc.size += t.size
1500 return 1499 return
1501 } 1500 }
1502 nptr := t.size / unsafe.Sizeof(uintptr(0)) 1501 nptr := t.size / unsafe.Sizeof(uintptr(0))
1503 var prog []byte 1502 var prog []byte
1504 if t.kind&kindGCProg != 0 { 1503 if t.kind&kindGCProg != 0 {
1505 // Ensure that the runtime has unrolled GC program. 1504 // Ensure that the runtime has unrolled GC program.
1505 // TODO(rsc): Do not allocate.
1506 unsafe_New(t) 1506 unsafe_New(t)
1507 // The program is stored in t.gc[0], skip unroll flag. 1507 // The program is stored in t.gc[0], skip unroll flag.
1508 prog = (*[1 << 30]byte)(unsafe.Pointer(t.gc[0]))[1:] 1508 prog = (*[1 << 30]byte)(unsafe.Pointer(t.gc[0]))[1:]
1509 } else { 1509 } else {
1510 // The mask is embed directly in t.gc. 1510 // The mask is embed directly in t.gc.
1511 prog = (*[1 << 30]byte)(unsafe.Pointer(&t.gc[0]))[:] 1511 prog = (*[1 << 30]byte)(unsafe.Pointer(&t.gc[0]))[:]
1512 } 1512 }
1513 for i := uintptr(0); i < nptr; i++ { 1513 for i := uintptr(0); i < nptr; i++ {
1514 gc.appendWord(extractGCWord(prog, i)) 1514 gc.appendWord(extractGCWord(prog, i))
1515 } 1515 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 } 1645 }
1646 1646
1647 // ArrayOf returns the array type with the given count and element type. 1647 // ArrayOf returns the array type with the given count and element type.
1648 // For example, if t represents int, ArrayOf(5, t) represents [5]int. 1648 // For example, if t represents int, ArrayOf(5, t) represents [5]int.
1649 // 1649 //
1650 // If the resulting type would be larger than the available address space, 1650 // If the resulting type would be larger than the available address space,
1651 // ArrayOf panics. 1651 // ArrayOf panics.
1652 // 1652 //
1653 // TODO(rsc): Unexported for now. Export once the alg field is set correctly 1653 // TODO(rsc): Unexported for now. Export once the alg field is set correctly
1654 // for the type. This may require significant work. 1654 // for the type. This may require significant work.
1655 //
1656 // TODO(rsc): TestArrayOf is also disabled. Re-enable.
1655 func arrayOf(count int, elem Type) Type { 1657 func arrayOf(count int, elem Type) Type {
1656 typ := elem.(*rtype) 1658 typ := elem.(*rtype)
1657 slice := SliceOf(elem) 1659 slice := SliceOf(elem)
1658 1660
1659 // Look in cache. 1661 // Look in cache.
1660 ckey := cacheKey{Array, typ, nil, uintptr(count)} 1662 ckey := cacheKey{Array, typ, nil, uintptr(count)}
1661 if slice := cacheGet(ckey); slice != nil { 1663 if slice := cacheGet(ckey); slice != nil {
1662 return slice 1664 return slice
1663 } 1665 }
1664 1666
1665 // Look in known types. 1667 // Look in known types.
1666 s := "[" + strconv.Itoa(count) + "]" + *typ.string 1668 s := "[" + strconv.Itoa(count) + "]" + *typ.string
1667 for _, tt := range typesByString(s) { 1669 for _, tt := range typesByString(s) {
1668 slice := (*sliceType)(unsafe.Pointer(tt)) 1670 slice := (*sliceType)(unsafe.Pointer(tt))
1669 if slice.elem == typ { 1671 if slice.elem == typ {
1670 return cachePut(ckey, tt) 1672 return cachePut(ckey, tt)
1671 } 1673 }
1672 } 1674 }
1673 1675
1674 // Make an array type. 1676 // Make an array type.
1675 var iarray interface{} = [1]unsafe.Pointer{} 1677 var iarray interface{} = [1]unsafe.Pointer{}
1676 prototype := *(**arrayType)(unsafe.Pointer(&iarray)) 1678 prototype := *(**arrayType)(unsafe.Pointer(&iarray))
1677 array := new(arrayType) 1679 array := new(arrayType)
1678 *array = *prototype 1680 *array = *prototype
1681 // TODO: Set extra kind bits correctly.
1679 array.string = &s 1682 array.string = &s
1680 array.hash = fnv1(typ.hash, '[') 1683 array.hash = fnv1(typ.hash, '[')
1681 for n := uint32(count); n > 0; n >>= 8 { 1684 for n := uint32(count); n > 0; n >>= 8 {
1682 array.hash = fnv1(array.hash, byte(n)) 1685 array.hash = fnv1(array.hash, byte(n))
1683 } 1686 }
1684 array.hash = fnv1(array.hash, ']') 1687 array.hash = fnv1(array.hash, ']')
1685 array.elem = typ 1688 array.elem = typ
1686 max := ^uintptr(0) / typ.size 1689 max := ^uintptr(0) / typ.size
1687 if uintptr(count) > max { 1690 if uintptr(count) > max {
1688 panic("reflect.ArrayOf: array size would exceed virtual address space") 1691 panic("reflect.ArrayOf: array size would exceed virtual address space")
1689 } 1692 }
1690 array.size = typ.size * uintptr(count) 1693 array.size = typ.size * uintptr(count)
1691 array.align = typ.align 1694 array.align = typ.align
1692 array.fieldAlign = typ.fieldAlign 1695 array.fieldAlign = typ.fieldAlign
1693 // TODO: array.alg 1696 // TODO: array.alg
1694 // TODO: array.gc 1697 // TODO: array.gc
1698 // TODO:
1695 array.uncommonType = nil 1699 array.uncommonType = nil
1696 array.ptrToThis = nil 1700 array.ptrToThis = nil
1697 array.zero = unsafe.Pointer(&make([]byte, array.size)[0]) 1701 array.zero = unsafe.Pointer(&make([]byte, array.size)[0])
1698 array.len = uintptr(count) 1702 array.len = uintptr(count)
1699 array.slice = slice.(*rtype) 1703 array.slice = slice.(*rtype)
1700 1704
1701 return cachePut(ckey, &array.rtype) 1705 return cachePut(ckey, &array.rtype)
1702 } 1706 }
1703 1707
1704 // toType converts from a *rtype to a Type that can be returned 1708 // toType converts from a *rtype to a Type that can be returned
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 } 1760 }
1757 1761
1758 tt := (*funcType)(unsafe.Pointer(t)) 1762 tt := (*funcType)(unsafe.Pointer(t))
1759 1763
1760 // compute gc program for arguments 1764 // compute gc program for arguments
1761 var gc gcProg 1765 var gc gcProg
1762 if rcvr != nil { 1766 if rcvr != nil {
1763 // Reflect uses the "interface" calling convention for 1767 // Reflect uses the "interface" calling convention for
1764 // methods, where receivers take one word of argument 1768 // methods, where receivers take one word of argument
1765 // space no matter how big they actually are. 1769 // space no matter how big they actually are.
1766 » » if rcvr.size > ptrSize { 1770 » » if !isDirectIface(rcvr) {
1767 // we pass a pointer to the receiver. 1771 // we pass a pointer to the receiver.
1768 gc.append(bitsPointer) 1772 gc.append(bitsPointer)
1769 } else if rcvr.pointers() { 1773 } else if rcvr.pointers() {
1770 // rcvr is a one-word pointer object. Its gc program 1774 // rcvr is a one-word pointer object. Its gc program
1771 // is just what we need here. 1775 // is just what we need here.
1772 gc.append(bitsPointer) 1776 gc.append(bitsPointer)
1773 } else { 1777 } else {
1774 gc.append(bitsScalar) 1778 gc.append(bitsScalar)
1775 } 1779 }
1776 } 1780 }
(...skipping 29 matching lines...) Expand all
1806 layoutCache.m = make(map[layoutKey]layoutType) 1810 layoutCache.m = make(map[layoutKey]layoutType)
1807 } 1811 }
1808 layoutCache.m[k] = layoutType{ 1812 layoutCache.m[k] = layoutType{
1809 t: x, 1813 t: x,
1810 argSize: argSize, 1814 argSize: argSize,
1811 retOffset: retOffset, 1815 retOffset: retOffset,
1812 } 1816 }
1813 layoutCache.Unlock() 1817 layoutCache.Unlock()
1814 return x, argSize, retOffset 1818 return x, argSize, retOffset
1815 } 1819 }
1820
1821 // isDirectIface reports whether t is stored directly in an interface value.
1822 func isDirectIface(t *rtype) bool {
1823 return t.kind&kindDirectIface != 0
1824 }
OLDNEW
« no previous file with comments | « src/pkg/reflect/all_test.go ('k') | src/pkg/reflect/value.go » ('j') | no next file with comments »

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