< 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 >