82 } |
83 } |
83 |
84 |
84 void JfrThreadLocal::on_start(Thread* t) { |
85 void JfrThreadLocal::on_start(Thread* t) { |
85 assert(t != NULL, "invariant"); |
86 assert(t != NULL, "invariant"); |
86 assert(Thread::current() == t, "invariant"); |
87 assert(Thread::current() == t, "invariant"); |
|
88 JfrJavaSupport::on_thread_start(t); |
87 if (JfrRecorder::is_recording()) { |
89 if (JfrRecorder::is_recording()) { |
88 if (t->is_Java_thread()) { |
90 if (!t->jfr_thread_local()->is_excluded()) { |
89 send_java_thread_start_event((JavaThread*)t); |
91 JfrCheckpointManager::write_thread_checkpoint(t); |
|
92 if (t->is_Java_thread()) { |
|
93 send_java_thread_start_event((JavaThread*)t); |
|
94 } |
90 } |
95 } |
91 } |
96 } |
92 } |
97 } |
93 |
98 |
94 static void send_java_thread_end_events(traceid id, JavaThread* jt) { |
99 static void send_java_thread_end_events(traceid id, JavaThread* jt) { |
101 event.commit(); |
106 event.commit(); |
102 JfrThreadCPULoadEvent::send_event_for_thread(jt); |
107 JfrThreadCPULoadEvent::send_event_for_thread(jt); |
103 } |
108 } |
104 } |
109 } |
105 |
110 |
|
111 void JfrThreadLocal::release(Thread* t) { |
|
112 if (has_java_event_writer()) { |
|
113 assert(t->is_Java_thread(), "invariant"); |
|
114 JfrJavaSupport::destroy_global_jni_handle(java_event_writer()); |
|
115 _java_event_writer = NULL; |
|
116 } |
|
117 if (has_native_buffer()) { |
|
118 JfrStorage::release_thread_local(native_buffer(), t); |
|
119 _native_buffer = NULL; |
|
120 } |
|
121 if (has_java_buffer()) { |
|
122 JfrStorage::release_thread_local(java_buffer(), t); |
|
123 _java_buffer = NULL; |
|
124 } |
|
125 if (_stackframes != NULL) { |
|
126 FREE_C_HEAP_ARRAY(JfrStackFrame, _stackframes); |
|
127 _stackframes = NULL; |
|
128 } |
|
129 } |
|
130 |
106 void JfrThreadLocal::release(JfrThreadLocal* tl, Thread* t) { |
131 void JfrThreadLocal::release(JfrThreadLocal* tl, Thread* t) { |
107 assert(tl != NULL, "invariant"); |
132 assert(tl != NULL, "invariant"); |
108 assert(t != NULL, "invariant"); |
133 assert(t != NULL, "invariant"); |
109 assert(Thread::current() == t, "invariant"); |
134 assert(Thread::current() == t, "invariant"); |
110 assert(!tl->is_dead(), "invariant"); |
135 assert(!tl->is_dead(), "invariant"); |
111 assert(tl->shelved_buffer() == NULL, "invariant"); |
136 assert(tl->shelved_buffer() == NULL, "invariant"); |
112 if (tl->has_native_buffer()) { |
|
113 JfrStorage::release_thread_local(tl->native_buffer(), t); |
|
114 } |
|
115 if (tl->has_java_buffer()) { |
|
116 JfrStorage::release_thread_local(tl->java_buffer(), t); |
|
117 } |
|
118 if (tl->has_java_event_writer()) { |
|
119 assert(t->is_Java_thread(), "invariant"); |
|
120 JfrJavaSupport::destroy_global_jni_handle(tl->java_event_writer()); |
|
121 } |
|
122 FREE_C_HEAP_ARRAY(JfrStackFrame, tl->_stackframes); |
|
123 tl->_dead = true; |
137 tl->_dead = true; |
|
138 tl->release(t); |
124 } |
139 } |
125 |
140 |
126 void JfrThreadLocal::on_exit(Thread* t) { |
141 void JfrThreadLocal::on_exit(Thread* t) { |
127 assert(t != NULL, "invariant"); |
142 assert(t != NULL, "invariant"); |
128 JfrThreadLocal * const tl = t->jfr_thread_local(); |
143 JfrThreadLocal * const tl = t->jfr_thread_local(); |
129 assert(!tl->is_dead(), "invariant"); |
144 assert(!tl->is_dead(), "invariant"); |
130 if (t->is_Java_thread()) { |
145 if (JfrRecorder::is_recording()) { |
131 JavaThread* const jt = (JavaThread*)t; |
146 if (t->is_Java_thread()) { |
132 ObjectSampleCheckpoint::on_thread_exit(jt); |
147 JavaThread* const jt = (JavaThread*)t; |
133 send_java_thread_end_events(tl->thread_id(), jt); |
148 ObjectSampleCheckpoint::on_thread_exit(jt); |
|
149 send_java_thread_end_events(tl->thread_id(), jt); |
|
150 } |
134 } |
151 } |
135 release(tl, Thread::current()); // because it could be that Thread::current() != t |
152 release(tl, Thread::current()); // because it could be that Thread::current() != t |
|
153 } |
|
154 |
|
155 static JfrBuffer* acquire_buffer(bool excluded) { |
|
156 JfrBuffer* const buffer = JfrStorage::acquire_thread_local(Thread::current()); |
|
157 if (buffer != NULL && excluded) { |
|
158 buffer->set_excluded(); |
|
159 } |
|
160 return buffer; |
136 } |
161 } |
137 |
162 |
138 JfrBuffer* JfrThreadLocal::install_native_buffer() const { |
163 JfrBuffer* JfrThreadLocal::install_native_buffer() const { |
139 assert(!has_native_buffer(), "invariant"); |
164 assert(!has_native_buffer(), "invariant"); |
140 _native_buffer = JfrStorage::acquire_thread_local(Thread::current()); |
165 _native_buffer = acquire_buffer(_excluded); |
141 return _native_buffer; |
166 return _native_buffer; |
142 } |
167 } |
143 |
168 |
144 JfrBuffer* JfrThreadLocal::install_java_buffer() const { |
169 JfrBuffer* JfrThreadLocal::install_java_buffer() const { |
145 assert(!has_java_buffer(), "invariant"); |
170 assert(!has_java_buffer(), "invariant"); |
146 assert(!has_java_event_writer(), "invariant"); |
171 assert(!has_java_event_writer(), "invariant"); |
147 _java_buffer = JfrStorage::acquire_thread_local(Thread::current()); |
172 _java_buffer = acquire_buffer(_excluded); |
148 return _java_buffer; |
173 return _java_buffer; |
149 } |
174 } |
150 |
175 |
151 JfrStackFrame* JfrThreadLocal::install_stackframes() const { |
176 JfrStackFrame* JfrThreadLocal::install_stackframes() const { |
152 assert(_stackframes == NULL, "invariant"); |
177 assert(_stackframes == NULL, "invariant"); |