Skip to content

Commit 542b300

Browse files
author
Doug Simon
committed
8315954: getArgumentValues002.java fails on Graal
Reviewed-by: never, fparain
1 parent 0637900 commit 542b300

File tree

8 files changed

+278
-22
lines changed

8 files changed

+278
-22
lines changed

src/hotspot/share/interpreter/oopMapCache.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,8 @@ void OopMapCacheEntry::flush() {
407407
void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) {
408408
assert(_resource_allocate_bit_mask,
409409
"Should not resource allocate the _bit_mask");
410+
assert(from->has_valid_mask(),
411+
"Cannot copy entry with an invalid mask");
410412

411413
set_method(from->method());
412414
set_bci(from->bci());
@@ -612,7 +614,9 @@ void OopMapCache::compute_one_oop_map(const methodHandle& method, int bci, Inter
612614
OopMapCacheEntry* tmp = NEW_C_HEAP_OBJ(OopMapCacheEntry, mtClass);
613615
tmp->initialize();
614616
tmp->fill(method, bci);
615-
entry->resource_copy(tmp);
617+
if (tmp->has_valid_mask()) {
618+
entry->resource_copy(tmp);
619+
}
616620
tmp->flush();
617621
FREE_C_HEAP_OBJ(tmp);
618622
}

src/hotspot/share/interpreter/oopMapCache.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class InterpreterOopMap: ResourceObj {
8484
private:
8585
Method* _method; // the method for which the mask is valid
8686
unsigned short _bci; // the bci for which the mask is valid
87-
int _mask_size; // the mask size in bits
87+
int _mask_size; // the mask size in bits (USHRT_MAX if invalid)
8888
int _expression_stack_size; // the size of the expression stack in slots
8989

9090
protected:
@@ -146,6 +146,8 @@ class InterpreterOopMap: ResourceObj {
146146

147147
int expression_stack_size() const { return _expression_stack_size; }
148148

149+
// Determines if a valid mask has been computed
150+
bool has_valid_mask() const { return _mask_size != USHRT_MAX; }
149151
};
150152

151153
class OopMapCache : public CHeapObj<mtClass> {

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "compiler/oopMap.hpp"
3636
#include "interpreter/bytecodeStream.hpp"
3737
#include "interpreter/linkResolver.hpp"
38+
#include "interpreter/oopMapCache.hpp"
3839
#include "jfr/jfrEvents.hpp"
3940
#include "jvmci/jvmciCodeInstaller.hpp"
4041
#include "jvmci/jvmciCompilerToVM.hpp"
@@ -2512,7 +2513,7 @@ C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclas
25122513
jlongArray info = (jlongArray) JNIHandles::make_local(THREAD, info_oop);
25132514
runtime->init_JavaVM_info(info, JVMCI_CHECK_0);
25142515
return info;
2515-
}
2516+
C2V_END
25162517

25172518
C2V_VMENTRY_PREFIX(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject c2vm))
25182519
if (thread == nullptr || thread->libjvmci_runtime() == nullptr) {
@@ -2777,7 +2778,7 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool
27772778
return 0L;
27782779
}
27792780
return (jlong) PEER_JVMCIENV->make_global(result).as_jobject();
2780-
}
2781+
C2V_END
27812782

27822783
C2V_VMENTRY_NULL(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
27832784
requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
@@ -2790,13 +2791,13 @@ C2V_VMENTRY_NULL(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
27902791

27912792
JVMCIENV->destroy_global(global_handle_obj);
27922793
return result;
2793-
}
2794+
C2V_END
27942795

27952796
C2V_VMENTRY(void, updateHotSpotNmethod, (JNIEnv* env, jobject, jobject code_handle))
27962797
JVMCIObject code = JVMCIENV->wrap(code_handle);
27972798
// Execute this operation for the side effect of updating the InstalledCode state
27982799
JVMCIENV->get_nmethod(code);
2799-
}
2800+
C2V_END
28002801

28012802
C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
28022803
JVMCIObject code = JVMCIENV->wrap(code_handle);
@@ -2812,7 +2813,7 @@ C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle
28122813
JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
28132814
JVMCIENV->copy_bytes_from(code_bytes, result, 0, code_size);
28142815
return JVMCIENV->get_jbyteArray(result);
2815-
}
2816+
C2V_END
28162817

