diff mbox

Go patch committed: Drop zero field from type descriptors

Message ID CAOyqgcWrZ+R+1CktnBVqwMpwJbhJ0ktfHOzhi8t5Xw6FAPBtew@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor Oct. 29, 2015, 6:14 p.m. UTC
The gc Go library added a zero field to type descriptors for use by
maps.  It was added to gccgo in a library updated a while back,
although gccgo never used it.  The gc library has since dropped it.
This patch removes it from gccgo.  This is in preparation for an
update to the Go 1.5 library.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 229098)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-11e249a59e8c627fe9c2938c38e39cb1efefb1fb
+57da43e8159bfe1a31e49683c371cf36e2fb6051
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 229098)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -1197,19 +1197,29 @@  Func_descriptor_expression::do_get_backe
 
   Gogo* gogo = context->gogo();
   std::string var_name;
-  if (no->package() == NULL)
-    var_name = gogo->pkgpath_symbol();
+  bool is_descriptor = false;
+  if (no->is_function_declaration()
+      && !no->func_declaration_value()->asm_name().empty()
+      && Linemap::is_predeclared_location(no->location()))
+    {
+      var_name = no->func_declaration_value()->asm_name() + "_descriptor";
+      is_descriptor = true;
+    }
   else
-    var_name = no->package()->pkgpath_symbol();
-  var_name.push_back('.');
-  var_name.append(Gogo::unpack_hidden_name(no->name()));
-  var_name.append("$descriptor");
+    {
+      if (no->package() == NULL)
+	var_name = gogo->pkgpath_symbol();
+      else
+	var_name = no->package()->pkgpath_symbol();
+      var_name.push_back('.');
+      var_name.append(Gogo::unpack_hidden_name(no->name()));
+      var_name.append("$descriptor");
+    }
 
   Btype* btype = this->type()->get_backend(gogo);
 
   Bvariable* bvar;
-  if (no->package() != NULL
-      || Linemap::is_predeclared_location(no->location()))
+  if (no->package() != NULL || is_descriptor)
     bvar = context->backend()->immutable_struct_reference(var_name, btype,
 							  loc);
   else
Index: gcc/go/gofrontend/types.cc
===================================================================
--- gcc/go/gofrontend/types.cc	(revision 228306)
+++ gcc/go/gofrontend/types.cc	(working copy)
@@ -1474,6 +1474,27 @@  Type::make_type_descriptor_type()
       Type* void_type = Type::make_void_type();
       Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
 
+      Typed_identifier_list *params = new Typed_identifier_list();
+      params->push_back(Typed_identifier("key", unsafe_pointer_type, bloc));
+      params->push_back(Typed_identifier("key_size", uintptr_type, bloc));
+
+      Typed_identifier_list* results = new Typed_identifier_list();
+      results->push_back(Typed_identifier("", uintptr_type, bloc));
+
+      Type* hash_fntype = Type::make_function_type(NULL, params, results,
+						   bloc);
+
+      params = new Typed_identifier_list();
+      params->push_back(Typed_identifier("key1", unsafe_pointer_type, bloc));
+      params->push_back(Typed_identifier("key2", unsafe_pointer_type, bloc));
+      params->push_back(Typed_identifier("key_size", uintptr_type, bloc));
+
+      results = new Typed_identifier_list();
+      results->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc));
+
+      Type* equal_fntype = Type::make_function_type(NULL, params, results,
+						    bloc);
+
       // Forward declaration for the type descriptor type.
       Named_object* named_type_descriptor_type =
 	Named_object::make_type_declaration("commonType", NULL, bloc);
@@ -1514,8 +1535,8 @@  Type::make_type_descriptor_type()
 				       "fieldAlign", uint8_type,
 				       "size", uintptr_type,
 				       "hash", uint32_type,
-				       "hashfn", uintptr_type,
-				       "equalfn", uintptr_type,
+				       "hashfn", hash_fntype,
+				       "equalfn", equal_fntype,
 				       "gc", uintptr_type,
 				       "string", pointer_string_type,
 				       "", pointer_uncommon_type,
@@ -1852,6 +1873,10 @@  Type::write_specific_type_functions(Gogo
   gogo->add_block(b, bloc);
   gogo->lower_block(equal_fn, b);
   gogo->finish_function(bloc);
+
+  // Build the function descriptors for the type descriptor to refer to.
+  hash_fn->func_value()->descriptor(gogo, hash_fn);
+  equal_fn->func_value()->descriptor(gogo, equal_fn);
 }
 
 // Write a hash function that simply calls the hash function for a
