Skip to content

Commit b05290a

Browse files
author
Doug Simon
committed
8252898: remove bulk registration of JFR CompilerPhaseType names
Reviewed-by: kvn, jcm
1 parent 779d2c3 commit b05290a

File tree

6 files changed

+71
-83
lines changed

6 files changed

+71
-83
lines changed

src/hotspot/share/compiler/compileBroker.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -601,19 +601,16 @@ void register_jfr_phasetype_serializer(CompilerType compiler_type) {
601601
ResourceMark rm;
602602
static bool first_registration = true;
603603
if (compiler_type == compiler_jvmci) {
604-
// register serializer, phases will be added later lazily.
605-
GrowableArray<const char*>* jvmci_phase_names = new GrowableArray<const char*>(1);
606-
jvmci_phase_names->append("NOT_A_PHASE_NAME");
607-
CompilerEvent::PhaseEvent::register_phases(jvmci_phase_names);
604+
CompilerEvent::PhaseEvent::get_phase_id("NOT_A_PHASE_NAME", false, false, false);
608605
first_registration = false;
609606
#ifdef COMPILER2
610607
} else if (compiler_type == compiler_c2) {
611608
assert(first_registration, "invariant"); // c2 must be registered first.
612609
GrowableArray<const char*>* c2_phase_names = new GrowableArray<const char*>(PHASE_NUM_TYPES);
613610
for (int i = 0; i < PHASE_NUM_TYPES; i++) {
614-
c2_phase_names->append(CompilerPhaseTypeHelper::to_string((CompilerPhaseType)i));
611+
const char* phase_name = CompilerPhaseTypeHelper::to_string((CompilerPhaseType) i);
612+
CompilerEvent::PhaseEvent::get_phase_id(phase_name, false, false, false);
615613
}
616-
CompilerEvent::PhaseEvent::register_phases(c2_phase_names);
617614
first_registration = false;
618615
#endif // COMPILER2
619616
}

src/hotspot/share/compiler/compilerEvent.cpp

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,67 +34,84 @@
3434
class PhaseTypeGuard : public StackObj {
3535
private:
3636
static Semaphore _mutex_semaphore;
37+
bool _enabled;
3738
public:
38-
PhaseTypeGuard() {
39-
_mutex_semaphore.wait();
39+
PhaseTypeGuard(bool enabled=true) {
40+
if (enabled) {
41+
_mutex_semaphore.wait();
42+
_enabled = true;
43+
} else {
44+
_enabled = false;
45+
}
4046
}
4147
~PhaseTypeGuard() {
42-
_mutex_semaphore.signal();
48+
if (_enabled) {
49+
_mutex_semaphore.signal();
50+
}
4351
}
4452
};
4553

4654
Semaphore PhaseTypeGuard::_mutex_semaphore(1);
4755

48-
static void write_phases(JfrCheckpointWriter& writer, u4 base_idx, GrowableArray<const char*>* phases) {
49-
assert(phases != NULL, "invariant");
50-
assert(phases->is_nonempty(), "invariant");
51-
const u4 nof_entries = phases->length();
52-
writer.write_count(nof_entries);
53-
for (u4 i = 0; i < nof_entries; i++) {
54-
writer.write_key(base_idx + i);
55-
writer.write(phases->at(i));
56-
}
57-
}
58-
56+
// Table for mapping compiler phases names to int identifiers.
5957
static GrowableArray<const char*>* phase_names = NULL;
6058

6159
class CompilerPhaseTypeConstant : public JfrSerializer {
6260
public:
6361
void serialize(JfrCheckpointWriter& writer) {
6462
PhaseTypeGuard guard;
65-
write_phases(writer, 0, phase_names);
63+
assert(phase_names != NULL, "invariant");
64+
assert(phase_names->is_nonempty(), "invariant");
65+
const u4 nof_entries = phase_names->length();
66+
writer.write_count(nof_entries);
67+
for (u4 i = 0; i < nof_entries; i++) {
68+
writer.write_key(i);
69+
writer.write(phase_names->at(i));
70+
}
6671
}
6772
};
6873

69-
// This function provides support for adding dynamic entries to JFR type CompilerPhaseType.
70-
// The mapping for CompilerPhaseType is maintained as growable array phase_names.
71-
// The serializer CompilerPhaseTypeConstant must be registered with JFR at vm init.
72-
// Registration of new phase names creates mapping, serialize it for current chunk and registers its serializer with JFR if it is not already done.
73-
int CompilerEvent::PhaseEvent::register_phases(GrowableArray<const char*>* new_phases) {
74-
int idx = -1;
75-
if (new_phases == NULL || new_phases->is_empty()) {
76-
return idx;
74+
static int lookup_phase(const char* phase_name) {
75+
for (int i = 0; i < phase_names->length(); i++) {
76+
const char* name = phase_names->at(i);
77+
if (strcmp(name, phase_name) == 0) {
78+
return i;
79+
}
7780
}
81+
return -1;
82+
}
83+
84+
int CompilerEvent::PhaseEvent::get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) {
85+
int index;
7886
bool register_jfr_serializer = false;
7987
{
80-
PhaseTypeGuard guard;
88+
PhaseTypeGuard guard(sync);
8189
if (phase_names == NULL) {
82-
phase_names = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<const char*>(100, mtCompiler);
90+
phase_names = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<const char*>(100, mtCompiler);
8391
register_jfr_serializer = true;
92+
} else if (may_exist) {
93+
index = lookup_phase(phase_name);
94+
if (index != -1) {
95+
return index;
96+
}
97+
} else {
98+
assert((index = lookup_phase(phase_name)) == -1, "phase name \"%s\" already registered: %d", phase_name, index);
8499
}
85-
idx = phase_names->length();
86-
phase_names->appendAll(new_phases);
87-
guarantee(phase_names->length() < 256, "exceeds maximum supported phases");
100+
101+
index = phase_names->length();
102+
phase_names->append(use_strdup ? strdup(phase_name) : phase_name);
88103
}
89104
if (register_jfr_serializer) {
90105
JfrSerializer::register_serializer(TYPE_COMPILERPHASETYPE, false, new CompilerPhaseTypeConstant());
91106
} else if (Jfr::is_recording()) {
92-
// serialize new_phases.
107+
// serialize new phase.
93108
JfrCheckpointWriter writer;
94109
writer.write_type(TYPE_COMPILERPHASETYPE);
95-
write_phases(writer, idx, new_phases);
110+
writer.write_count(1);
111+
writer.write_key(index);
112+
writer.write(phase_name);
96113
}
97-
return idx;
114+
return index;
98115
}
99116

100117
void CompilerEvent::CompilationEvent::post(EventCompilation& event, int compile_id, CompilerType compiler_type, Method* method, int compile_level, bool success, bool is_osr, int code_size, int inlined_bytecodes) {

src/hotspot/share/compiler/compilerEvent.hpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,13 @@ class CompilerEvent : AllStatic {
6464
class PhaseEvent : AllStatic {
6565
friend class CompilerPhaseTypeConstant;
6666
public:
67-
/**
68-
* Register compiler phases for JFR type CompilerPhaseType serialization purposes.
69-
* This method is called during compiler creation or during compilation.
70-
* Registration will serialize the passed in phase constants, supporting bulk and/or incremental registrations.
71-
* This method returns start index of new list that just got appended to phase_names.
72-
* Param new_phases may contain duplicates.
73-
* Return value could be used for mapping purpose at caller site, or caller can assume explicit order of registration.
74-
*/
75-
static int register_phases(GrowableArray<const char*>* new_phases) NOT_JFR_RETURN_(-1);
67+
68+
// Gets a unique identifier for `phase_name`, computing and registering it first if necessary.
69+
// If `may_exist` is true, then current registrations are searched first. If false, then
70+
// there must not be an existing registration for `phase_name`.
71+
// If `use_strdup` is true, then `phase_name` is strdup'ed before registration.
72+
// If `sync` is true, then access to the registration table is synchronized.
73+
static int get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) NOT_JFR_RETURN_(-1);
7674

7775
static void post(EventCompilerPhase& event, const Ticks& start_time, int phase, int compile_id, int level) NOT_JFR_RETURN();
7876
static void post(EventCompilerPhase& event, jlong start_time, int phase, int compile_id, int level) {

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,19 +2639,11 @@ C2V_VMENTRY_0(jlong, ticksNow, (JNIEnv* env, jobject))
26392639
return CompilerEvent::ticksNow();
26402640
}
26412641

2642-
C2V_VMENTRY_0(jint, registerCompilerPhases, (JNIEnv* env, jobject, jobjectArray jphases))
2642+
C2V_VMENTRY_0(jint, registerCompilerPhase, (JNIEnv* env, jobject, jstring jphase_name))
26432643
#if INCLUDE_JFR
2644-
if (jphases == NULL) {
2645-
return -1;
2646-
}
2647-
JVMCIObjectArray phases = JVMCIENV->wrap(jphases);
2648-
int len = JVMCIENV->get_length(phases);
2649-
GrowableArray<const char*>* jvmci_phase_names = new GrowableArray<const char*>(len);
2650-
for (int i = 0; i < len; i++) {
2651-
JVMCIObject phase = JVMCIENV->get_object_at(phases, i);
2652-
jvmci_phase_names->append(strdup(JVMCIENV->as_utf8_string(phase)));
2653-
}
2654-
return CompilerEvent::PhaseEvent::register_phases(jvmci_phase_names);
2644+
JVMCIObject phase_name = JVMCIENV->wrap(jphase_name);
2645+
const char *name = JVMCIENV->as_utf8_string(phase_name);
2646+
return CompilerEvent::PhaseEvent::get_phase_id(name, true, true, true);
26552647
#else
26562648
return -1;
26572649
#endif // !INCLUDE_JFR
@@ -2823,7 +2815,7 @@ JNINativeMethod CompilerToVM::methods[] = {
28232815
{CC "addFailedSpeculation", CC "(J[B)Z", FN_PTR(addFailedSpeculation)},
28242816
{CC "callSystemExit", CC "(I)V", FN_PTR(callSystemExit)},
28252817
{CC "ticksNow", CC "()J", FN_PTR(ticksNow)},
2826-
{CC "registerCompilerPhases", CC "([" STRING ")I", FN_PTR(registerCompilerPhases)},
2818+
{CC "registerCompilerPhase", CC "(" STRING ")I", FN_PTR(registerCompilerPhase)},
28272819
{CC "notifyCompilerPhaseEvent", CC "(JIII)V", FN_PTR(notifyCompilerPhaseEvent)},
28282820
{CC "notifyCompilerInliningEvent", CC "(I" HS_RESOLVED_METHOD HS_RESOLVED_METHOD "ZLjava/lang/String;I)V", FN_PTR(notifyCompilerInliningEvent)},
28292821
};

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -999,9 +999,9 @@ HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean com
999999
/**
10001000
* Adds phases in HotSpot JFR.
10011001
*
1002-
* @see JFR.CompilerPhaseEvent#registerPhases and JFR.CompilerPhaseEvent#write
1002+
* @see JFR.CompilerPhaseEvent#write
10031003
*/
1004-
native int registerCompilerPhases(String[] phases);
1004+
native int registerCompilerPhase(String phaseName);
10051005

10061006
/**
10071007
* @see JFR.CompilerPhaseEvent#write

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

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
* questions.
2222
*/
2323

24-
2524
package jdk.vm.ci.hotspot;
2625

2726
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
@@ -33,8 +32,9 @@
3332
import jdk.vm.ci.meta.ResolvedJavaMethod;
3433

3534
/**
36-
* Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify it when events occur.
37-
* The JFR events are defined in {see @code src/share/jfr/metadata/metadata.xml}.
35+
* Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify
36+
* it when events occur. The JFR events are defined in {see @code
37+
* src/share/jfr/metadata/metadata.xml}.
3838
*/
3939
public final class JFR {
4040

@@ -60,22 +60,7 @@ public static final class CompilerPhaseEvent {
6060
private static final ConcurrentHashMap<String, Integer> phaseToId = new ConcurrentHashMap<>();
6161

6262
private static int getPhaseToId(String phaseName) {
63-
String[] phaseNames = { phaseName };
64-
return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhases(phaseNames));
65-
}
66-
67-
/**
68-
* Registers new compiler phases with JFR. This should be called during compiler initialization.
69-
*
70-
* @param phaseNames compiler phase names
71-
*/
72-
public static synchronized void registerPhases(String[] phaseNames) {
73-
ArrayList<String> toProcess = new ArrayList<>(Arrays.asList(phaseNames));
74-
toProcess.removeAll(phaseToId.keySet());
75-
int pid = compilerToVM().registerCompilerPhases(toProcess.toArray(new String[toProcess.size()]));
76-
for (String phase : toProcess) {
77-
phaseToId.put(phase, pid++);
78-
}
63+
return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhase(phaseName));
7964
}
8065

8166
/**
@@ -92,8 +77,8 @@ public static void write(long startTime, String phaseName, int compileId, int ph
9277
}
9378

9479
/**
95-
* Helper methods for managing JFR CompilerInlining events.
96-
* The events are defined in {see @code src/share/jfr/metadata/metadata.xml}.
80+
* Helper methods for managing JFR CompilerInlining events. The events are defined in {see @code
81+
* src/share/jfr/metadata/metadata.xml}.
9782
*/
9883
public static final class CompilerInliningEvent {
9984

@@ -112,4 +97,3 @@ public static void write(int compileId, ResolvedJavaMethod caller, ResolvedJavaM
11297
}
11398
}
11499
}
115-

0 commit comments

Comments
 (0)