28172818
C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
28182819
requireInHotSpot("asReflectionExecutable", JVMCI_CHECK_NULL);
@@ -2828,7 +2829,7 @@ C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, ARGUMEN
28282829
executable = Reflection::new_method(m, false, CHECK_NULL);
28292830
}
28302831
return JNIHandles::make_local(THREAD, executable);
2831-
}
2832+
C2V_END
28322833

28332834
static InstanceKlass* check_field(Klass* klass, jint index, JVMCI_TRAPS) {
28342835
if (!klass->is_instance_klass()) {
@@ -2850,7 +2851,7 @@ C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, ARGUMENT_PAI
28502851
fieldDescriptor fd(iklass, index);
28512852
oop reflected = Reflection::new_field(&fd, CHECK_NULL);
28522853
return JNIHandles::make_local(THREAD, reflected);
2853-
}
2854+
C2V_END
28542855

28552856
static jbyteArray get_encoded_annotation_data(InstanceKlass* holder, AnnotationArray* annotations_array, bool for_class,
28562857
jint filter_length, jlong filter_klass_pointers,
@@ -2964,7 +2965,7 @@ C2V_VMENTRY_NULL(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlo
29642965
JVMCIENV->put_object_at(result, result_index++, entry);
29652966
}
29662967
return JVMCIENV->get_jobjectArray(result);
2967-
}
2968+
C2V_END
29682969

29692970
C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
29702971
methodHandle method(THREAD, UNPACK_PAIR(Method, method));
@@ -2975,19 +2976,19 @@ C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, ARGUME
29752976
method->set_method_data(method_data);
29762977
}
29772978
return (jlong) method_data->get_failed_speculations_address();
2978-
}
2979+
C2V_END
29792980

29802981
C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))
29812982
FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
2982-
}
2983+
C2V_END
29832984

29842985
C2V_VMENTRY_0(jboolean, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
29852986
JVMCIPrimitiveArray speculation_handle = JVMCIENV->wrap(speculation_obj);
29862987
int speculation_len = JVMCIENV->get_length(speculation_handle);
29872988
char* speculation = NEW_RESOURCE_ARRAY(char, speculation_len);
29882989
JVMCIENV->copy_bytes_to(speculation_handle, (jbyte*) speculation, 0, speculation_len);
29892990
return FailedSpeculation::add_failed_speculation(nullptr, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);
2990-
}
2991+
C2V_END
29912992

29922993
C2V_VMENTRY(void, callSystemExit, (JNIEnv* env, jobject, jint status))
29932994
JavaValue result(T_VOID);
@@ -2999,11 +3000,11 @@ C2V_VMENTRY(void, callSystemExit, (JNIEnv* env, jobject, jint status))
29993000
vmSymbols::int_void_signature(),
30003001
&jargs,
30013002
CHECK);
3002-
}
3003+
C2V_END
30033004

30043005
C2V_VMENTRY_0(jlong, ticksNow, (JNIEnv* env, jobject))
30053006
return CompilerEvent::ticksNow();
3006-
}
3007+
C2V_END
30073008

30083009
C2V_VMENTRY_0(jint, registerCompilerPhase, (JNIEnv* env, jobject, jstring jphase_name))
30093010
#if INCLUDE_JFR
@@ -3013,14 +3014,14 @@ C2V_VMENTRY_0(jint, registerCompilerPhase, (JNIEnv* env, jobject, jstring jphase
30133014
#else
30143015
return -1;
30153016
#endif // !INCLUDE_JFR
3016-
}
3017+
C2V_END
30173018

30183019
C2V_VMENTRY(void, notifyCompilerPhaseEvent, (JNIEnv* env, jobject, jlong startTime, jint phase, jint compileId, jint level))
30193020
EventCompilerPhase event;
30203021
if (event.should_commit()) {
30213022
CompilerEvent::PhaseEvent::post(event, startTime, phase, compileId, level);
30223023
}
3023-
}
3024+
C2V_END
30243025