@@ -2009,8 +2034,8 @@  Type::type_descriptor_constructor(Gogo*
   Named_object* equal_fn;
   this->type_functions(gogo, name, hash_fntype, equal_fntype, &hash_fn,
 		       &equal_fn);
-  vals->push_back(Expression::make_func_code_reference(hash_fn, bloc));
-  vals->push_back(Expression::make_func_code_reference(equal_fn, bloc));
+  vals->push_back(Expression::make_func_reference(hash_fn, NULL, bloc));
+  vals->push_back(Expression::make_func_reference(equal_fn, NULL, bloc));
 
   ++p;
   go_assert(p->is_field_name("gc"));
Index: libgo/go/reflect/type.go
===================================================================
--- libgo/go/reflect/type.go	(revision 228306)
+++ libgo/go/reflect/type.go	(working copy)
@@ -255,8 +255,8 @@  type rtype struct {
 	size       uintptr
 	hash       uint32 // hash of type; avoids computation in hash tables
 
-	hashfn  uintptr // hash function code
-	equalfn uintptr // equality function code
+	hashfn  func(unsafe.Pointer, uintptr)                 // hash function
+	equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) // equality function
 
 	gc            unsafe.Pointer // garbage collection data
 	string        *string        // string form; unnecessary  but undeniably useful
Index: libgo/runtime/go-eface-compare.c
===================================================================
--- libgo/runtime/go-eface-compare.c	(revision 228306)
+++ libgo/runtime/go-eface-compare.c	(working copy)
@@ -28,8 +28,8 @@  __go_empty_interface_compare (struct __g
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == right.__object ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, right.__object,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
+			  right.__object, left_descriptor->__size))
     return 1;
   return 0;
 }
Index: libgo/runtime/go-eface-val-compare.c
===================================================================
--- libgo/runtime/go-eface-val-compare.c	(revision 228306)
+++ libgo/runtime/go-eface-val-compare.c	(working copy)
@@ -26,8 +26,8 @@  __go_empty_interface_value_compare (
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == val ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, val,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
+			  left_descriptor->__size))
     return 1;
   return 0;
 }
Index: libgo/runtime/go-interface-compare.c
===================================================================
--- libgo/runtime/go-interface-compare.c	(revision 228306)
+++ libgo/runtime/go-interface-compare.c	(working copy)
@@ -28,8 +28,8 @@  __go_interface_compare (struct __go_inte
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == right.__object ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, right.__object,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
+			  right.__object, left_descriptor->__size))
     return 1;
   return 0;
 }
Index: libgo/runtime/go-interface-eface-compare.c
===================================================================
--- libgo/runtime/go-interface-eface-compare.c	(revision 228306)
+++ libgo/runtime/go-interface-eface-compare.c	(working copy)
@@ -27,8 +27,8 @@  __go_interface_empty_compare (struct __g
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == right.__object ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, right.__object,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
+			  right.__object, left_descriptor->__size))
     return 1;
   return 0;
 }
Index: libgo/runtime/go-interface-val-compare.c
===================================================================
--- libgo/runtime/go-interface-val-compare.c	(revision 228306)
+++ libgo/runtime/go-interface-val-compare.c	(working copy)
@@ -26,8 +26,8 @@  __go_interface_value_compare (
     return 1;
   if (__go_is_pointer_type (left_descriptor))
     return left.__object == val ? 0 : 1;
-  if (!left_descriptor->__equalfn (left.__object, val,
-				   left_descriptor->__size))
+  if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
+			  left_descriptor->__size))
     return 1;
   return 0;
 }
