Skip to content

Commit 95c390e

Browse files
author
Doug Simon
committed
8296956: [JVMCI] HotSpotResolvedJavaFieldImpl.getIndex returns wrong value
Reviewed-by: thartmann, never
1 parent 68d3ed5 commit 95c390e

File tree

7 files changed

+175
-43
lines changed

7 files changed

+175
-43
lines changed

src/hotspot/share/runtime/fieldDescriptor.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class fieldDescriptor {
6262

6363
AccessFlags access_flags() const { return _access_flags; }
6464
oop loader() const;
65-
// Offset (in words) of field from start of instanceOop / Klass*
65+
// Offset (in bytes) of field from start of instanceOop / Klass*
6666
inline int offset() const;
6767
Symbol* generic_signature() const;
6868
int index() const { return _index; }

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -256,11 +256,23 @@ private static int rawIndexToConstantPoolCacheIndex(int rawIndex, int opcode) {
256256
if (opcode == Bytecodes.INVOKEDYNAMIC) {
257257
index = rawIndex;
258258
// See: ConstantPool::is_invokedynamic_index
259-
assert index < 0 : "not an invokedynamic constant pool index " + index;
259+
if (index >= 0) {
260+
throw new IllegalArgumentException("not an invokedynamic constant pool index " + index);
261+
}
260262
} else {
261-
assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE ||
262-
opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode;
263-
index = rawIndex + config().constantPoolCpCacheIndexTag;
263+
if (opcode == Bytecodes.GETFIELD ||
264+
opcode == Bytecodes.PUTFIELD ||
265+
opcode == Bytecodes.GETSTATIC ||
266+
opcode == Bytecodes.PUTSTATIC ||
267+
opcode == Bytecodes.INVOKEINTERFACE ||
268+
opcode == Bytecodes.INVOKEVIRTUAL ||
269+
opcode == Bytecodes.INVOKESPECIAL ||
270+
opcode == Bytecodes.INVOKESTATIC) {
271+
index = rawIndex + config().constantPoolCpCacheIndexTag;
272+
} else {
273+
throw new IllegalArgumentException("unexpected opcode " + opcode);
274+
275+
}
264276
}
265277
return index;
266278
}
@@ -292,7 +304,9 @@ private static boolean isInvokedynamicIndex(int index) {
292304
* See {@code ConstantPool::decode_invokedynamic_index}.
293305
*/
294306
private static int decodeInvokedynamicIndex(int i) {
295-
assert isInvokedynamicIndex(i) : i;
307+
if (!isInvokedynamicIndex(i)) {
308+
throw new IllegalArgumentException("not an invokedynamic index: " + i);
309+
}
296310
return ~i;
297311
}
298312

@@ -315,7 +329,7 @@ public long getMetadataHandle() {
315329
* @return constant pool tag
316330
*/
317331
private JvmConstant getTagAt(int index) {
318-
assert checkBounds(index);
332+
checkBounds(index);
319333
HotSpotVMConfig config = config();
320334
final long metaspaceConstantPoolTags = UNSAFE.getAddress(getConstantPoolPointer() + config.constantPoolTagsOffset);
321335
final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
@@ -332,7 +346,7 @@ private JvmConstant getTagAt(int index) {
332346
* @return constant pool entry
333347
*/
334348
long getEntryAt(int index) {
335-
assert checkBounds(index);
349+
checkBounds(index);
336350
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
337351
return UNSAFE.getAddress(getConstantPoolPointer() + config().constantPoolSize + offset);
338352
}
@@ -344,7 +358,7 @@ long getEntryAt(int index) {
344358
* @return integer constant pool entry at index
345359
*/
346360
private int getIntAt(int index) {
347-
assert checkTag(index, constants.jvmInteger);
361+
checkTag(index, constants.jvmInteger);
348362
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
349363
return UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolSize + offset);
350364
}
@@ -356,7 +370,7 @@ private int getIntAt(int index) {
356370
* @return long constant pool entry
357371
*/
358372
private long getLongAt(int index) {
359-
assert checkTag(index, constants.jvmLong);
373+
checkTag(index, constants.jvmLong);
360374
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
361375
return UNSAFE.getLong(getConstantPoolPointer() + config().constantPoolSize + offset);
362376
}
@@ -368,7 +382,7 @@ private long getLongAt(int index) {
368382
* @return float constant pool entry
369383
*/
370384
private float getFloatAt(int index) {
371-
assert checkTag(index, constants.jvmFloat);
385+
checkTag(index, constants.jvmFloat);
372386
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
373387
return UNSAFE.getFloat(getConstantPoolPointer() + config().constantPoolSize + offset);
374388
}
@@ -380,7 +394,7 @@ private float getFloatAt(int index) {
380394
* @return float constant pool entry
381395
*/
382396
private double getDoubleAt(int index) {
383-
assert checkTag(index, constants.jvmDouble);
397+
checkTag(index, constants.jvmDouble);
384398
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
385399
return UNSAFE.getDouble(getConstantPoolPointer() + config().constantPoolSize + offset);
386400
}
@@ -392,7 +406,7 @@ private double getDoubleAt(int index) {
392406
* @return {@code JVM_CONSTANT_NameAndType} constant pool entry
393407
*/
394408
private int getNameAndTypeAt(int index) {
395-
assert checkTag(index, constants.jvmNameAndType);
409+
checkTag(index, constants.jvmNameAndType);
396410
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
397411
return UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolSize + offset);
398412
}
@@ -474,7 +488,7 @@ private int getKlassRefIndexAt(int index) {
474488
* @return klass reference index
475489
*/
476490
private int getUncachedKlassRefIndexAt(int index) {
477-
assert checkTagIsFieldOrMethod(index);
491+
checkTagIsFieldOrMethod(index);
478492
int offset = index * runtime().getHostJVMCIBackend().getTarget().wordSize;
479493
final int refIndex = UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolSize + offset);
480494
// klass ref index is in the low 16-bits.
@@ -485,24 +499,26 @@ private int getUncachedKlassRefIndexAt(int index) {
485499
* Checks that the constant pool index {@code index} is in the bounds of the constant pool.
486500
*
487501
* @param index constant pool index
488-
* @throws AssertionError if the check fails
502+
* @throws IndexOutOfBoundsException if the check fails
489503
*/
490-
private boolean checkBounds(int index) {
491-
assert 0 <= index && index < length() : "index " + index + " not between 0 and " + length();
492-
return true;
504+
private void checkBounds(int index) {
505+
if (index < 1 || index >= length()) {
506+
throw new IndexOutOfBoundsException("index " + index + " not between 1 and " + length());
507+
}
493508
}
494509

495510
/**
496511
* Checks that the constant pool tag at index {@code index} is equal to {@code tag}.
497512
*
498513
* @param index constant pool index
499514
* @param tag expected tag
500-
* @throws AssertionError if the check fails
515+
* @throws IllegalArgumentException if the check fails
501516
*/
502-
private boolean checkTag(int index, JvmConstant tag) {
517+
private void checkTag(int index, JvmConstant tag) {
503518
final JvmConstant tagAt = getTagAt(index);
504-
assert tagAt == tag : "constant pool tag at index " + index + " is " + tagAt + " but expected " + tag;
505-
return true;
519+
if (tagAt != tag) {
520+
throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt + " but expected " + tag);
521+
}
506522
}
507523

508524
/**
@@ -511,12 +527,13 @@ private boolean checkTag(int index, JvmConstant tag) {
511527
* {@link JvmConstants#jvmInterfaceMethodref}.
512528
*
513529
* @param index constant pool index
514-
* @throws AssertionError if the check fails
530+
* @throws IllegalArgumentException if the check fails
515531
*/
516-
private boolean checkTagIsFieldOrMethod(int index) {
532+
private void checkTagIsFieldOrMethod(int index) {
517533
final JvmConstant tagAt = getTagAt(index);
518-
assert tagAt == constants.jvmFieldref || tagAt == constants.jvmMethodref || tagAt == constants.jvmInterfaceMethodref : tagAt;
519-
return true;
534+
if (tagAt != constants.jvmFieldref && tagAt != constants.jvmMethodref && tagAt != constants.jvmInterfaceMethodref) {
535+
throw new IllegalArgumentException("constant pool tag at index " + index + " is " + tagAt);
536+
}
520537
}
521538

522539
@Override
@@ -642,7 +659,6 @@ JavaConstant getStaticFieldConstantValue(int cpi) {
642659

643660
@Override
644661
public Object lookupConstant(int cpi) {
645-
assert cpi != 0;
646662
final JvmConstant tag = getTagAt(cpi);
647663
switch (tag.name) {
648664
case "Integer":
@@ -679,7 +695,7 @@ public Object lookupConstant(int cpi) {
679695

680696
@Override
681697
public String lookupUtf8(int cpi) {
682-
assert checkTag(cpi, constants.jvmUtf8);
698+
checkTag(cpi, constants.jvmUtf8);
683699
return compilerToVM().getSymbol(getEntryAt(cpi));
684700
}
685701

@@ -690,7 +706,10 @@ public Signature lookupSignature(int cpi) {
690706

691707
@Override
692708
public JavaConstant lookupAppendix(int cpi, int opcode) {
693-
assert Bytecodes.isInvoke(opcode);
709+
if (!Bytecodes.isInvoke(opcode)) {
710+
throw new IllegalArgumentException("expected an invoke bytecode at " + cpi + ", got " + opcode);
711+
}
712+
694713
final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode);
695714
return compilerToVM().lookupAppendixInPool(this, index);
696715
}
@@ -822,10 +841,14 @@ public JavaField lookupField(int cpi, ResolvedJavaMethod method, int opcode) {
822841
public int rawIndexToConstantPoolIndex(int rawIndex, int opcode) {
823842
int index;
824843
if (isInvokedynamicIndex(rawIndex)) {
825-
assert opcode == Bytecodes.INVOKEDYNAMIC;
844+
if (opcode != Bytecodes.INVOKEDYNAMIC) {
845+
throw new IllegalArgumentException("expected INVOKEDYNAMIC at " + rawIndex + ", got " + opcode);
846+
}
826847
index = decodeInvokedynamicIndex(rawIndex) + config().constantPoolCpCacheIndexTag;
827848
} else {
828-
assert opcode != Bytecodes.INVOKEDYNAMIC;
849+
if (opcode == Bytecodes.INVOKEDYNAMIC) {
850+
throw new IllegalArgumentException("unexpected INVOKEDYNAMIC at " + rawIndex);
851+
}
829852
index = rawIndexToConstantPoolCacheIndex(rawIndex, opcode);
830853
}
831854
return compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
@@ -898,7 +921,7 @@ public void loadReferencedType(int cpi, int opcode, boolean initialize) {
898921
if (tag == constants.jvmMethodref) {
899922
if (Bytecodes.isInvokeHandleAlias(opcode) && isSignaturePolymorphicHolder(type)) {
900923
final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode);
901-
assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
924+
checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
902925
compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
903926
}
904927
}
@@ -950,7 +973,7 @@ static boolean isSignaturePolymorphicHolder(final ResolvedJavaType type) {
950973
public boolean isResolvedDynamicInvoke(int cpi, int opcode) {
951974
if (Bytecodes.isInvokeHandleAlias(opcode)) {
952975
final int methodRefCacheIndex = rawIndexToConstantPoolCacheIndex(cpi, opcode);
953-
assert checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
976+
checkTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), constants.jvmMethodref);
954977
int op = compilerToVM().isResolvedInvokeHandleInPool(this, methodRefCacheIndex);
955978
return op == opcode;
956979
}

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
*/
2323
package jdk.vm.ci.hotspot;
2424

25+
import static jdk.internal.misc.Unsafe.ADDRESS_SIZE;
2526
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
2627
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
2728
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
28-
import static jdk.internal.misc.Unsafe.ADDRESS_SIZE;
2929

3030
import java.lang.annotation.Annotation;
3131

@@ -45,28 +45,26 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
4545
private JavaType type;
4646

4747
/**
48-
* Value of {@code fieldDescriptor::access_flags()}.
48+
* Offset (in bytes) of field from start of its storage container (i.e. {@code instanceOop} or
49+
* {@code Klass*}).
4950
*/
5051
private final int offset;
5152

5253
/**
5354
* Value of {@code fieldDescriptor::index()}.
5455
*/
55-
private final short index;
56+
private final int index;
5657

5758
/**
5859
* This value contains all flags as stored in the VM including internal ones.
5960
*/
6061
private final int modifiers;
6162

62-
HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, JavaType type, long offset, int modifiers, int index) {
63+
HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, JavaType type, int offset, int modifiers, int index) {
6364
this.holder = holder;
6465
this.type = type;
65-
this.index = (short) index;
66-
assert this.index == index;
67-
assert offset != -1;
68-
assert offset == (int) offset : "offset larger than int";
69-
this.offset = (int) offset;
66+
this.index = index;
67+
this.offset = offset;
7068
this.modifiers = modifiers;
7169
}
7270

@@ -143,6 +141,10 @@ public JavaType getType() {
143141

144142
}
145143

144+
/**
145+
* Gets the offset (in bytes) of field from start of its storage container (i.e.
146+
* {@code instanceOop} or {@code Klass*}).
147+
*/
146148
@Override
147149
public int getOffset() {
148150
return offset;

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ public int getVtableLength() {
576576
return result;
577577
}
578578

579-
HotSpotResolvedJavaField createField(JavaType type, long offset, int rawFlags, int index) {
579+
HotSpotResolvedJavaField createField(JavaType type, int offset, int rawFlags, int index) {
580580
return new HotSpotResolvedJavaFieldImpl(this, type, offset, rawFlags, index);
581581
}
582582

src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ public interface ResolvedJavaField extends JavaField, ModifiersProvider, Annotat
4040
@Override
4141
int getModifiers();
4242

43+
/**
44+
* Returns the offset of the field relative to the base of its storage container (e.g.,
45+
* {@code instanceOop} for an instance field or {@code Klass*} for a static field on HotSpot).
46+
*/
4347
int getOffset();
4448

4549
default boolean isFinal() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package jdk.vm.ci.hotspot;
25+
26+
import jdk.vm.ci.meta.JavaType;
27+
import jdk.vm.ci.meta.ResolvedJavaField;
28+
29+
public class HotSpotResolvedJavaFieldHelper {
30+
public static ResolvedJavaField createField(HotSpotResolvedObjectTypeImpl holder, JavaType type, int offset, int modifiers, int index) {
31+
return new HotSpotResolvedJavaFieldImpl(holder, type, offset, modifiers, index);
32+
}
33+
34+
public static int getIndex(ResolvedJavaField field) {
35+
return ((HotSpotResolvedJavaFieldImpl) field).getIndex();
36+
}
37+
}

0 commit comments

Comments
 (0)