< prev index next >

src/java.base/share/classes/jdk/internal/jimage/ImageLocation.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

*** 57,93 **** ImageStrings getStrings() { return strings; } - private static int attributeLength(int data) { - return (data & 0x7) + 1; - } - - private static int attributeKind(int data) { - return data >>> 3; - } - static long[] decompress(ByteBuffer bytes) { Objects.requireNonNull(bytes); long[] attributes = new long[ATTRIBUTE_COUNT]; if (bytes != null) { while (bytes.hasRemaining()) { int data = bytes.get() & 0xFF; ! int kind = attributeKind(data); if (kind == ATTRIBUTE_END) { break; } if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { throw new InternalError( "Invalid jimage attribute kind: " + kind); } ! int length = attributeLength(data); long value = 0; for (int j = 0; j < length; j++) { value <<= 8; --- 57,85 ---- ImageStrings getStrings() { return strings; } static long[] decompress(ByteBuffer bytes) { Objects.requireNonNull(bytes); long[] attributes = new long[ATTRIBUTE_COUNT]; if (bytes != null) { while (bytes.hasRemaining()) { int data = bytes.get() & 0xFF; ! int kind = data >>> 3; if (kind == ATTRIBUTE_END) { break; } if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { throw new InternalError( "Invalid jimage attribute kind: " + kind); } ! int length = (data & 0x7) + 1; long value = 0; for (int j = 0; j < length; j++) { value <<= 8;
*** 126,138 **** return stream.toArray(); } public boolean verify(String name) { Objects.requireNonNull(name); ! return name.equals(getFullName()); } long getAttribute(int kind) { if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { throw new InternalError( --- 118,204 ---- return stream.toArray(); } public boolean verify(String name) { + return verify(name, attributes, strings); + } + + /** + * A simpler verification would be {@code name.equals(getFullName())}, but + * by not creating the full name and enabling early returns we allocate + * fewer objects. Could possibly be made allocation free by extending + * ImageStrings to test if strings at an offset match the name region. + */ + static boolean verify(String name, final long[] attributes, + final ImageStrings strings) { Objects.requireNonNull(name); + final int length = name.length(); + int index = 0; + int moduleOffset = (int)attributes[ATTRIBUTE_MODULE]; + if (moduleOffset != 0) { + String module = strings.get(moduleOffset); + final int moduleLen = module.length(); + index = moduleLen + 1; + if (length <= index + || name.charAt(0) != '/' + || !name.regionMatches(1, module, 0, moduleLen) + || name.charAt(index++) != '/') { + return false; + } + } ! return verifyName(name, index, length, attributes, strings); ! } ! ! static boolean verify(String module, String name, ! final long[] attributes, final ImageStrings strings) { ! Objects.requireNonNull(module); ! Objects.requireNonNull(name); ! int moduleOffset = (int)attributes[ATTRIBUTE_MODULE]; ! if (moduleOffset != 0) { ! if (!module.equals(strings.get(moduleOffset))) { ! return false; ! } ! } ! ! return verifyName(name, 0, name.length(), attributes, strings); ! } ! ! private static boolean verifyName(String name, int index, final int length, ! final long[] attributes, final ImageStrings strings) { ! ! int parentOffset = (int) attributes[ATTRIBUTE_PARENT]; ! if (parentOffset != 0) { ! String parent = strings.get(parentOffset); ! final int parentLen = parent.length(); ! if (!name.regionMatches(index, parent, 0, parentLen)) { ! return false; ! } ! index += parentLen; ! if (length <= index || name.charAt(index++) != '/') { ! return false; ! } ! } ! String base = strings.get((int) attributes[ATTRIBUTE_BASE]); ! final int baseLen = base.length(); ! if (!name.regionMatches(index, base, 0, baseLen)) { ! return false; ! } ! index += baseLen; ! int extOffset = (int) attributes[ATTRIBUTE_EXTENSION]; ! if (extOffset != 0) { ! String extension = strings.get(extOffset); ! int extLen = extension.length(); ! if (length <= index ! || name.charAt(index++) != '.' ! || !name.regionMatches(index, extension, 0, extLen)) { ! return false; ! } ! index += extLen; ! } ! return length == index; } long getAttribute(int kind) { if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { throw new InternalError(
< prev index next >