40 bool _enabled;
41 public:
42 PhaseTypeGuard(bool enabled=true) {
43 if (enabled) {
44 _mutex_semaphore.wait();
45 _enabled = true;
46 } else {
47 _enabled = false;
48 }
49 }
50 ~PhaseTypeGuard() {
51 if (_enabled) {
52 _mutex_semaphore.signal();
53 }
54 }
55 };
56
57 Semaphore PhaseTypeGuard::_mutex_semaphore(1);
58
59 // Table for mapping compiler phases names to int identifiers.
60 static GrowableArray<const char*>* phase_names = nullptr;
61
62 class CompilerPhaseTypeConstant : public JfrSerializer {
63 public:
64 void serialize(JfrCheckpointWriter& writer) {
65 PhaseTypeGuard guard;
66 assert(phase_names != nullptr, "invariant");
67 assert(phase_names->is_nonempty(), "invariant");
68 const u4 nof_entries = phase_names->length();
69 writer.write_count(nof_entries);
70 for (u4 i = 0; i < nof_entries; i++) {
71 writer.write_key(i);
72 writer.write(phase_names->at(i));
73 }
74 }
75 };
76
77 static int lookup_phase(const char* phase_name) {
78 for (int i = 0; i < phase_names->length(); i++) {
79 const char* name = phase_names->at(i);
80 if (strcmp(name, phase_name) == 0) {
81 return i;
82 }
83 }
84 return -1;
85 }
86
87 int CompilerEvent::PhaseEvent::get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) {
88 int index;
89 bool register_jfr_serializer = false;
90 {
91 PhaseTypeGuard guard(sync);
92 if (phase_names == nullptr) {
93 phase_names = new (mtInternal) GrowableArray<const char*>(100, mtCompiler);
94 register_jfr_serializer = true;
95 } else if (may_exist) {
96 index = lookup_phase(phase_name);
97 if (index != -1) {
98 return index;
99 }
100 } else {
101 assert((index = lookup_phase(phase_name)) == -1, "phase name \"%s\" already registered: %d", phase_name, index);
102 }
103
104 index = phase_names->length();
105 phase_names->append(use_strdup ? os::strdup(phase_name) : phase_name);
106 }
107 if (register_jfr_serializer) {
108 JfrSerializer::register_serializer(TYPE_COMPILERPHASETYPE, false, new CompilerPhaseTypeConstant());
109 } else if (Jfr::is_recording()) {
110 // serialize new phase.
111 JfrCheckpointWriter writer;
112 writer.write_type(TYPE_COMPILERPHASETYPE);
113 writer.write_count(1);
114 writer.write_key(index);
115 writer.write(phase_name);
116 }
117 return index;
118 }
119
120 // As part of event commit, a Method* is tagged as a function of an epoch.
121 // Epochs evolve during safepoints. To ensure the event is tagged in the correct epoch,
122 // that is, to avoid a race, the thread will participate in the safepoint protocol
123 // by doing the commit while the thread is _thread_in_vm.
124 template <typename EventType>
125 static inline void commit(EventType& event) {
126 JavaThread* thread = JavaThread::current();
127 JavaThreadState state = thread->thread_state();
128 if (state == _thread_in_native) {
129 ThreadInVMfromNative transition(thread);
130 event.commit();
131 } else {
132 assert(state == _thread_in_vm, "coming from wrong thread state %d", state);
133 event.commit();
134 }
135 }
|
40 bool _enabled;
41 public:
42 PhaseTypeGuard(bool enabled=true) {
43 if (enabled) {
44 _mutex_semaphore.wait();
45 _enabled = true;
46 } else {
47 _enabled = false;
48 }
49 }
50 ~PhaseTypeGuard() {
51 if (_enabled) {
52 _mutex_semaphore.signal();
53 }
54 }
55 };
56
57 Semaphore PhaseTypeGuard::_mutex_semaphore(1);
58
59 // Table for mapping compiler phases names to int identifiers.
60 static GrowableArray<const char*>* cphase_names = nullptr;
61
62 class CompilerPhaseTypeConstant : public JfrSerializer {
63 public:
64 void serialize(JfrCheckpointWriter& writer) {
65 PhaseTypeGuard guard;
66 assert(cphase_names != nullptr, "invariant");
67 assert(cphase_names->is_nonempty(), "invariant");
68 const u4 nof_entries = cphase_names->length();
69 writer.write_count(nof_entries);
70 for (u4 i = 0; i < nof_entries; i++) {
71 writer.write_key(i);
72 writer.write(cphase_names->at(i));
73 }
74 }
75 };
76
77 static int lookup_phase(const char* cphase_name) {
78 for (int i = 0; i < cphase_names->length(); i++) {
79 const char* name = cphase_names->at(i);
80 if (strcmp(name, cphase_name) == 0) {
81 return i;
82 }
83 }
84 return -1;
85 }
86
87 int CompilerEvent::PhaseEvent::get_phase_id(const char* cphase_name, bool may_exist, bool use_strdup, bool sync) {
88 int index;
89 bool register_jfr_serializer = false;
90 {
91 PhaseTypeGuard guard(sync);
92 if (cphase_names == nullptr) {
93 cphase_names = new (mtInternal) GrowableArray<const char*>(100, mtCompiler);
94 register_jfr_serializer = true;
95 } else if (may_exist) {
96 index = lookup_phase(cphase_name);
97 if (index != -1) {
98 return index;
99 }
100 } else {
101 assert((index = lookup_phase(cphase_name)) == -1, "phase name \"%s\" already registered: %d", cphase_name, index);
102 }
103
104 index = cphase_names->length();
105 cphase_names->append(use_strdup ? os::strdup(cphase_name) : cphase_name);
106 }
107 if (register_jfr_serializer) {
108 JfrSerializer::register_serializer(TYPE_COMPILERPHASETYPE, false, new CompilerPhaseTypeConstant());
109 } else if (Jfr::is_recording()) {
110 // serialize new phase.
111 JfrCheckpointWriter writer;
112 writer.write_type(TYPE_COMPILERPHASETYPE);
113 writer.write_count(1);
114 writer.write_key(index);
115 writer.write(cphase_name);
116 }
117 return index;
118 }
119
120 // As part of event commit, a Method* is tagged as a function of an epoch.
121 // Epochs evolve during safepoints. To ensure the event is tagged in the correct epoch,
122 // that is, to avoid a race, the thread will participate in the safepoint protocol
123 // by doing the commit while the thread is _thread_in_vm.
124 template <typename EventType>
125 static inline void commit(EventType& event) {
126 JavaThread* thread = JavaThread::current();
127 JavaThreadState state = thread->thread_state();
128 if (state == _thread_in_native) {
129 ThreadInVMfromNative transition(thread);
130 event.commit();
131 } else {
132 assert(state == _thread_in_vm, "coming from wrong thread state %d", state);
133 event.commit();
134 }
135 }
|