summaryrefslogtreecommitdiff
path: root/libgo/runtime
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-29 17:14:51 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-10-29 17:14:51 +0000
commit09e5769840d85ea7a5b64f1804b7104d6abb4c9d (patch)
tree51c7bcf037fe05935e1479b498e56d84212089b1 /libgo/runtime
parent758c9897fe1980843ed7f0dfa033bb335110d5e0 (diff)
downloadgcc-09e5769840d85ea7a5b64f1804b7104d6abb4c9d.tar.gz
compiler, runtime: change type hash/equal to Go funcs
Change the type descriptor hash and equal functions from C code pointers to Go func values. This permits them to be set to a Go function closure. This is in preparation for the Go 1.5, so that we can use a closure for the hash/equal functions returned by the new reflect.ArrayOf function. Reviewed-on: https://go-review.googlesource.com/16485 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229541 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/runtime')
-rw-r--r--libgo/runtime/go-eface-compare.c4
-rw-r--r--libgo/runtime/go-eface-val-compare.c4
-rw-r--r--libgo/runtime/go-interface-compare.c4
-rw-r--r--libgo/runtime/go-interface-eface-compare.c4
-rw-r--r--libgo/runtime/go-interface-val-compare.c4
-rw-r--r--libgo/runtime/go-map-delete.c6
-rw-r--r--libgo/runtime/go-map-index.c10
-rw-r--r--libgo/runtime/go-reflect-map.c3
-rw-r--r--libgo/runtime/go-type-complex.c6
-rw-r--r--libgo/runtime/go-type-eface.c14
-rw-r--r--libgo/runtime/go-type-error.c6
-rw-r--r--libgo/runtime/go-type-float.c6
-rw-r--r--libgo/runtime/go-type-identity.c6
-rw-r--r--libgo/runtime/go-type-interface.c14
-rw-r--r--libgo/runtime/go-type-string.c6
-rw-r--r--libgo/runtime/go-type.h35
-rw-r--r--libgo/runtime/go-unsafe-pointer.c8
-rw-r--r--libgo/runtime/proc.c4
18 files changed, 109 insertions, 35 deletions
diff --git a/libgo/runtime/go-eface-compare.c b/libgo/runtime/go-eface-compare.c
index 3555a65d9cc..40b716eb4af 100644
--- a/libgo/runtime/go-eface-compare.c
+++ b/libgo/runtime/go-eface-compare.c
@@ -28,8 +28,8 @@ __go_empty_interface_compare (struct __go_empty_interface left,
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;
}
diff --git a/libgo/runtime/go-eface-val-compare.c b/libgo/runtime/go-eface-val-compare.c
index 743f126ec1e..e810750d5db 100644
--- a/libgo/runtime/go-eface-val-compare.c
+++ b/libgo/runtime/go-eface-val-compare.c
@@ -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;
}
diff --git a/libgo/runtime/go-interface-compare.c b/libgo/runtime/go-interface-compare.c
index 6374bd2fb42..1d367753a1e 100644
--- a/libgo/runtime/go-interface-compare.c
+++ b/libgo/runtime/go-interface-compare.c
@@ -28,8 +28,8 @@ __go_interface_compare (struct __go_interface left,
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;
}
diff --git a/libgo/runtime/go-interface-eface-compare.c b/libgo/runtime/go-interface-eface-compare.c
index a38917fd0c6..d1e6fd084d2 100644
--- a/libgo/runtime/go-interface-eface-compare.c
+++ b/libgo/runtime/go-interface-eface-compare.c
@@ -27,8 +27,8 @@ __go_interface_empty_compare (struct __go_interface left,
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;
}
diff --git a/libgo/runtime/go-interface-val-compare.c b/libgo/runtime/go-interface-val-compare.c
index e2dae6a1892..36b6efdc9f1 100644
--- a/libgo/runtime/go-interface-val-compare.c
+++ b/libgo/runtime/go-interface-val-compare.c
@@ -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;
}
diff --git a/libgo/runtime/go-map-delete.c b/libgo/runtime/go-map-delete.c
index aff25d104bf..fb7c331856e 100644
--- a/libgo/runtime/go-map-delete.c
+++ b/libgo/runtime/go-map-delete.c
@@ -21,7 +21,7 @@ __go_map_delete (struct __go_map *map, const void *key)
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, const void *key)
__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)
diff --git a/libgo/runtime/go-map-index.c b/libgo/runtime/go-map-index.c
index 616b00c68c8..353041db6c4 100644
--- a/libgo/runtime/go-map-index.c
+++ b/libgo/runtime/go-map-index.c
@@ -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, const void *key, _Bool insert)
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, const void *key, _Bool insert)
__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;
}
diff --git a/libgo/runtime/go-reflect-map.c b/libgo/runtime/go-reflect-map.c
index 58e1b34a1ea..36f31025d30 100644
--- a/libgo/runtime/go-reflect-map.c
+++ b/libgo/runtime/go-reflect-map.c
@@ -151,5 +151,6 @@ extern _Bool ismapkey (const struct __go_type_descriptor *)
_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);
}
diff --git a/libgo/runtime/go-type-complex.c b/libgo/runtime/go-type-complex.c
index 0f8f0627d73..585984e9fef 100644
--- a/libgo/runtime/go-type-complex.c
+++ b/libgo/runtime/go-type-complex.c
@@ -84,6 +84,9 @@ __go_type_hash_complex (const void *vkey, uintptr_t key_size)
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, const void *vk2, uintptr_t key_size)
else
runtime_throw ("__go_type_equal_complex: invalid complex size");
}
+
+const FuncVal __go_type_equal_complex_descriptor =
+ { (void *) __go_type_equal_complex };
diff --git a/libgo/runtime/go-type-eface.c b/libgo/runtime/go-type-eface.c
index 30614d25112..315c30efb7f 100644
--- a/libgo/runtime/go-type-eface.c
+++ b/libgo/runtime/go-type-eface.c
@@ -24,11 +24,14 @@ __go_type_hash_empty_interface (const void *vval,
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 void *vv1, const void *vv2,
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 };
diff --git a/libgo/runtime/go-type-error.c b/libgo/runtime/go-type-error.c
index b4c609b93ec..8881a86f6e0 100644
--- a/libgo/runtime/go-type-error.c
+++ b/libgo/runtime/go-type-error.c
@@ -17,6 +17,9 @@ __go_type_hash_error (const void *val __attribute__ ((unused)),
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 __attribute__ ((unused)),
{
runtime_panicstring ("comparing uncomparable types");
}
+
+const FuncVal __go_type_equal_error_descriptor =
+ { (void *) __go_type_equal_error };
diff --git a/libgo/runtime/go-type-float.c b/libgo/runtime/go-type-float.c
index 4ae73470de9..39f9b29ae7d 100644
--- a/libgo/runtime/go-type-float.c
+++ b/libgo/runtime/go-type-float.c
@@ -56,6 +56,9 @@ __go_type_hash_float (const void *vkey, uintptr_t key_size)
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, const void *vk2, uintptr_t key_size)
else
runtime_throw ("__go_type_equal_float: invalid float size");
}
+
+const FuncVal __go_type_equal_float_descriptor =
+ { (void *) __go_type_equal_float };
diff --git a/libgo/runtime/go-type-identity.c b/libgo/runtime/go-type-identity.c
index ed510f75a72..a334d56cbe4 100644
--- a/libgo/runtime/go-type-identity.c
+++ b/libgo/runtime/go-type-identity.c
@@ -45,6 +45,9 @@ __go_type_hash_identity (const void *key, uintptr_t key_size)
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, const void *k2, uintptr_t key_size)
{
return __builtin_memcmp (k1, k2, key_size) == 0;
}
+
+const FuncVal __go_type_equal_identity_descriptor =
+ { (void *) __go_type_equal_identity };
diff --git a/libgo/runtime/go-type-interface.c b/libgo/runtime/go-type-interface.c
index 9aad720085c..e9e577956eb 100644
--- a/libgo/runtime/go-type-interface.c
+++ b/libgo/runtime/go-type-interface.c
@@ -24,11 +24,14 @@ __go_type_hash_interface (const void *vval,
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 *vv1, const void *vv2,
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 };
diff --git a/libgo/runtime/go-type-string.c b/libgo/runtime/go-type-string.c
index a96af0290b2..3d33d6ee510 100644
--- a/libgo/runtime/go-type-string.c
+++ b/libgo/runtime/go-type-string.c
@@ -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, const void *vk2,
k2 = (const String *) vk2;
return __go_ptr_strings_equal (k1, k2);
}
+
+const FuncVal __go_type_equal_string_descriptor =
+ { (void *) __go_type_equal_string };
diff --git a/libgo/runtime/go-type.h b/libgo/runtime/go-type.h
index d7693353039..72c9f56986e 100644
--- a/libgo/runtime/go-type.h
+++ b/libgo/runtime/go-type.h
@@ -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_type_descriptor *td)
|| (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) */
diff --git a/libgo/runtime/go-unsafe-pointer.c b/libgo/runtime/go-unsafe-pointer.c
index 71364f511b4..a59ae852185 100644
--- a/libgo/runtime/go-unsafe-pointer.c
+++ b/libgo/runtime/go-unsafe-pointer.c
@@ -54,9 +54,9 @@ const struct __go_type_descriptor unsafe_Pointer =
/* __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_unsafe_Pointer =
/* __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 */
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index babad01ea95..db8b94f28f7 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -528,9 +528,9 @@ static struct __go_channel_type chan_bool_type_descriptor =
/* __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 */