115 } |
115 } |
116 assert(tl->has_thread_checkpoint(), "invariant"); |
116 assert(tl->has_thread_checkpoint(), "invariant"); |
117 return tl->thread_id(); |
117 return tl->thread_id(); |
118 } |
118 } |
119 |
119 |
120 // Populates the thread local stack frames, but does not add them |
120 static void record_stacktrace(JavaThread* thread) { |
121 // to the stacktrace repository (...yet, see stacktrace_id() below) |
|
122 // |
|
123 void ObjectSampler::fill_stacktrace(JfrStackTrace* stacktrace, JavaThread* thread) { |
|
124 assert(stacktrace != NULL, "invariant"); |
|
125 assert(thread != NULL, "invariant"); |
121 assert(thread != NULL, "invariant"); |
126 if (JfrEventSetting::has_stacktrace(EventOldObjectSample::eventId)) { |
122 if (JfrEventSetting::has_stacktrace(EventOldObjectSample::eventId)) { |
127 JfrStackTraceRepository::fill_stacktrace_for(thread, stacktrace, 0); |
123 JfrStackTraceRepository::record_and_cache(thread); |
128 } |
124 } |
129 } |
|
130 |
|
131 // We were successful in acquiring the try lock and have been selected for adding a sample. |
|
132 // Go ahead with installing our previously taken stacktrace into the stacktrace repository. |
|
133 // |
|
134 traceid ObjectSampler::stacktrace_id(const JfrStackTrace* stacktrace, JavaThread* thread) { |
|
135 assert(stacktrace != NULL, "invariant"); |
|
136 assert(stacktrace->hash() != 0, "invariant"); |
|
137 const traceid stacktrace_id = JfrStackTraceRepository::add(stacktrace, thread); |
|
138 thread->jfr_thread_local()->set_cached_stack_trace_id(stacktrace_id, stacktrace->hash()); |
|
139 return stacktrace_id; |
|
140 } |
125 } |
141 |
126 |
142 void ObjectSampler::sample(HeapWord* obj, size_t allocated, JavaThread* thread) { |
127 void ObjectSampler::sample(HeapWord* obj, size_t allocated, JavaThread* thread) { |
143 assert(thread != NULL, "invariant"); |
128 assert(thread != NULL, "invariant"); |
144 assert(is_created(), "invariant"); |
129 assert(is_created(), "invariant"); |
145 |
|
146 const traceid thread_id = get_thread_id(thread); |
130 const traceid thread_id = get_thread_id(thread); |
147 if (thread_id == 0) { |
131 if (thread_id == 0) { |
148 return; |
132 return; |
149 } |
133 } |
150 |
134 record_stacktrace(thread); |
151 const JfrThreadLocal* const tl = thread->jfr_thread_local(); |
|
152 JfrStackTrace stacktrace(tl->stackframes(), tl->stackdepth()); |
|
153 fill_stacktrace(&stacktrace, thread); |
|
154 |
|
155 // try enter critical section |
135 // try enter critical section |
156 JfrTryLock tryLock(&_lock); |
136 JfrTryLock tryLock(&_lock); |
157 if (!tryLock.has_lock()) { |
137 if (!tryLock.has_lock()) { |
158 log_trace(jfr, oldobject, sampling)("Skipping old object sample due to lock contention"); |
138 log_trace(jfr, oldobject, sampling)("Skipping old object sample due to lock contention"); |
159 return; |
139 return; |
160 } |
140 } |
161 |
141 instance().add(obj, allocated, thread_id, thread); |
162 instance().add(obj, allocated, thread_id, &stacktrace, thread); |
142 } |
163 } |
143 |
164 |
144 void ObjectSampler::add(HeapWord* obj, size_t allocated, traceid thread_id, JavaThread* thread) { |
165 void ObjectSampler::add(HeapWord* obj, size_t allocated, traceid thread_id, JfrStackTrace* stacktrace, JavaThread* thread) { |
145 assert(obj != NULL, "invariant"); |
166 assert(stacktrace != NULL, "invariant"); |
|
167 assert(thread_id != 0, "invariant"); |
146 assert(thread_id != 0, "invariant"); |
168 assert(thread != NULL, "invariant"); |
147 assert(thread != NULL, "invariant"); |
169 assert(thread->jfr_thread_local()->has_thread_checkpoint(), "invariant"); |
148 assert(thread->jfr_thread_local()->has_thread_checkpoint(), "invariant"); |
170 |
149 |
171 if (_dead_samples) { |
150 if (_dead_samples) { |
188 sample = _list->get(); |
167 sample = _list->get(); |
189 } |
168 } |
190 |
169 |
191 assert(sample != NULL, "invariant"); |
170 assert(sample != NULL, "invariant"); |
192 sample->set_thread_id(thread_id); |
171 sample->set_thread_id(thread_id); |
193 sample->set_thread_checkpoint(thread->jfr_thread_local()->thread_checkpoint()); |
172 |
194 |
173 const JfrThreadLocal* const tl = thread->jfr_thread_local(); |
195 const unsigned int stacktrace_hash = stacktrace->hash(); |
174 sample->set_thread_checkpoint(tl->thread_checkpoint()); |
|
175 |
|
176 const unsigned int stacktrace_hash = tl->cached_stack_trace_hash(); |
196 if (stacktrace_hash != 0) { |
177 if (stacktrace_hash != 0) { |
197 sample->set_stack_trace_id(stacktrace_id(stacktrace, thread)); |
178 sample->set_stack_trace_id(tl->cached_stack_trace_id()); |
198 sample->set_stack_trace_hash(stacktrace_hash); |
179 sample->set_stack_trace_hash(stacktrace_hash); |
199 } |
180 } |
200 |
181 |
201 sample->set_span(allocated); |
182 sample->set_span(allocated); |
202 sample->set_object((oop)obj); |
183 sample->set_object((oop)obj); |