Index: libgo/runtime/go-map-delete.c
===================================================================
--- libgo/runtime/go-map-delete.c	(revision 228306)
+++ libgo/runtime/go-map-delete.c	(working copy)
@@ -21,7 +21,7 @@  __go_map_delete (struct __go_map *map, c
   const struct __go_map_descriptor *descriptor;
   const struct __go_type_descriptor *key_descriptor;
   uintptr_t key_offset;
-  _Bool (*equalfn) (const void*, const void*, uintptr_t);
+  const FuncVal *equalfn;
   size_t key_hash;
   size_t key_size;
   size_t bucket_index;
@@ -41,14 +41,14 @@  __go_map_delete (struct __go_map *map, c
   __go_assert (key_size != -1UL);
   equalfn = key_descriptor->__equalfn;
 
-  key_hash = key_descriptor->__hashfn (key, key_size);
+  key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size);
   bucket_index = key_hash % map->__bucket_count;
 
   pentry = map->__buckets + bucket_index;
   while (*pentry != NULL)
     {
       char *entry = (char *) *pentry;
-      if (equalfn (key, entry + key_offset, key_size))
+      if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size))
 	{
 	  *pentry = *(void **) entry;
 	  if (descriptor->__entry_size >= TinySize)
Index: libgo/runtime/go-map-index.c
===================================================================
--- libgo/runtime/go-map-index.c	(revision 228306)
+++ libgo/runtime/go-map-index.c	(working copy)
@@ -22,7 +22,7 @@  __go_map_rehash (struct __go_map *map)
   const struct __go_type_descriptor *key_descriptor;
   uintptr_t key_offset;
   size_t key_size;
-  uintptr_t (*hashfn) (const void *, uintptr_t);
+  const FuncVal *hashfn;
   uintptr_t old_bucket_count;
   void **old_buckets;
   uintptr_t new_bucket_count;
@@ -55,7 +55,7 @@  __go_map_rehash (struct __go_map *map)
 
 	  /* We could speed up rehashing at the cost of memory space
 	     by caching the hash code.  */
-	  key_hash = hashfn (entry + key_offset, key_size);
+	  key_hash = __go_call_hashfn (hashfn, entry + key_offset, key_size);
 	  new_bucket_index = key_hash % new_bucket_count;
 
 	  next = *(char **) entry;
@@ -82,7 +82,7 @@  __go_map_index (struct __go_map *map, co
   const struct __go_map_descriptor *descriptor;
   const struct __go_type_descriptor *key_descriptor;
   uintptr_t key_offset;
-  _Bool (*equalfn) (const void*, const void*, uintptr_t);
+  const FuncVal *equalfn;
   size_t key_hash;
   size_t key_size;
   size_t bucket_index;
@@ -103,13 +103,13 @@  __go_map_index (struct __go_map *map, co
   __go_assert (key_size != -1UL);
   equalfn = key_descriptor->__equalfn;
 
-  key_hash = key_descriptor->__hashfn (key, key_size);
+  key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size);
   bucket_index = key_hash % map->__bucket_count;
 
   entry = (char *) map->__buckets[bucket_index];
   while (entry != NULL)
     {
-      if (equalfn (key, entry + key_offset, key_size))
+      if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size))
 	return entry + descriptor->__val_offset;
       entry = *(char **) entry;
     }
