Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

PR#6361 continued: don't count 1 for Forward_tag, because in this cas…

…e a GC can change the hash value. Instead, avoid looping on Forward_tag cycles by another mean.

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@14850 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
  • Loading branch information...
commit d12328e7b50ca6101216327516393b8a9f0fb6a6 1 parent 2a8d358
@xavierleroy xavierleroy authored
Showing with 11 additions and 5 deletions.
  1. +11 −5 byterun/hash.c
View
16 byterun/hash.c
@@ -172,6 +172,8 @@ CAMLexport uint32 caml_hash_mix_string(uint32 h, value s)
/* Maximal size of the queue used for breadth-first traversal. */
#define HASH_QUEUE_SIZE 256
+/* Maximal number of Forward_tag links followed in one step */
+#define MAX_FORWARD_DEREFERENCE 1000
/* The generic hash function */
@@ -226,11 +228,15 @@ CAMLprim value caml_hash(value count, value limit, value seed, value obj)
v = v - Infix_offset_val(v);
goto again;
case Forward_tag:
- v = Forward_val(v);
- /* PR#6361: this should count as 1, otherwise we can get into a loop */
- num--;
- if (num <= 0) break;
- goto again;
+ /* PR#6361: we can have a loop here, so limit the number of
+ Forward_tag links being followed */
+ for (i = MAX_FORWARD_DEREFERENCE; i > 0; i--) {
+ v = Forward_val(v);
+ if (Is_long(v) || !Is_in_value_area(v) || Tag_val(v) != Forward_tag)
+ goto again;
+ }
+ /* Give up on this object and move to the next */
+ break;
case Object_tag:
h = caml_hash_mix_intnat(h, Oid_val(v));
num--;
Please sign in to comment.
Something went wrong with that request. Please try again.