From patchwork Thu Oct 29 18:14:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 537967 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6569F1402C4 for ; Fri, 30 Oct 2015 05:15:16 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=qYH0NWj6; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:content-type; q= dns; s=default; b=tlp1z2bOvn3/m3bQVqM68TETMtTgkBAcBjAvsRFzcOC5lu dO/5wX71tbAnqeOt64Ax/unWGZWI2/a26bW/aOETqrI8UuRMWI17ip4Tj8ZoiztV GncGvv5JV2Dgih8S6rM1KqOLgXJhWgyiRPMBhbm6Z/zh7VOSEVpMKrwAG1rko= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:content-type; s= default; bh=lJzWXEZSVt5zkhJBISvaC7LGDMc=; b=qYH0NWj6PFZLkn6EIldZ Ngl2IZ94fQEs5NvNL0jBTM4nUL0SrEvWdX/fzpVlLmmOLJjLD7DxFx3RcVwNonmc rUqxt4cuUxc82WnA4ETHxIWB7bFLs2r6kSQmCzwJwbH5h/0Kw08OWVCEllQpgXsM Kbk/6WranafcC7R9jvQo3yI= Received: (qmail 115787 invoked by alias); 29 Oct 2015 18:15:06 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 100924 invoked by uid 89); 29 Oct 2015 18:15:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.0 required=5.0 tests=AWL, BAYES_99, BAYES_999, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-ig0-f176.google.com Received: from mail-ig0-f176.google.com (HELO mail-ig0-f176.google.com) (209.85.213.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 29 Oct 2015 18:14:59 +0000 Received: by igpw7 with SMTP id w7so55011894igp.1 for ; Thu, 29 Oct 2015 11:14:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=W9m5AZ0vxEX9WG94pobwtHthuSYYvV96/Ws56UAPM6A=; b=VpiCpB2sfA/P0Wewjyqp02Id3u7PF17D79lxI0IQDRHBAxT1wW1/4vaMVZbnS5t88d chbkuhvHAjUULuaKcsq+87WqshIjBxZAy8JuMJtuVIsOn8gDwZPF1+nl6dSvtyVcN8jg 1Y7pzgKImTvzZ+YopELjFKLkc1DCnVnj2DJua+svPwb4+PFsNJRTIfE8dRV4nE3r+l1c rsCOVc22ZKQFUWIi00Azo05ULW/bN+BFVIm1ACwlYsl+f8g2perU0/sgBJQiut65rVGT azzT1O1XFCZyoUmW8u2Y9koNewcRdzaADOVlpcO5KQhMOiX8eO5V0Xd8IN4qDrMX/2S3 tkjw== X-Gm-Message-State: ALoCoQmdbM8xoxZjpLEnB4Ga4RSTY4yPh0c8zdQhBHad2ItjwyNCdw4EuI2CMgnDrp3Y+IHSXMmy MIME-Version: 1.0 X-Received: by 10.50.78.7 with SMTP id x7mr12481021igw.54.1446142497702; Thu, 29 Oct 2015 11:14:57 -0700 (PDT) Received: by 10.107.162.201 with HTTP; Thu, 29 Oct 2015 11:14:57 -0700 (PDT) Date: Thu, 29 Oct 2015 11:14:57 -0700 Message-ID: Subject: Go patch committed: Drop zero field from type descriptors From: Ian Lance Taylor To: gcc-patches , "gofrontend-dev@googlegroups.com" 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 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 */