Index: libgo/runtime/go-reflect-map.c
===================================================================
--- libgo/runtime/go-reflect-map.c	(revision 228306)
+++ libgo/runtime/go-reflect-map.c	(working copy)
@@ -151,5 +151,6 @@  extern _Bool ismapkey (const struct __go
 _Bool
 ismapkey (const struct __go_type_descriptor *typ)
 {
-  return typ != NULL && typ->__hashfn != __go_type_hash_error;
+  return (typ != NULL
+	  && (void *) typ->__hashfn->fn != (void *) __go_type_hash_error);
 }
Index: libgo/runtime/go-type-complex.c
===================================================================
--- libgo/runtime/go-type-complex.c	(revision 228306)
+++ libgo/runtime/go-type-complex.c	(working copy)
@@ -84,6 +84,9 @@  __go_type_hash_complex (const void *vkey
     runtime_throw ("__go_type_hash_complex: invalid complex size");
 }
 
+const FuncVal __go_type_hash_complex_descriptor =
+  { (void *) __go_type_hash_complex };
+
 /* Equality function for complex types.  */
 
 _Bool
@@ -112,3 +115,6 @@  __go_type_equal_complex (const void *vk1
   else
     runtime_throw ("__go_type_equal_complex: invalid complex size");
 }
+
+const FuncVal __go_type_equal_complex_descriptor =
+  { (void *) __go_type_equal_complex };
Index: libgo/runtime/go-type-eface.c
===================================================================
--- libgo/runtime/go-type-eface.c	(revision 228306)
+++ libgo/runtime/go-type-eface.c	(working copy)
@@ -24,11 +24,14 @@  __go_type_hash_empty_interface (const vo
     return 0;
   size = descriptor->__size;
   if (__go_is_pointer_type (descriptor))
-    return descriptor->__hashfn (&val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
   else
-    return descriptor->__hashfn (val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, val->__object, size);
 }
 
+const FuncVal __go_type_hash_empty_interface_descriptor =
+  { (void *) __go_type_hash_empty_interface };
+
 /* An equality function for an empty interface.  */
 
 _Bool
@@ -51,6 +54,9 @@  __go_type_equal_empty_interface (const v
   if (__go_is_pointer_type (v1_descriptor))
     return v1->__object == v2->__object;
   else
-    return v1_descriptor->__equalfn (v1->__object, v2->__object,
-				     v1_descriptor->__size);
+    return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
+			      v2->__object, v1_descriptor->__size);
 }
+
+const FuncVal __go_type_equal_empty_interface_descriptor =
+  { (void *) __go_type_equal_empty_interface };
Index: libgo/runtime/go-type-error.c
===================================================================
--- libgo/runtime/go-type-error.c	(revision 228306)
+++ libgo/runtime/go-type-error.c	(working copy)
@@ -17,6 +17,9 @@  __go_type_hash_error (const void *val __
   runtime_panicstring ("hash of unhashable type");
 }
 
+const FuncVal __go_type_hash_error_descriptor =
+  { (void *) __go_type_hash_error };
+
 /* An equality function for an interface.  */
 
 _Bool
@@ -26,3 +29,6 @@  __go_type_equal_error (const void *v1 __
 {
   runtime_panicstring ("comparing uncomparable types");
 }
+
+const FuncVal __go_type_equal_error_descriptor =
+  { (void *) __go_type_equal_error };
Index: libgo/runtime/go-type-float.c
===================================================================
--- libgo/runtime/go-type-float.c	(revision 228306)
+++ libgo/runtime/go-type-float.c	(working copy)
@@ -56,6 +56,9 @@  __go_type_hash_float (const void *vkey,
     runtime_throw ("__go_type_hash_float: invalid float size");
 }
 
+const FuncVal __go_type_hash_float_descriptor =
+  { (void *) __go_type_hash_float };
+
 /* Equality function for float types.  */
 
 _Bool
@@ -84,3 +87,6 @@  __go_type_equal_float (const void *vk1,
   else
     runtime_throw ("__go_type_equal_float: invalid float size");
 }
+
+const FuncVal __go_type_equal_float_descriptor =
+  { (void *) __go_type_equal_float };
Index: libgo/runtime/go-type-identity.c
===================================================================
--- libgo/runtime/go-type-identity.c	(revision 228306)
+++ libgo/runtime/go-type-identity.c	(working copy)
@@ -45,6 +45,9 @@  __go_type_hash_identity (const void *key
   return ret;
 }
 
+const FuncVal __go_type_hash_identity_descriptor =
+  { (void *) __go_type_hash_identity };
+
 /* An identity equality function for a type.  This is used for types
    where we can check for equality by checking that the values have
    the same bits.  */
@@ -54,3 +57,6 @@  __go_type_equal_identity (const void *k1
 {
   return __builtin_memcmp (k1, k2, key_size) == 0;
 }
+
+const FuncVal __go_type_equal_identity_descriptor =
+  { (void *) __go_type_equal_identity };
Index: libgo/runtime/go-type-interface.c
===================================================================
--- libgo/runtime/go-type-interface.c	(revision 228306)
+++ libgo/runtime/go-type-interface.c	(working copy)
@@ -24,11 +24,14 @@  __go_type_hash_interface (const void *vv
   descriptor = (const struct __go_type_descriptor *) val->__methods[0];
   size = descriptor->__size;
   if (__go_is_pointer_type (descriptor))
-    return descriptor->__hashfn (&val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
   else
-    return descriptor->__hashfn (val->__object, size);
+    return __go_call_hashfn (descriptor->__hashfn, val->__object, size);
 }
 
+const FuncVal __go_type_hash_interface_descriptor =
+  { (void *) __go_type_hash_interface };
+
 /* An equality function for an interface.  */
 
 _Bool
@@ -51,6 +54,9 @@  __go_type_equal_interface (const void *v
   if (__go_is_pointer_type (v1_descriptor))
     return v1->__object == v2->__object;
   else
-    return v1_descriptor->__equalfn (v1->__object, v2->__object,
-				     v1_descriptor->__size);
+    return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
+			      v2->__object, v1_descriptor->__size);
 }
+
+const FuncVal __go_type_equal_interface_descriptor =
+  { (void *) __go_type_equal_interface };
Index: libgo/runtime/go-type-string.c
===================================================================
--- libgo/runtime/go-type-string.c	(revision 228306)
+++ libgo/runtime/go-type-string.c	(working copy)
@@ -28,6 +28,9 @@  __go_type_hash_string (const void *vkey,
   return ret;
 }
 
+const FuncVal __go_type_hash_string_descriptor =
+  { (void *) __go_type_hash_string };
+
 /* A string equality function for a map.  */
 
 _Bool
@@ -41,3 +44,6 @@  __go_type_equal_string (const void *vk1,
   k2 = (const String *) vk2;
   return __go_ptr_strings_equal (k1, k2);
 }
+
+const FuncVal __go_type_equal_string_descriptor =
+  { (void *) __go_type_equal_string };
Index: libgo/runtime/go-type.h
===================================================================
--- libgo/runtime/go-type.h	(revision 228306)
+++ libgo/runtime/go-type.h	(working copy)
@@ -89,11 +89,11 @@  struct __go_type_descriptor
      size of this type, and returns a hash code.  We pass the size
      explicitly becaues it means that we can share a single instance
      of this function for various different types.  */
-  uintptr_t (*__hashfn) (const void *, uintptr_t);
+  const FuncVal *__hashfn;
 
   /* This function takes two pointers to values of this type, and the
      size of this type, and returns whether the values are equal.  */
-  _Bool (*__equalfn) (const void *, const void *, uintptr_t);
+  const FuncVal *__equalfn;
 
   /* The garbage collection data. */
   const uintptr *__gc;
@@ -316,21 +316,52 @@  __go_is_pointer_type (const struct __go_
 	  || (td->__code & GO_CODE_MASK) == GO_UNSAFE_POINTER);
 }
 
+/* Call a type hash function, given the __hashfn value.  */
+
+static inline uintptr_t
+__go_call_hashfn (const FuncVal *hashfn, const void *p, uintptr_t size)
+{
+  uintptr_t (*h) (const void *, uintptr_t) = (void *) hashfn->fn;
+  return __builtin_call_with_static_chain (h (p, size), hashfn);
+}
+
+/* Call a type equality function, given the __equalfn value.  */
+
+static inline _Bool
+__go_call_equalfn (const FuncVal *equalfn, const void *p1, const void *p2,
+		   uintptr_t size)
+{
+  _Bool (*e) (const void *, const void *, uintptr_t) = (void *) equalfn->fn;
+  return __builtin_call_with_static_chain (e (p1, p2, size), equalfn);
+}
+
 extern _Bool
 __go_type_descriptors_equal(const struct __go_type_descriptor*,
 			    const struct __go_type_descriptor*);
 
 extern uintptr_t __go_type_hash_identity (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_identity_descriptor;
 extern _Bool __go_type_equal_identity (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_identity_descriptor;
 extern uintptr_t __go_type_hash_string (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_string_descriptor;
 extern _Bool __go_type_equal_string (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_string_descriptor;
 extern uintptr_t __go_type_hash_float (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_float_descriptor;
 extern _Bool __go_type_equal_float (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_float_descriptor;
 extern uintptr_t __go_type_hash_complex (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_complex_descriptor;
 extern _Bool __go_type_equal_complex (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_complex_descriptor;
 extern uintptr_t __go_type_hash_interface (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_interface_descriptor;
 extern _Bool __go_type_equal_interface (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_interface_descriptor;
 extern uintptr_t __go_type_hash_error (const void *, uintptr_t);
+extern const FuncVal __go_type_hash_error_descriptor;
 extern _Bool __go_type_equal_error (const void *, const void *, uintptr_t);
+extern const FuncVal __go_type_equal_error_descriptor;
 
 #endif /* !defined(LIBGO_GO_TYPE_H) */
Index: libgo/runtime/go-unsafe-pointer.c
===================================================================
--- libgo/runtime/go-unsafe-pointer.c	(revision 228306)
+++ libgo/runtime/go-unsafe-pointer.c	(working copy)
@@ -54,9 +54,9 @@  const struct __go_type_descriptor unsafe
   /* __hash */
   78501163U,
   /* __hashfn */
-  __go_type_hash_identity,
+  &__go_type_hash_identity_descriptor,
   /* __equalfn */
-  __go_type_equal_identity,
+  &__go_type_equal_identity_descriptor,
   /* __gc */
   unsafe_Pointer_gc,
   /* __reflection */
@@ -99,9 +99,9 @@  const struct __go_ptr_type pointer_unsaf
     /* __hash */
     1256018616U,
     /* __hashfn */
-    __go_type_hash_identity,
+    &__go_type_hash_identity_descriptor,
     /* __equalfn */
-    __go_type_equal_identity,
+    &__go_type_equal_identity_descriptor,
     /* __gc */
     unsafe_Pointer_gc,
     /* __reflection */
Index: libgo/runtime/proc.c
===================================================================
--- libgo/runtime/proc.c	(revision 228306)
+++ libgo/runtime/proc.c	(working copy)
@@ -528,9 +528,9 @@  static struct __go_channel_type chan_boo
       /* __hash */
       0, /* This value doesn't matter.  */
       /* __hashfn */
-      __go_type_hash_error,
+      &__go_type_hash_error_descriptor,
       /* __equalfn */
-      __go_type_equal_error,
+      &__go_type_equal_error_descriptor,
       /* __gc */
       NULL, /* This value doesn't matter */
       /* __reflection */