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