< prev index next >
src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java
Print this page
rev 16767 : 8175561: Memory churn in jimage code affects startup after resource encapsulation changes
Reviewed-by: jlaskey
rev 16768 : imported patch imgstr_oneup
@@ -36,10 +36,12 @@
* but also compiled and delivered as part of the jrtfs.jar to support access
* to the jimage file provided by the shipped JDK by tools running on JDK 8.
*/
public class ImageStringsReader implements ImageStrings {
public static final int HASH_MULTIPLIER = 0x01000193;
+ public static final int POSITIVE_MASK = 0x7FFFFFFF;
+
private final BasicImageReader reader;
ImageStringsReader(BasicImageReader reader) {
this.reader = Objects.requireNonNull(reader);
}
@@ -52,44 +54,64 @@
@Override
public int add(final String string) {
throw new InternalError("Can not add strings at runtime");
}
- private static int hashCode(byte[] bytes, int offset, int count, int seed) {
- Objects.requireNonNull(bytes);
-
- if (offset < 0 || count < 0 || offset > bytes.length - count) {
- throw new IndexOutOfBoundsException("offset=" + offset + ", count=" + count);
+ public static int hashCode(String string) {
+ return hashCode(string, HASH_MULTIPLIER);
}
- int limit = offset + count;
-
- if (limit < 0 || limit > bytes.length) {
- throw new IndexOutOfBoundsException("limit=" + limit);
+ public static int hashCode(String string, int seed) {
+ return unmaskedHashCode(string, seed) & POSITIVE_MASK;
}
- for (int i = offset; i < limit; i++) {
- seed = (seed * HASH_MULTIPLIER) ^ (bytes[i] & 0xFF);
+ public static int hashCode(String module, String string) {
+ return hashCode(module, string, HASH_MULTIPLIER);
}
- return seed & 0x7FFFFFFF;
+ public static int hashCode(String module, String string, int seed) {
+ seed = unmaskedHashCode("/", seed);
+ seed = unmaskedHashCode(module, seed);
+ seed = unmaskedHashCode("/", seed);
+ seed = unmaskedHashCode(string, seed);
+ return seed & POSITIVE_MASK;
}
- public static int hashCode(byte[] bytes, int seed) {
- return hashCode(bytes, 0, bytes.length, seed);
- }
+ public static int unmaskedHashCode(String string, int seed) {
+ int slen = string.length();
+ byte[] buffer = null;
- public static int hashCode(byte[] bytes) {
- return hashCode(bytes, 0, bytes.length, HASH_MULTIPLIER);
- }
+ for (int i = 0; i < slen; i++) {
+ char ch = string.charAt(i);
+ int uch = ch & 0xFFFF;
- public static int hashCode(String string, int seed) {
- return hashCode(mutf8FromString(string), seed);
+ if ((uch & ~0x7F) != 0) {
+ if (buffer == null) {
+ buffer = new byte[8];
}
+ int mask = ~0x3F;
+ int n = 0;
- public static int hashCode(String string) {
- return hashCode(mutf8FromString(string), HASH_MULTIPLIER);
+ do {
+ buffer[n++] = (byte)(0x80 | (uch & 0x3F));
+ uch >>= 6;
+ mask >>= 1;
+ } while ((uch & mask) != 0);
+
+ buffer[n] = (byte)((mask << 1) | uch);
+
+ do {
+ seed = (seed * HASH_MULTIPLIER) ^ (buffer[n--] & 0xFF);
+ } while (0 <= n);
+ } else if (uch == 0) {
+ seed = (seed * HASH_MULTIPLIER) ^ (0xC0);
+ seed = (seed * HASH_MULTIPLIER) ^ (0x80);
+ } else {
+ seed = (seed * HASH_MULTIPLIER) ^ (uch);
+ }
+ }
+ return seed;
}
static int charsFromMUTF8Length(byte[] bytes, int offset, int count) {
int length = 0;
@@ -177,11 +199,11 @@
}
throw new InternalError("No terminating zero byte for modified UTF-8 byte sequence");
}
- static void charsFromByteBuffer(char chars[], ByteBuffer buffer) {
+ static void charsFromByteBuffer(char[] chars, ByteBuffer buffer) {
int j = 0;
while(buffer.hasRemaining()) {
byte ch = buffer.get();
@@ -226,14 +248,16 @@
charsFromByteBuffer(chars, buffer);
return new String(chars);
}
- static int mutf8FromCharsLength(char chars[]) {
+ static int mutf8FromStringLength(String s) {
int length = 0;
+ int slen = s.length();
- for (char ch : chars) {
+ for (int i = 0; i < slen; i++) {
+ char ch = s.charAt(i);
int uch = ch & 0xFFFF;
if ((uch & ~0x7F) != 0) {
int mask = ~0x3F;
int n = 0;
@@ -253,18 +277,23 @@
}
return length;
}
- static void mutf8FromChars(byte[] bytes, int offset, char chars[]) {
+ static void mutf8FromString(byte[] bytes, int offset, String s) {
int j = offset;
- byte[] buffer = new byte[8];
+ byte[] buffer = null;
+ int slen = s.length();
- for (char ch : chars) {
+ for (int i = 0; i < slen; i++) {
+ char ch = s.charAt(i);
int uch = ch & 0xFFFF;
if ((uch & ~0x7F) != 0) {
+ if (buffer == null) {
+ buffer = new byte[8];
+ }
int mask = ~0x3F;
int n = 0;
do {
buffer[n++] = (byte)(0x80 | (uch & 0x3F));
@@ -285,13 +314,12 @@
}
}
}
public static byte[] mutf8FromString(String string) {
- char[] chars = string.toCharArray();
- int length = mutf8FromCharsLength(chars);
+ int length = mutf8FromStringLength(string);
byte[] bytes = new byte[length];
- mutf8FromChars(bytes, 0, chars);
+ mutf8FromString(bytes, 0, string);
return bytes;
}
}
< prev index next >