8033792: AltHashing used jint for imprecise bit shifting
Summary: AltHashing used jint the way of juint in bit shifting which could lead loss of precision. Fix by change _seed defined as juint.
Reviewed-by: coleenp, ccheung
Contributed-by: yumin.qi@oracle.com
--- a/hotspot/src/share/vm/classfile/altHashing.cpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/classfile/altHashing.cpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,18 +39,18 @@
}
// Seed value used for each alternative hash calculated.
-jint AltHashing::compute_seed() {
+juint AltHashing::compute_seed() {
jlong nanos = os::javaTimeNanos();
jlong now = os::javaTimeMillis();
- jint SEED_MATERIAL[8] = {
- (jint) object_hash(SystemDictionary::String_klass()),
- (jint) object_hash(SystemDictionary::System_klass()),
- (jint) os::random(), // current thread isn't a java thread
- (jint) (((julong)nanos) >> 32),
- (jint) nanos,
- (jint) (((julong)now) >> 32),
- (jint) now,
- (jint) (os::javaTimeNanos() >> 2)
+ int SEED_MATERIAL[8] = {
+ (int) object_hash(SystemDictionary::String_klass()),
+ (int) object_hash(SystemDictionary::System_klass()),
+ (int) os::random(), // current thread isn't a java thread
+ (int) (((julong)nanos) >> 32),
+ (int) nanos,
+ (int) (((julong)now) >> 32),
+ (int) now,
+ (int) (os::javaTimeNanos() >> 2)
};
return murmur3_32(SEED_MATERIAL, 8);
@@ -58,14 +58,14 @@
// Murmur3 hashing for Symbol
-jint AltHashing::murmur3_32(jint seed, const jbyte* data, int len) {
- jint h1 = seed;
+juint AltHashing::murmur3_32(juint seed, const jbyte* data, int len) {
+ juint h1 = seed;
int count = len;
int offset = 0;
// body
while (count >= 4) {
- jint k1 = (data[offset] & 0x0FF)
+ juint k1 = (data[offset] & 0x0FF)
| (data[offset + 1] & 0x0FF) << 8
| (data[offset + 2] & 0x0FF) << 16
| data[offset + 3] << 24;
@@ -85,7 +85,7 @@
// tail
if (count > 0) {
- jint k1 = 0;
+ juint k1 = 0;
switch (count) {
case 3:
@@ -109,18 +109,18 @@
h1 ^= len;
// finalization mix force all bits of a hash block to avalanche
- h1 ^= ((unsigned int)h1) >> 16;
+ h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
- h1 ^= ((unsigned int)h1) >> 13;
+ h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
- h1 ^= ((unsigned int)h1) >> 16;
+ h1 ^= h1 >> 16;
return h1;
}
// Murmur3 hashing for Strings
-jint AltHashing::murmur3_32(jint seed, const jchar* data, int len) {
- jint h1 = seed;
+juint AltHashing::murmur3_32(juint seed, const jchar* data, int len) {
+ juint h1 = seed;
int off = 0;
int count = len;
@@ -129,7 +129,7 @@
while (count >= 2) {
jchar d1 = data[off++] & 0xFFFF;
jchar d2 = data[off++];
- jint k1 = (d1 | d2 << 16);
+ juint k1 = (d1 | d2 << 16);
count -= 2;
@@ -145,7 +145,7 @@
// tail
if (count > 0) {
- int k1 = data[off];
+ juint k1 = (juint)data[off];
k1 *= 0xcc9e2d51;
k1 = Integer_rotateLeft(k1, 15);
@@ -157,25 +157,25 @@
h1 ^= len * 2; // (Character.SIZE / Byte.SIZE);
// finalization mix force all bits of a hash block to avalanche
- h1 ^= ((unsigned int)h1) >> 16;
+ h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
- h1 ^= ((unsigned int)h1) >> 13;
+ h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
- h1 ^= ((unsigned int)h1) >> 16;
+ h1 ^= h1 >> 16;
return h1;
}
// Hash used for the seed.
-jint AltHashing::murmur3_32(jint seed, const int* data, int len) {
- jint h1 = seed;
+juint AltHashing::murmur3_32(juint seed, const int* data, int len) {
+ juint h1 = seed;
int off = 0;
int end = len;
// body
while (off < end) {
- jint k1 = data[off++];
+ juint k1 = (juint)data[off++];
k1 *= 0xcc9e2d51;
k1 = Integer_rotateLeft(k1, 15);
@@ -193,26 +193,26 @@
h1 ^= len * 4; // (Integer.SIZE / Byte.SIZE);
// finalization mix force all bits of a hash block to avalanche
- h1 ^= ((juint)h1) >> 16;
+ h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
- h1 ^= ((juint)h1) >> 13;
+ h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
- h1 ^= ((juint)h1) >> 16;
+ h1 ^= h1 >> 16;
return h1;
}
-jint AltHashing::murmur3_32(const int* data, int len) {
+juint AltHashing::murmur3_32(const int* data, int len) {
return murmur3_32(0, data, len);
}
#ifndef PRODUCT
// Overloaded versions for internal test.
-jint AltHashing::murmur3_32(const jbyte* data, int len) {
+juint AltHashing::murmur3_32(const jbyte* data, int len) {
return murmur3_32(0, data, len);
}
-jint AltHashing::murmur3_32(const jchar* data, int len) {
+juint AltHashing::murmur3_32(const jchar* data, int len) {
return murmur3_32(0, data, len);
}
@@ -251,11 +251,11 @@
// Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
for (int i = 0; i < 256; i++) {
- jint hash = murmur3_32(256 - i, vector, i);
+ juint hash = murmur3_32(256 - i, vector, i);
hashes[i * 4] = (jbyte) hash;
- hashes[i * 4 + 1] = (jbyte) (((juint)hash) >> 8);
- hashes[i * 4 + 2] = (jbyte) (((juint)hash) >> 16);
- hashes[i * 4 + 3] = (jbyte) (((juint)hash) >> 24);
+ hashes[i * 4 + 1] = (jbyte)(hash >> 8);
+ hashes[i * 4 + 2] = (jbyte)(hash >> 16);
+ hashes[i * 4 + 3] = (jbyte)(hash >> 24);
}
// hash to get const result.
@@ -269,7 +269,7 @@
}
void AltHashing::testEquivalentHashes() {
- jint jbytes, jchars, ints;
+ juint jbytes, jchars, ints;
// printf("testEquivalentHashes\n");
--- a/hotspot/src/share/vm/classfile/altHashing.hpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/classfile/altHashing.hpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,24 +39,24 @@
class AltHashing : AllStatic {
// utility function copied from java/lang/Integer
- static jint Integer_rotateLeft(jint i, int distance) {
- return (i << distance) | (((juint)i) >> (32-distance));
+ static juint Integer_rotateLeft(juint i, int distance) {
+ return (i << distance) | (i >> (32-distance));
}
- static jint murmur3_32(const int* data, int len);
- static jint murmur3_32(jint seed, const int* data, int len);
+ static juint murmur3_32(const int* data, int len);
+ static juint murmur3_32(juint seed, const int* data, int len);
#ifndef PRODUCT
// Hashing functions used for internal testing
- static jint murmur3_32(const jbyte* data, int len);
- static jint murmur3_32(const jchar* data, int len);
+ static juint murmur3_32(const jbyte* data, int len);
+ static juint murmur3_32(const jchar* data, int len);
static void testMurmur3_32_ByteArray();
static void testEquivalentHashes();
#endif // PRODUCT
public:
- static jint compute_seed();
- static jint murmur3_32(jint seed, const jbyte* data, int len);
- static jint murmur3_32(jint seed, const jchar* data, int len);
+ static juint compute_seed();
+ static juint murmur3_32(juint seed, const jbyte* data, int len);
+ static juint murmur3_32(juint seed, const jchar* data, int len);
NOT_PRODUCT(static void test_alt_hash();)
};
#endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -554,6 +554,7 @@
if (hk == NULL) {
return NULL;
} else {
+ assert(*hk != NULL, "host klass should always be set if the address is not null");
return *hk;
}
}
--- a/hotspot/src/share/vm/oops/metadata.hpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/oops/metadata.hpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
int identity_hash() { return (int)(uintptr_t)this; }
// Rehashing support for tables containing pointers to this
- unsigned int new_hash(jint seed) { ShouldNotReachHere(); return 0; }
+ unsigned int new_hash(juint seed) { ShouldNotReachHere(); return 0; }
virtual bool is_klass() const volatile { return false; }
virtual bool is_method() const volatile { return false; }
--- a/hotspot/src/share/vm/oops/oop.cpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/oops/oop.cpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,7 @@
}
// When String table needs to rehash
-unsigned int oopDesc::new_hash(jint seed) {
+unsigned int oopDesc::new_hash(juint seed) {
EXCEPTION_MARK;
ResourceMark rm;
int length;
--- a/hotspot/src/share/vm/oops/oop.hpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/oops/oop.hpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -362,7 +362,7 @@
intptr_t slow_identity_hash();
// Alternate hashing code if string table is rehashed
- unsigned int new_hash(jint seed);
+ unsigned int new_hash(juint seed);
// marks are forwarded to stack when object is locked
bool has_displaced_mark() const;
--- a/hotspot/src/share/vm/oops/symbol.cpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/oops/symbol.cpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -207,7 +207,7 @@
}
// Alternate hashing for unbalanced symbol tables.
-unsigned int Symbol::new_hash(jint seed) {
+unsigned int Symbol::new_hash(juint seed) {
ResourceMark rm;
// Use alternate hashing algorithm on this symbol.
return AltHashing::murmur3_32(seed, (const jbyte*)as_C_string(), utf8_length());
--- a/hotspot/src/share/vm/oops/symbol.hpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/oops/symbol.hpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -154,7 +154,7 @@
int identity_hash() { return _identity_hash; }
// For symbol table alternate hashing
- unsigned int new_hash(jint seed);
+ unsigned int new_hash(juint seed);
// Reference counting. See comments above this class for when to use.
int refcount() const { return _refcount; }
--- a/hotspot/src/share/vm/utilities/hashtable.cpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -93,7 +93,7 @@
return false;
}
-template <class T, MEMFLAGS F> jint Hashtable<T, F>::_seed = 0;
+template <class T, MEMFLAGS F> juint Hashtable<T, F>::_seed = 0;
// Create a new table and using alternate hash code, populate the new table
// with the existing elements. This can be used to change the hash code
--- a/hotspot/src/share/vm/utilities/hashtable.hpp Mon Feb 10 14:07:11 2014 -0800
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp Mon Feb 10 21:29:14 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -280,7 +280,7 @@
// Function to move these elements into the new table.
void move_to(Hashtable<T, F>* new_table);
static bool use_alternate_hashcode() { return _seed != 0; }
- static jint seed() { return _seed; }
+ static juint seed() { return _seed; }
static int literal_size(Symbol *symbol);
static int literal_size(oop oop);
@@ -296,7 +296,7 @@
void dump_table(outputStream* st, const char *table_name);
private:
- static jint _seed;
+ static juint _seed;
};