30253026
C2V_VMENTRY(void, notifyCompilerInliningEvent, (JNIEnv* env, jobject, jint compileId, ARGUMENT_PAIR(caller), ARGUMENT_PAIR(callee), jboolean succeeded, jstring jmessage, jint bci))
30263027
EventCompilerInlining event;
@@ -3030,7 +3031,7 @@ C2V_VMENTRY(void, notifyCompilerInliningEvent, (JNIEnv* env, jobject, jint compi
30303031
JVMCIObject message = JVMCIENV->wrap(jmessage);
30313032
CompilerEvent::InlineEvent::post(event, compileId, caller, callee, succeeded, JVMCIENV->as_utf8_string(message), bci);
30323033
}
3033-
}
3034+
C2V_END
30343035

30353036
C2V_VMENTRY(void, setThreadLocalObject, (JNIEnv* env, jobject, jint id, jobject value))
30363037
requireInHotSpot("setThreadLocalObject", JVMCI_CHECK);
@@ -3040,7 +3041,7 @@ C2V_VMENTRY(void, setThreadLocalObject, (JNIEnv* env, jobject, jint id, jobject
30403041
}
30413042
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
30423043
err_msg("%d is not a valid thread local id", id));
3043-
}
3044+
C2V_END
30443045

30453046
C2V_VMENTRY_NULL(jobject, getThreadLocalObject, (JNIEnv* env, jobject, jint id))
30463047
requireInHotSpot("getThreadLocalObject", JVMCI_CHECK_NULL);
@@ -3049,7 +3050,7 @@ C2V_VMENTRY_NULL(jobject, getThreadLocalObject, (JNIEnv* env, jobject, jint id))
30493050
}
30503051
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
30513052
err_msg("%d is not a valid thread local id", id));
3052-
}
3053+
C2V_END
30533054

30543055
C2V_VMENTRY(void, setThreadLocalLong, (JNIEnv* env, jobject, jint id, jlong value))
30553056
requireInHotSpot("setThreadLocalLong", JVMCI_CHECK);
@@ -3061,7 +3062,7 @@ C2V_VMENTRY(void, setThreadLocalLong, (JNIEnv* env, jobject, jint id, jlong valu
30613062
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
30623063
err_msg("%d is not a valid thread local id", id));
30633064
}
3064-
}
3065+
C2V_END
30653066

30663067
C2V_VMENTRY_0(jlong, getThreadLocalLong, (JNIEnv* env, jobject, jint id))
30673068
requireInHotSpot("getThreadLocalLong", JVMCI_CHECK_0);
@@ -3073,7 +3074,49 @@ C2V_VMENTRY_0(jlong, getThreadLocalLong, (JNIEnv* env, jobject, jint id))
30733074
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
30743075
err_msg("%d is not a valid thread local id", id));
30753076
}
3076-
}
3077+
C2V_END
3078+
3079+
C2V_VMENTRY(void, getOopMapAt, (JNIEnv* env, jobject, ARGUMENT_PAIR(method),
3080+
jint bci, jlongArray oop_map_handle))
3081+
methodHandle method(THREAD, UNPACK_PAIR(Method, method));
3082+
if (bci < 0 || bci >= method->code_size()) {
3083+
JVMCI_THROW_MSG(IllegalArgumentException,
3084+
err_msg("bci %d is out of bounds [0 .. %d)", bci, method->code_size()));
3085+
}
3086+
InterpreterOopMap mask;
3087+
OopMapCache::compute_one_oop_map(method, bci, &mask);
3088+
if (!mask.has_valid_mask()) {
3089+
JVMCI_THROW_MSG(IllegalArgumentException, err_msg("bci %d is not valid", bci));
3090+
}
3091+
if (mask.number_of_entries() == 0) {
3092+
return;
3093+
}
3094+
3095+
int nslots = method->max_locals() + method->max_stack();
3096+
int nwords = ((nslots - 1) / 64) + 1;
3097+
JVMCIPrimitiveArray oop_map = JVMCIENV->wrap(oop_map_handle);
3098+
int oop_map_len = JVMCIENV->get_length(oop_map);
3099+
if (nwords > oop_map_len) {
3100+
JVMCI_THROW_MSG(IllegalArgumentException,
3101+
err_msg("oop map too short: %d > %d", nwords, oop_map_len));
3102+
}
3103+
3104+
jlong* oop_map_buf = NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, jlong, nwords);
3105+
if (oop_map_buf == nullptr) {
3106+
JVMCI_THROW_MSG(InternalError, err_msg("could not allocate %d longs", nwords));
3107+
}
3108+
for (int i = 0; i < nwords; i++) {
3109+
oop_map_buf[i] = 0L;
3110+
}
3111+
3112+
BitMapView oop_map_view = BitMapView((BitMap::bm_word_t*) oop_map_buf, nwords * BitsPerLong);
3113+
for (int i = 0; i < nslots; i++) {
3114+
if (mask.is_oop(i)) {
3115+
oop_map_view.set_bit(i);
3116+
}
3117+
}
3118+
JVMCIENV->copy_longs_from((jlong*)oop_map_buf, oop_map, 0, nwords);
3119+
C2V_END
30773120

