Skip to content

Commit c12b386

Browse files
author
Tom Rodriguez
committed
8338007: [JVMCI] ResolvedJavaMethod.reprofile can crash ciMethodData
Reviewed-by: dnsimon, kvn
1 parent 81752c4 commit c12b386

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,8 @@ C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
13821382
if (method_data == nullptr) {
13831383
method_data = get_profiling_method_data(method, CHECK);
13841384
} else {
1385-
method_data->initialize();
1385+
CompilerThreadCanCallJava canCallJava(THREAD, true);
1386+
method_data->reinitialize();
13861387
}
13871388
C2V_END
13881389

src/hotspot/share/oops/methodData.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,14 @@ bool DataLayout::needs_array_len(u1 tag) {
5959
// Perform generic initialization of the data. More specific
6060
// initialization occurs in overrides of ProfileData::post_initialize.
6161
void DataLayout::initialize(u1 tag, u2 bci, int cell_count) {
62-
_header._bits = (intptr_t)0;
63-
_header._struct._tag = tag;
64-
_header._struct._bci = bci;
62+
DataLayout temp;
63+
temp._header._bits = (intptr_t)0;
64+
temp._header._struct._tag = tag;
65+
temp._header._struct._bci = bci;
66+
// Write the header using a single intptr_t write. This ensures that if the layout is
67+
// reinitialized readers will never see the transient state where the header is 0.
68+
_header = temp._header;
69+
6570
for (int i = 0; i < cell_count; i++) {
6671
set_cell_at(i, (intptr_t)0);
6772
}
@@ -1224,6 +1229,28 @@ MethodData::MethodData(const methodHandle& method)
12241229
initialize();
12251230
}
12261231

1232+
// Reinitialize the storage of an existing MDO at a safepoint. Doing it this way will ensure it's
1233+
// not being accessed while the contents are being rewritten.
1234+
class VM_ReinitializeMDO: public VM_Operation {
1235+
private:
1236+
MethodData* _mdo;
1237+
public:
1238+
VM_ReinitializeMDO(MethodData* mdo): _mdo(mdo) {}
1239+
VMOp_Type type() const { return VMOp_ReinitializeMDO; }
1240+
void doit() {
1241+
// The extra data is being zero'd, we'd like to acquire the extra_data_lock but it can't be held
1242+
// over a safepoint. This means that we don't actually need to acquire the lock.
1243+
_mdo->initialize();
1244+
}
1245+
bool allow_nested_vm_operations() const { return true; }
1246+
};
1247+
1248+
void MethodData::reinitialize() {
1249+
VM_ReinitializeMDO op(this);
1250+
VMThread::execute(&op);
1251+
}
1252+
1253+
12271254
void MethodData::initialize() {
12281255
Thread* thread = Thread::current();
12291256
NoSafepointVerifier no_safepoint; // init function atomic wrt GC

src/hotspot/share/oops/methodData.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,7 @@ class MethodData : public Metadata {
19491949
friend class ProfileData;
19501950
friend class TypeEntriesAtCall;
19511951
friend class ciMethodData;
1952+
friend class VM_ReinitializeMDO;
19521953

19531954
// If you add a new field that points to any metaspace object, you
19541955
// must add this field to MethodData::metaspace_pointers_do().
@@ -1965,11 +1966,18 @@ class MethodData : public Metadata {
19651966
Mutex _extra_data_lock;
19661967

19671968
MethodData(const methodHandle& method);
1969+
1970+
void initialize();
1971+
19681972
public:
19691973
static MethodData* allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS);
19701974

19711975
virtual bool is_methodData() const { return true; }
1972-
void initialize();
1976+
1977+
// Safely reinitialize the data in the MDO. This is intended as a testing facility as the
1978+
// reinitialization is performed at a safepoint so it's isn't cheap and it doesn't ensure that all
1979+
// readers will see consistent profile data.
1980+
void reinitialize();
19731981

19741982
// Whole-method sticky bits and flags
19751983
enum {

src/hotspot/share/runtime/vmOperation.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@
114114
template(GTestStopSafepoint) \
115115
template(JFROldObject) \
116116
template(JvmtiPostObjectFree) \
117-
template(RendezvousGCThreads)
117+
template(RendezvousGCThreads) \
118+
template(ReinitializeMDO)
118119

119120
class Thread;
120121
class outputStream;

0 commit comments

Comments
 (0)