github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/runtime/iface.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import (
     8  	"runtime/internal/atomic"
     9  	"runtime/internal/sys"
    10  	"unsafe"
    11  )
    12  
    13  const itabInitSize = 512
    14  
    15  var (
    16  	itabLock      mutex                               // lock for accessing itab table
    17  	itabTable     = &itabTableInit                    // pointer to current table
    18  	itabTableInit = itabTableType{size: itabInitSize} // starter table
    19  )
    20  
    21  // Note: change the formula in the mallocgc call in itabAdd if you change these fields.
    22  type itabTableType struct {
    23  	size    uintptr             // length of entries array. Always a power of 2.
    24  	count   uintptr             // current number of filled entries.
    25  	entries [itabInitSize]*itab // really [size] large
    26  }
    27  
    28  func itabHashFunc(inter *interfacetype, typ *_type) uintptr {
    29  	// compiler has provided some good hash codes for us.
    30  	return uintptr(inter.typ.hash ^ typ.hash)
    31  }
    32  
    33  func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
    34  	if len(inter.mhdr) == 0 {
    35  		throw("internal error - misuse of itab")
    36  	}
    37  
    38  	// easy case
    39  	if typ.tflag&tflagUncommon == 0 {
    40  		if canfail {
    41  			return nil
    42  		}
    43  		name := inter.typ.nameOff(inter.mhdr[0].name)
    44  		panic(&TypeAssertionError{nil, typ, &inter.typ, name.name()})
    45  	}
    46  
    47  	var m *itab
    48  
    49  	// First, look in the existing table to see if we can find the itab we need.
    50  	// This is by far the most common case, so do it without locks.
    51  	// Use atomic to ensure we see any previous writes done by the thread
    52  	// that updates the itabTable field (with atomic.Storep in itabAdd).
    53  	t := (*itabTableType)(atomic.Loadp(unsafe.Pointer(&itabTable)))
    54  	if m = t.find(inter, typ); m != nil {
    55  		goto finish
    56  	}
    57  
    58  	// Not found.  Grab the lock and try again.
    59  	lock(&itabLock)
    60  	if m = itabTable.find(inter, typ); m != nil {
    61  		unlock(&itabLock)
    62  		goto finish
    63  	}
    64  
    65  	// Entry doesn't exist yet. Make a new entry & add it.
    66  	m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*sys.PtrSize, 0, &memstats.other_sys))
    67  	m.inter = inter
    68  	m._type = typ
    69  	m.init()
    70  	itabAdd(m)
    71  	unlock(&itabLock)
    72  finish:
    73  	if m.fun[0] != 0 {
    74  		return m
    75  	}
    76  	if canfail {
    77  		return nil
    78  	}
    79  	// this can only happen if the conversion
    80  	// was already done once using the , ok form
    81  	// and we have a cached negative result.
    82  	// The cached result doesn't record which
    83  	// interface function was missing, so initialize
    84  	// the itab again to get the missing function name.
    85  	panic(&TypeAssertionError{concrete: typ, asserted: &inter.typ, missingMethod: m.init()})
    86  }
    87  
    88  // find finds the given interface/type pair in t.
    89  // Returns nil if the given interface/type pair isn't present.
    90  func (t *itabTableType) find(inter *interfacetype, typ *_type) *itab {
    91  	// Implemented using quadratic probing.
    92  	// Probe sequence is h(i) = h0 + i*(i+1)/2 mod 2^k.
    93  	// We're guaranteed to hit all table entries using this probe sequence.
    94  	mask := t.size - 1
    95  	h := itabHashFunc(inter, typ) & mask
    96  	for i := uintptr(1); ; i++ {
    97  		p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
    98  		// Use atomic read here so if we see m != nil, we also see
    99  		// the initializations of the fields of m.
   100  		// m := *p
   101  		m := (*itab)(atomic.Loadp(unsafe.Pointer(p)))
   102  		if m == nil {
   103  			return nil
   104  		}
   105  		if m.inter == inter && m._type == typ {
   106  			return m
   107  		}
   108  		h += i
   109  		h &= mask
   110  	}
   111  }
   112  
   113  // itabAdd adds the given itab to the itab hash table.
   114  // itabLock must be held.
   115  func itabAdd(m *itab) {
   116  	// Bugs can lead to calling this while mallocing is set,
   117  	// typically because this is called while panicing.
   118  	// Crash reliably, rather than only when we need to grow
   119  	// the hash table.
   120  	if getg().m.mallocing != 0 {
   121  		throw("malloc deadlock")
   122  	}
   123  
   124  	t := itabTable
   125  	if t.count >= 3*(t.size/4) { // 75% load factor
   126  		// Grow hash table.
   127  		// t2 = new(itabTableType) + some additional entries
   128  		// We lie and tell malloc we want pointer-free memory because
   129  		// all the pointed-to values are not in the heap.
   130  		t2 := (*itabTableType)(mallocgc((2+2*t.size)*sys.PtrSize, nil, true))
   131  		t2.size = t.size * 2
   132  
   133  		// Copy over entries.
   134  		// Note: while copying, other threads may look for an itab and
   135  		// fail to find it. That's ok, they will then try to get the itab lock
   136  		// and as a consequence wait until this copying is complete.
   137  		iterate_itabs(t2.add)
   138  		if t2.count != t.count {
   139  			throw("mismatched count during itab table copy")
   140  		}
   141  		// Publish new hash table. Use an atomic write: see comment in getitab.
   142  		atomicstorep(unsafe.Pointer(&itabTable), unsafe.Pointer(t2))
   143  		// Adopt the new table as our own.
   144  		t = itabTable
   145  		// Note: the old table can be GC'ed here.
   146  	}
   147  	t.add(m)
   148  }
   149  
   150  // add adds the given itab to itab table t.
   151  // itabLock must be held.
   152  func (t *itabTableType) add(m *itab) {
   153  	// See comment in find about the probe sequence.
   154  	// Insert new itab in the first empty spot in the probe sequence.
   155  	mask := t.size - 1
   156  	h := itabHashFunc(m.inter, m._type) & mask
   157  	for i := uintptr(1); ; i++ {
   158  		p := (**itab)(add(unsafe.Pointer(&t.entries), h*sys.PtrSize))
   159  		m2 := *p
   160  		if m2 == m {
   161  			// A given itab may be used in more than one module
   162  			// and thanks to the way global symbol resolution works, the
   163  			// pointed-to itab may already have been inserted into the
   164  			// global 'hash'.
   165  			return
   166  		}
   167  		if m2 == nil {
   168  			// Use atomic write here so if a reader sees m, it also
   169  			// sees the correctly initialized fields of m.
   170  			// NoWB is ok because m is not in heap memory.
   171  			// *p = m
   172  			atomic.StorepNoWB(unsafe.Pointer(p), unsafe.Pointer(m))
   173  			t.count++
   174  			return
   175  		}
   176  		h += i
   177  		h &= mask
   178  	}
   179  }
   180  
   181  // init fills in the m.fun array with all the code pointers for
   182  // the m.inter/m._type pair. If the type does not implement the interface,
   183  // it sets m.fun[0] to 0 and returns the name of an interface function that is missing.
   184  // It is ok to call this multiple times on the same m, even concurrently.
   185  func (m *itab) init() string {
   186  	inter := m.inter
   187  	typ := m._type
   188  	x := typ.uncommon()
   189  
   190  	// both inter and typ have method sorted by name,
   191  	// and interface names are unique,
   192  	// so can iterate over both in lock step;
   193  	// the loop is O(ni+nt) not O(ni*nt).
   194  	ni := len(inter.mhdr)
   195  	nt := int(x.mcount)
   196  	xmhdr := (*[1 << 16]method)(add(unsafe.Pointer(x), uintptr(x.moff)))[:nt:nt]
   197  	j := 0
   198  imethods:
   199  	for k := 0; k < ni; k++ {
   200  		i := &inter.mhdr[k]
   201  		itype := inter.typ.typeOff(i.ityp)
   202  		name := inter.typ.nameOff(i.name)
   203  		iname := name.name()
   204  		ipkg := name.pkgPath()
   205  		if ipkg == "" {
   206  			ipkg = inter.pkgpath.name()
   207  		}
   208  		for ; j < nt; j++ {
   209  			t := &xmhdr[j]
   210  			tname := typ.nameOff(t.name)
   211  			if typ.typeOff(t.mtyp) == itype && tname.name() == iname {
   212  				pkgPath := tname.pkgPath()
   213  				if pkgPath == "" {
   214  					pkgPath = typ.nameOff(x.pkgpath).name()
   215  				}
   216  				if tname.isExported() || pkgPath == ipkg {
   217  					if m != nil {
   218  						ifn := typ.textOff(t.ifn)
   219  						*(*unsafe.Pointer)(add(unsafe.Pointer(&m.fun[0]), uintptr(k)*sys.PtrSize)) = ifn
   220  					}
   221  					continue imethods
   222  				}
   223  			}
   224  		}
   225  		// didn't find method
   226  		m.fun[0] = 0
   227  		return iname
   228  	}
   229  	m.hash = typ.hash
   230  	return ""
   231  }
   232  
   233  func itabsinit() {
   234  	lock(&itabLock)
   235  	for _, md := range activeModules() {
   236  		for _, i := range md.itablinks {
   237  			itabAdd(i)
   238  		}
   239  	}
   240  	unlock(&itabLock)
   241  }
   242  
   243  // panicdottypeE is called when doing an e.(T) conversion and the conversion fails.
   244  // have = the dynamic type we have.
   245  // want = the static type we're trying to convert to.
   246  // iface = the static type we're converting from.
   247  func panicdottypeE(have, want, iface *_type) {
   248  	panic(&TypeAssertionError{iface, have, want, ""})
   249  }
   250  
   251  // panicdottypeI is called when doing an i.(T) conversion and the conversion fails.
   252  // Same args as panicdottypeE, but "have" is the dynamic itab we have.
   253  func panicdottypeI(have *itab, want, iface *_type) {
   254  	var t *_type
   255  	if have != nil {
   256  		t = have._type
   257  	}
   258  	panicdottypeE(t, want, iface)
   259  }
   260  
   261  // panicnildottype is called when doing a i.(T) conversion and the interface i is nil.
   262  // want = the static type we're trying to convert to.
   263  func panicnildottype(want *_type) {
   264  	panic(&TypeAssertionError{nil, nil, want, ""})
   265  	// TODO: Add the static type we're converting from as well.
   266  	// It might generate a better error message.
   267  	// Just to match other nil conversion errors, we don't for now.
   268  }
   269  
   270  // The conv and assert functions below do very similar things.
   271  // The convXXX functions are guaranteed by the compiler to succeed.
   272  // The assertXXX functions may fail (either panicking or returning false,
   273  // depending on whether they are 1-result or 2-result).
   274  // The convXXX functions succeed on a nil input, whereas the assertXXX
   275  // functions fail on a nil input.
   276  
   277  func convT2E(t *_type, elem unsafe.Pointer) (e eface) {
   278  	if raceenabled {
   279  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2E))
   280  	}
   281  	if msanenabled {
   282  		msanread(elem, t.size)
   283  	}
   284  	x := mallocgc(t.size, t, true)
   285  	// TODO: We allocate a zeroed object only to overwrite it with actual data.
   286  	// Figure out how to avoid zeroing. Also below in convT2Eslice, convT2I, convT2Islice.
   287  	typedmemmove(t, x, elem)
   288  	e._type = t
   289  	e.data = x
   290  	return
   291  }
   292  
   293  func convT2E16(t *_type, val uint16) (e eface) {
   294  	var x unsafe.Pointer
   295  	if val == 0 {
   296  		x = unsafe.Pointer(&zeroVal[0])
   297  	} else {
   298  		x = mallocgc(2, t, false)
   299  		*(*uint16)(x) = val
   300  	}
   301  	e._type = t
   302  	e.data = x
   303  	return
   304  }
   305  
   306  func convT2E32(t *_type, val uint32) (e eface) {
   307  	var x unsafe.Pointer
   308  	if val == 0 {
   309  		x = unsafe.Pointer(&zeroVal[0])
   310  	} else {
   311  		x = mallocgc(4, t, false)
   312  		*(*uint32)(x) = val
   313  	}
   314  	e._type = t
   315  	e.data = x
   316  	return
   317  }
   318  
   319  func convT2E64(t *_type, val uint64) (e eface) {
   320  	var x unsafe.Pointer
   321  	if val == 0 {
   322  		x = unsafe.Pointer(&zeroVal[0])
   323  	} else {
   324  		x = mallocgc(8, t, false)
   325  		*(*uint64)(x) = val
   326  	}
   327  	e._type = t
   328  	e.data = x
   329  	return
   330  }
   331  
   332  func convT2Estring(t *_type, val string) (e eface) {
   333  	var x unsafe.Pointer
   334  	if val == "" {
   335  		x = unsafe.Pointer(&zeroVal[0])
   336  	} else {
   337  		x = mallocgc(unsafe.Sizeof(val), t, true)
   338  		*(*string)(x) = val
   339  	}
   340  	e._type = t
   341  	e.data = x
   342  	return
   343  }
   344  
   345  func convT2Eslice(t *_type, val []byte) (e eface) {
   346  	// Note: this must work for any element type, not just byte.
   347  	var x unsafe.Pointer
   348  	if (*slice)(unsafe.Pointer(&val)).array == nil {
   349  		x = unsafe.Pointer(&zeroVal[0])
   350  	} else {
   351  		x = mallocgc(unsafe.Sizeof(val), t, true)
   352  		*(*[]byte)(x) = val
   353  	}
   354  	e._type = t
   355  	e.data = x
   356  	return
   357  }
   358  
   359  func convT2Enoptr(t *_type, elem unsafe.Pointer) (e eface) {
   360  	if raceenabled {
   361  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Enoptr))
   362  	}
   363  	if msanenabled {
   364  		msanread(elem, t.size)
   365  	}
   366  	x := mallocgc(t.size, t, false)
   367  	memmove(x, elem, t.size)
   368  	e._type = t
   369  	e.data = x
   370  	return
   371  }
   372  
   373  func convT2I(tab *itab, elem unsafe.Pointer) (i iface) {
   374  	t := tab._type
   375  	if raceenabled {
   376  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2I))
   377  	}
   378  	if msanenabled {
   379  		msanread(elem, t.size)
   380  	}
   381  	x := mallocgc(t.size, t, true)
   382  	typedmemmove(t, x, elem)
   383  	i.tab = tab
   384  	i.data = x
   385  	return
   386  }
   387  
   388  func convT2I16(tab *itab, val uint16) (i iface) {
   389  	t := tab._type
   390  	var x unsafe.Pointer
   391  	if val == 0 {
   392  		x = unsafe.Pointer(&zeroVal[0])
   393  	} else {
   394  		x = mallocgc(2, t, false)
   395  		*(*uint16)(x) = val
   396  	}
   397  	i.tab = tab
   398  	i.data = x
   399  	return
   400  }
   401  
   402  func convT2I32(tab *itab, val uint32) (i iface) {
   403  	t := tab._type
   404  	var x unsafe.Pointer
   405  	if val == 0 {
   406  		x = unsafe.Pointer(&zeroVal[0])
   407  	} else {
   408  		x = mallocgc(4, t, false)
   409  		*(*uint32)(x) = val
   410  	}
   411  	i.tab = tab
   412  	i.data = x
   413  	return
   414  }
   415  
   416  func convT2I64(tab *itab, val uint64) (i iface) {
   417  	t := tab._type
   418  	var x unsafe.Pointer
   419  	if val == 0 {
   420  		x = unsafe.Pointer(&zeroVal[0])
   421  	} else {
   422  		x = mallocgc(8, t, false)
   423  		*(*uint64)(x) = val
   424  	}
   425  	i.tab = tab
   426  	i.data = x
   427  	return
   428  }
   429  
   430  func convT2Istring(tab *itab, val string) (i iface) {
   431  	t := tab._type
   432  	var x unsafe.Pointer
   433  	if val == "" {
   434  		x = unsafe.Pointer(&zeroVal[0])
   435  	} else {
   436  		x = mallocgc(unsafe.Sizeof(val), t, true)
   437  		*(*string)(x) = val
   438  	}
   439  	i.tab = tab
   440  	i.data = x
   441  	return
   442  }
   443  
   444  func convT2Islice(tab *itab, val []byte) (i iface) {
   445  	// Note: this must work for any element type, not just byte.
   446  	t := tab._type
   447  	var x unsafe.Pointer
   448  	if (*slice)(unsafe.Pointer(&val)).array == nil {
   449  		x = unsafe.Pointer(&zeroVal[0])
   450  	} else {
   451  		x = mallocgc(unsafe.Sizeof(val), t, true)
   452  		*(*[]byte)(x) = val
   453  	}
   454  	i.tab = tab
   455  	i.data = x
   456  	return
   457  }
   458  
   459  func convT2Inoptr(tab *itab, elem unsafe.Pointer) (i iface) {
   460  	t := tab._type
   461  	if raceenabled {
   462  		raceReadObjectPC(t, elem, getcallerpc(), funcPC(convT2Inoptr))
   463  	}
   464  	if msanenabled {
   465  		msanread(elem, t.size)
   466  	}
   467  	x := mallocgc(t.size, t, false)
   468  	memmove(x, elem, t.size)
   469  	i.tab = tab
   470  	i.data = x
   471  	return
   472  }
   473  
   474  func convI2I(inter *interfacetype, i iface) (r iface) {
   475  	tab := i.tab
   476  	if tab == nil {
   477  		return
   478  	}
   479  	if tab.inter == inter {
   480  		r.tab = tab
   481  		r.data = i.data
   482  		return
   483  	}
   484  	r.tab = getitab(inter, tab._type, false)
   485  	r.data = i.data
   486  	return
   487  }
   488  
   489  func assertI2I(inter *interfacetype, i iface) (r iface) {
   490  	tab := i.tab
   491  	if tab == nil {
   492  		// explicit conversions require non-nil interface value.
   493  		panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
   494  	}
   495  	if tab.inter == inter {
   496  		r.tab = tab
   497  		r.data = i.data
   498  		return
   499  	}
   500  	r.tab = getitab(inter, tab._type, false)
   501  	r.data = i.data
   502  	return
   503  }
   504  
   505  func assertI2I2(inter *interfacetype, i iface) (r iface, b bool) {
   506  	tab := i.tab
   507  	if tab == nil {
   508  		return
   509  	}
   510  	if tab.inter != inter {
   511  		tab = getitab(inter, tab._type, true)
   512  		if tab == nil {
   513  			return
   514  		}
   515  	}
   516  	r.tab = tab
   517  	r.data = i.data
   518  	b = true
   519  	return
   520  }
   521  
   522  func assertE2I(inter *interfacetype, e eface) (r iface) {
   523  	t := e._type
   524  	if t == nil {
   525  		// explicit conversions require non-nil interface value.
   526  		panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
   527  	}
   528  	r.tab = getitab(inter, t, false)
   529  	r.data = e.data
   530  	return
   531  }
   532  
   533  func assertE2I2(inter *interfacetype, e eface) (r iface, b bool) {
   534  	t := e._type
   535  	if t == nil {
   536  		return
   537  	}
   538  	tab := getitab(inter, t, true)
   539  	if tab == nil {
   540  		return
   541  	}
   542  	r.tab = tab
   543  	r.data = e.data
   544  	b = true
   545  	return
   546  }
   547  
   548  //go:linkname reflect_ifaceE2I reflect.ifaceE2I
   549  func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
   550  	*dst = assertE2I(inter, e)
   551  }
   552  
   553  func iterate_itabs(fn func(*itab)) {
   554  	// Note: only runs during stop the world or with itabLock held,
   555  	// so no other locks/atomics needed.
   556  	t := itabTable
   557  	for i := uintptr(0); i < t.size; i++ {
   558  		m := *(**itab)(add(unsafe.Pointer(&t.entries), i*sys.PtrSize))
   559  		if m != nil {
   560  			fn(m)
   561  		}
   562  	}
   563  }
   564  
   565  // staticbytes is used to avoid convT2E for byte-sized values.
   566  var staticbytes = [...]byte{
   567  	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   568  	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   569  	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   570  	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   571  	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
   572  	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   573  	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
   574  	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   575  	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
   576  	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
   577  	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
   578  	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
   579  	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
   580  	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
   581  	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
   582  	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
   583  	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
   584  	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
   585  	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
   586  	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
   587  	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
   588  	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
   589  	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
   590  	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
   591  	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
   592  	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
   593  	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
   594  	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
   595  	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
   596  	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
   597  	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
   598  	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
   599  }