# HG changeset patch # User Tom Rodriguez # Date 1406680800 25200 # Node ID 3812931f935003259027f59e3eabd32771574956 # Parent 0f2a9150d6f84024551197fc4766ede834a6dc12 Don't read beyond end of known vtable diff -r 0f2a9150d6f8 -r 3812931f9350 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Jul 29 17:39:11 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Jul 29 17:40:00 2014 -0700 @@ -848,6 +848,8 @@ @HotSpotVMType(name = "vtableEntry", get = HotSpotVMType.Type.SIZE) @Stable public int vtableEntrySize; @HotSpotVMField(name = "vtableEntry::_method", type = "Method*", get = HotSpotVMField.Type.OFFSET) @Stable public int vtableEntryMethodOffset; @HotSpotVMValue(expression = "InstanceKlass::vtable_start_offset() * HeapWordSize") @Stable public int instanceKlassVtableStartOffset; + @HotSpotVMValue(expression = "InstanceKlass::vtable_length_offset() * HeapWordSize") @Stable public int instanceKlassVtableLengthOffset; + @HotSpotVMValue(expression = "Universe::base_vtable_size() / vtableEntry::size()") @Stable public int baseVtableLength; /** * The offset of the array length word in an array object's header. diff -r 0f2a9150d6f8 -r 3812931f9350 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Tue Jul 29 17:39:11 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Tue Jul 29 17:40:00 2014 -0700 @@ -612,21 +612,26 @@ public int vtableEntryOffset(ResolvedJavaType resolved) { guarantee(isInVirtualMethodTable(resolved), "%s does not have a vtable entry", this); HotSpotVMConfig config = runtime().getConfig(); - final int vtableIndex = getVtableIndex(resolved); + final int vtableIndex = getVtableIndex((HotSpotResolvedObjectType) resolved); return config.instanceKlassVtableStartOffset + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset; } @Override public boolean isInVirtualMethodTable(ResolvedJavaType resolved) { - return getVtableIndex(resolved) >= 0; + if (resolved instanceof HotSpotResolvedObjectType) { + HotSpotResolvedObjectType hotspotResolved = (HotSpotResolvedObjectType) resolved; + int vtableIndex = getVtableIndex(hotspotResolved); + return vtableIndex >= 0 && vtableIndex < hotspotResolved.getVtableLength(); + } + return false; } - private int getVtableIndex(ResolvedJavaType resolved) { + private int getVtableIndex(HotSpotResolvedObjectType resolved) { if (!holder.isLinked()) { return runtime().getConfig().invalidVtableIndex; } if (holder.isInterface()) { - if (resolved.isArray() || resolved.isInterface()) { + if (resolved.isInterface()) { return runtime().getConfig().invalidVtableIndex; } return getVtableIndexForInterface(resolved); diff -r 0f2a9150d6f8 -r 3812931f9350 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jul 29 17:39:11 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jul 29 17:40:00 2014 -0700 @@ -436,6 +436,17 @@ return method; } + public int getVtableLength() { + HotSpotVMConfig config = runtime().getConfig(); + if (isInterface() || isArray()) { + /* Everything has the core vtable of java.lang.Object */ + return config.baseVtableLength; + } + int result = unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) / (config.vtableEntrySize / config.heapWordSize); + assert result >= config.baseVtableLength : unsafe.getInt(getMetaspaceKlass() + config.instanceKlassVtableLengthOffset) + " " + config.vtableEntrySize; + return result; + } + /** * Gets the mask used to filter out HotSpot internal flags for fields when a {@link Field} * object is created. This is the value of {@code JVM_RECOGNIZED_FIELD_MODIFIERS} in