30783121
#define CC (char*) /*cast a literal from (const char*)*/
30793122
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
@@ -3232,6 +3275,7 @@ JNINativeMethod CompilerToVM::methods[] = {
32323275
{CC "registerCompilerPhase", CC "(" STRING ")I", FN_PTR(registerCompilerPhase)},
32333276
{CC "notifyCompilerPhaseEvent", CC "(JIII)V", FN_PTR(notifyCompilerPhaseEvent)},
32343277
{CC "notifyCompilerInliningEvent", CC "(I" HS_METHOD2 HS_METHOD2 "ZLjava/lang/String;I)V", FN_PTR(notifyCompilerInliningEvent)},
3278+
{CC "getOopMapAt", CC "(" HS_METHOD2 "I[J)V", FN_PTR(getOopMapAt)},
32353279
};
32363280

32373281
int CompilerToVM::methods_count() {

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,4 +1473,13 @@ public void close() {
14731473
}
14741474
}
14751475
}
1476+
1477+
/**
1478+
* @see HotSpotResolvedJavaMethod#getOopMapAt
1479+
*/
1480+
void getOopMapAt(HotSpotResolvedJavaMethodImpl method, int bci, long[] oopMap) {
1481+
getOopMapAt(method, method.getMethodPointer(), bci, oopMap);
1482+
}
1483+
1484+
native void getOopMapAt(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci, long[] oopMap);
14761485
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package jdk.vm.ci.hotspot;
2424

2525
import java.lang.reflect.Modifier;
26+
import java.util.BitSet;
2627

2728
import jdk.vm.ci.meta.JavaMethod;
2829
import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -127,4 +128,18 @@ default boolean isDefault() {
127128
boolean hasCodeAtLevel(int entryBCI, int level);
128129

129130
int methodIdnum();
131+
132+
133+
/**
134+
* Computes which local variables and operand stack slots in {@code method} contain
135+
* live object values at the instruction denoted by {@code bci}. This is the "oop map"
136+
* used by the garbage collector for interpreter frames.
137+
*
138+
* @param bci the index of an instruction in this method's bytecodes
139+
* @return the computed oop map. The first {@link #getMaxLocals} bits are for
140+
* the local variables, the remaining bits are for the stack slots.
141+
* @throws IllegalArgumentException if this method has no bytecode or
142+
* {@code bci} is not the index of a bytecode instruction
143+
*/
144+
BitSet getOopMapAt(int bci);
130145
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.lang.reflect.Executable;
3636
import java.lang.reflect.Modifier;
3737
import java.lang.reflect.Type;
38+
import java.util.BitSet;
3839
import java.util.Collections;
3940
import java.util.List;
4041
import java.util.Objects;
@@ -767,4 +768,15 @@ private List<AnnotationData> getAnnotationData0(ResolvedJavaType... filter) {
767768
byte[] encoded = compilerToVM().getEncodedExecutableAnnotationData(this, filter);
768769
return VMSupport.decodeAnnotations(encoded, AnnotationDataDecoder.INSTANCE);
769770
}
771+
772+
@Override
773+
public BitSet getOopMapAt(int bci) {
774+
if (getCodeSize() == 0) {
775+
throw new IllegalArgumentException("has no bytecode");
776+
}
777+
int nwords = ((getMaxLocals() + getMaxStackSize() - 1) / 64) + 1;
778+
long[] oopMap = new long[nwords];
779+
compilerToVM().getOopMapAt(this, bci, oopMap);
780+
return BitSet.valueOf(oopMap);
781+
}
770782
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.lang.reflect.Method;
2929
import java.lang.reflect.Modifier;
3030
import java.lang.reflect.Type;
31+
import java.util.BitSet;
3132

3233
/**
3334
* Represents a resolved Java method. Methods, like fields and types, are resolved through

0 commit comments

Comments
 (0)