diff --git a/src/svalue.c b/src/svalue.c
index 0f960b2e53b8c5c02b4adb1e29f1c9df74bcae7f..40704c84730ddc01d58db6c9cd00bc9eda604951 100644
--- a/src/svalue.c
+++ b/src/svalue.c
@@ -408,6 +408,14 @@ PMOD_EXPORT void assign_short_svalue(union anything *to,
   }
 }
 
+static INLINE unsigned INT32 hash_ptr(void * ptr) {
+#if SIZEOF_CHAR_P > 4
+  return DO_NOT_WARN((unsigned INT32)(PTR_TO_INT(ptr) >> 2));
+#else
+  return DO_NOT_WARN((unsigned INT32)(PTR_TO_INT(ptr)));
+#endif
+}
+
 PMOD_EXPORT unsigned INT32 hash_svalue(const struct svalue *s)
 {
   unsigned INT32 q;
@@ -450,11 +458,19 @@ PMOD_EXPORT unsigned INT32 hash_svalue(const struct svalue *s)
     }
     /* FALL THROUGH */
   default:
-#if SIZEOF_CHAR_P > 4
-    q=DO_NOT_WARN((unsigned INT32)(PTR_TO_INT(s->u.ptr) >> 2));
-#else
-    q=DO_NOT_WARN((unsigned INT32)(PTR_TO_INT(s->u.ptr)));
-#endif
+    q = hash_ptr(s->u.ptr);
+    break;
+  case T_FUNCTION:
+    if ((SUBTYPEOF(*s) != FUNCTION_BUILTIN) && s->u.object
+        && s->u.object->prog == pike_trampoline_program) {
+
+      struct pike_trampoline *tramp = get_storage(s->u.object, pike_trampoline_program);
+      if (tramp) {
+        q = (unsigned INT32)tramp->func ^ hash_ptr(tramp->frame);
+        break;
+      }
+    }
+    q = hash_ptr(s->u.ptr);
     break;
   case T_INT:
     q=(unsigned INT32) s->u.integer;
diff --git a/src/testsuite.in b/src/testsuite.in
index 2091c4048778dbac009ed1541f66f7855d715f91..74ca4df03c00db3e947f1e90201da83690f94c76 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -11035,6 +11035,23 @@ test_hash_value(time)
 test_hash_value(ADT.Stack)
 dnl test_hash_value(String)
 test_hash_value(typeof(true))
+test_any([[
+    int v = 0;
+
+    void trampoline() {
+        v = 1;
+    };
+
+    int(0..1) check_hash()
+    {
+        function f1 = trampoline;
+        function f2 = trampoline;
+        return hash_value(f1) == hash_value(f2);
+    };
+
+    return check_hash();
+]], 1)
+
 
 // - indices
 test_equal(indices("foo"),({0,1,2}))