1 /*
  2  * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
 27 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
 28 #include "jfr/recorder/repository/jfrChunkWriter.hpp"
 29 #include "jfr/recorder/stacktrace/jfrStackTrace.hpp"
 30 #include "jfr/recorder/storage/jfrBuffer.hpp"
 31 #include "jfr/support/jfrMethodLookup.hpp"
 32 #include "jfr/support/jfrThreadLocal.hpp"
 33 #include "memory/allocation.inline.hpp"
 34 #include "oops/instanceKlass.inline.hpp"
 35 #include "runtime/continuation.hpp"
 36 #include "runtime/continuationEntry.inline.hpp"
 37 #include "runtime/handles.inline.hpp"
 38 #include "runtime/vframe.inline.hpp"
 39 
 40 static void copy_frames(JfrStackFrame** lhs_frames, u4 length, const JfrStackFrame* rhs_frames) {
 41   assert(lhs_frames != nullptr, "invariant");
 42   assert(rhs_frames != nullptr, "invariant");
 43   if (length > 0) {
 44     *lhs_frames = NEW_C_HEAP_ARRAY(JfrStackFrame, length, mtTracing);
 45     memcpy(*lhs_frames, rhs_frames, length * sizeof(JfrStackFrame));
 46   }
 47 }
 48 
 49 JfrStackFrame::JfrStackFrame(const traceid& id, int bci, int type, const InstanceKlass* ik) :
 50   _klass(ik), _methodid(id), _line(0), _bci(bci), _type(type) {}
 51 
 52 JfrStackFrame::JfrStackFrame(const traceid& id, int bci, int type, int lineno, const InstanceKlass* ik) :
 53   _klass(ik), _methodid(id), _line(lineno), _bci(bci), _type(type) {}
 54 
 55 JfrStackTrace::JfrStackTrace(JfrStackFrame* frames, u4 max_frames) :
 56   _next(nullptr),
 57   _frames(frames),
 58   _id(0),
 59   _hash(0),
 60   _nr_of_frames(0),
 61   _max_frames(max_frames),
 62   _frames_ownership(false),
 63   _reached_root(false),
 64   _lineno(false),
 65   _written(false) {}
 66 
 67 JfrStackTrace::JfrStackTrace(traceid id, const JfrStackTrace& trace, const JfrStackTrace* next) :
 68   _next(next),
 69   _frames(nullptr),
 70   _id(id),
 71   _hash(trace._hash),
 72   _nr_of_frames(trace._nr_of_frames),
 73   _max_frames(trace._max_frames),
 74   _frames_ownership(true),
 75   _reached_root(trace._reached_root),
 76   _lineno(trace._lineno),
 77   _written(false) {
 78   copy_frames(&_frames, trace._nr_of_frames, trace._frames);
 79 }
 80 
 81 JfrStackTrace::~JfrStackTrace() {
 82   if (_frames_ownership) {
 83     FREE_C_HEAP_ARRAY(JfrStackFrame, _frames);
 84   }
 85 }
 86 
 87 template <typename Writer>
 88 static void write_stacktrace(Writer& w, traceid id, bool reached_root, u4 nr_of_frames, const JfrStackFrame* frames) {
 89   w.write((u8)id);
 90   w.write((u1)!reached_root);
 91   w.write(nr_of_frames);
 92   for (u4 i = 0; i < nr_of_frames; ++i) {
 93     frames[i].write(w);
 94   }
 95 }
 96 
 97 void JfrStackTrace::write(JfrChunkWriter& sw) const {
 98   assert(!_written, "invariant");
 99   write_stacktrace(sw, _id, _reached_root, _nr_of_frames, _frames);
100   _written = true;
101 }
102 
103 void JfrStackTrace::write(JfrCheckpointWriter& cpw) const {
104   write_stacktrace(cpw, _id, _reached_root, _nr_of_frames, _frames);
105 }
106 
107 bool JfrStackFrame::equals(const JfrStackFrame& rhs) const {
108   return _methodid == rhs._methodid && _bci == rhs._bci && _type == rhs._type;
109 }
110 
111 bool JfrStackTrace::equals(const JfrStackTrace& rhs) const {
112   if (_reached_root != rhs._reached_root || _nr_of_frames != rhs._nr_of_frames || _hash != rhs._hash) {
113     return false;
114   }
115   for (u4 i = 0; i < _nr_of_frames; ++i) {
116     if (!_frames[i].equals(rhs._frames[i])) {
117       return false;
118     }
119   }
120   return true;
121 }
122 
123 template <typename Writer>
124 static void write_frame(Writer& w, traceid methodid, int line, int bci, u1 type) {
125   w.write((u8)methodid);
126   w.write((u4)line);
127   w.write((u4)bci);
128   w.write((u8)type);
129 }
130 
131 void JfrStackFrame::write(JfrChunkWriter& cw) const {
132   write_frame(cw, _methodid, _line, _bci, _type);
133 }
134 
135 void JfrStackFrame::write(JfrCheckpointWriter& cpw) const {
136   write_frame(cpw, _methodid, _line, _bci, _type);
137 }
138 
139 class JfrVframeStream : public vframeStreamCommon {
140  private:
141   const ContinuationEntry* _cont_entry;
142   bool _async_mode;
143   bool _vthread;
144   bool step_to_sender();
145   void next_frame();
146  public:
147   JfrVframeStream(JavaThread* jt, const frame& fr, bool stop_at_java_call_stub, bool async_mode);
148   void next_vframe();
149 };
150 
151 static RegisterMap::WalkContinuation walk_continuation(JavaThread* jt) {
152   // NOTE: WalkContinuation::skip, because of interactions with ZGC relocation
153   //       and load barriers. This code is run while generating stack traces for
154   //       the ZPage allocation event, even when ZGC is relocating  objects.
155   //       When ZGC is relocating, it is forbidden to run code that performs
156   //       load barriers. With WalkContinuation::include, we visit heap stack
157   //       chunks and could be using load barriers.
158   return (UseZGC && !StackWatermarkSet::processing_started(jt))
159       ? RegisterMap::WalkContinuation::skip
160       : RegisterMap::WalkContinuation::include;
161 }
162 
163 JfrVframeStream::JfrVframeStream(JavaThread* jt, const frame& fr, bool stop_at_java_call_stub, bool async_mode) :
164   vframeStreamCommon(RegisterMap(jt,
165                                  RegisterMap::UpdateMap::skip,
166                                  RegisterMap::ProcessFrames::skip,
167                                  walk_continuation(jt))),
168     _cont_entry(JfrThreadLocal::is_vthread(jt) ? jt->last_continuation() : nullptr),
169     _async_mode(async_mode), _vthread(JfrThreadLocal::is_vthread(jt)) {
170   assert(!_vthread || _cont_entry != nullptr, "invariant");
171   _reg_map.set_async(async_mode);
172   _frame = fr;
173   _stop_at_java_call_stub = stop_at_java_call_stub;
174   while (!fill_from_frame()) {
175     step_to_sender();
176   }
177 }
178 
179 inline bool JfrVframeStream::step_to_sender() {
180   if (_async_mode && !_frame.safe_for_sender(_thread)) {
181     _mode = at_end_mode;
182     return false;
183   }
184   _frame = _frame.sender(&_reg_map);
185   return true;
186 }
187 
188 inline void JfrVframeStream::next_frame() {
189   static constexpr const u4 loop_max = MAX_STACK_DEPTH * 2;
190   u4 loop_count = 0;
191   do {
192     if (_vthread && Continuation::is_continuation_enterSpecial(_frame)) {
193       if (_cont_entry->is_virtual_thread()) {
194         // An entry of a vthread continuation is a termination point.
195         _mode = at_end_mode;
196         break;
197       }
198       _cont_entry = _cont_entry->parent();
199     }
200     if (_async_mode) {
201       ++loop_count;
202       if (loop_count > loop_max) {
203         _mode = at_end_mode;
204         break;
205       }
206     }
207   } while (step_to_sender() && !fill_from_frame());
208 }
209 
210 // Solaris SPARC Compiler1 needs an additional check on the grandparent
211 // of the top_frame when the parent of the top_frame is interpreted and
212 // the grandparent is compiled. However, in this method we do not know
213 // the relationship of the current _frame relative to the top_frame so
214 // we implement a more broad sanity check. When the previous callee is
215 // interpreted and the current sender is compiled, we verify that the
216 // current sender is also walkable. If it is not walkable, then we mark
217 // the current vframeStream as at the end.
218 void JfrVframeStream::next_vframe() {
219   // handle frames with inlining
220   if (_mode == compiled_mode && fill_in_compiled_inlined_sender()) {
221     return;
222   }
223   next_frame();
224 }
225 
226 static const size_t min_valid_free_size_bytes = 16;
227 
228 static inline bool is_full(const JfrBuffer* enqueue_buffer) {
229   return enqueue_buffer->free_size() < min_valid_free_size_bytes;
230 }
231 
232 bool JfrStackTrace::record_async(JavaThread* jt, const frame& frame) {
233   assert(jt != nullptr, "invariant");
234   assert(!_lineno, "invariant");
235   Thread* current_thread = Thread::current();
236   assert(jt != current_thread, "invariant");
237   // Explicitly monitor the available space of the thread-local buffer used for enqueuing klasses as part of tagging methods.
238   // We do this because if space becomes sparse, we cannot rely on the implicit allocation of a new buffer as part of the
239   // regular tag mechanism. If the free list is empty, a malloc could result, and the problem with that is that the thread
240   // we have suspended could be the holder of the malloc lock. If there is no more available space, the attempt is aborted.
241   const JfrBuffer* const enqueue_buffer = JfrTraceIdLoadBarrier::get_sampler_enqueue_buffer(current_thread);
242   HandleMark hm(current_thread); // RegisterMap uses Handles to support continuations.
243   JfrVframeStream vfs(jt, frame, false, true);
244   u4 count = 0;
245   _reached_root = true;
246   _hash = 1;
247   while (!vfs.at_end()) {
248     if (count >= _max_frames) {
249       _reached_root = false;
250       break;
251     }
252     const Method* method = vfs.method();
253     if (!Method::is_valid_method(method) || is_full(enqueue_buffer)) {
254       // we throw away everything we've gathered in this sample since
255       // none of it is safe
256       return false;
257     }
258     const traceid mid = JfrTraceId::load(method);
259     int type = vfs.is_interpreted_frame() ? JfrStackFrame::FRAME_INTERPRETER : JfrStackFrame::FRAME_JIT;
260     int bci = 0;
261     if (method->is_native()) {
262       type = JfrStackFrame::FRAME_NATIVE;
263     } else {
264       bci = vfs.bci();
265     }
266 
267     intptr_t* frame_id = vfs.frame_id();
268     vfs.next_vframe();
269     if (type == JfrStackFrame::FRAME_JIT && !vfs.at_end() && frame_id == vfs.frame_id()) {
270       // This frame and the caller frame are both the same physical
271       // frame, so this frame is inlined into the caller.
272       type = JfrStackFrame::FRAME_INLINE;
273     }
274     _hash = (_hash * 31) + mid;
275     _hash = (_hash * 31) + bci;
276     _hash = (_hash * 31) + type;
277     _frames[count] = JfrStackFrame(mid, bci, type, method->line_number_from_bci(bci), method->method_holder());
278     count++;
279   }
280   _lineno = true;
281   _nr_of_frames = count;
282   return count > 0;
283 }
284 
285 bool JfrStackTrace::record(JavaThread* jt, const frame& frame, int skip) {
286   assert(jt != nullptr, "invariant");
287   assert(jt == Thread::current(), "invariant");
288   assert(!_lineno, "invariant");
289   // Must use ResetNoHandleMark here to bypass if any NoHandleMark exist on stack.
290   // This is because RegisterMap uses Handles to support continuations.
291   ResetNoHandleMark rnhm;
292   HandleMark hm(jt);
293   JfrVframeStream vfs(jt, frame, false, false);
294   u4 count = 0;
295   _reached_root = true;
296   for (int i = 0; i < skip; ++i) {
297     if (vfs.at_end()) {
298       break;
299     }
300     vfs.next_vframe();
301   }
302   _hash = 1;
303   while (!vfs.at_end()) {
304     if (count >= _max_frames) {
305       _reached_root = false;
306       break;
307     }
308     const Method* method = vfs.method();
309     const traceid mid = JfrTraceId::load(method);
310     int type = vfs.is_interpreted_frame() ? JfrStackFrame::FRAME_INTERPRETER : JfrStackFrame::FRAME_JIT;
311     int bci = 0;
312     if (method->is_native()) {
313       type = JfrStackFrame::FRAME_NATIVE;
314     } else {
315       bci = vfs.bci();
316     }
317 
318     intptr_t* frame_id = vfs.frame_id();
319     vfs.next_vframe();
320     if (type == JfrStackFrame::FRAME_JIT && !vfs.at_end() && frame_id == vfs.frame_id()) {
321       // This frame and the caller frame are both the same physical
322       // frame, so this frame is inlined into the caller.
323       type = JfrStackFrame::FRAME_INLINE;
324     }
325     _hash = (_hash * 31) + mid;
326     _hash = (_hash * 31) + bci;
327     _hash = (_hash * 31) + type;
328     _frames[count] = JfrStackFrame(mid, bci, type, method->method_holder());
329     count++;
330   }
331   _nr_of_frames = count;
332   return count > 0;
333 }
334 
335 bool JfrStackTrace::record(JavaThread* current_thread, int skip) {
336   assert(current_thread != nullptr, "invariant");
337   assert(current_thread == Thread::current(), "invariant");
338   if (!current_thread->has_last_Java_frame()) {
339     return false;
340   }
341   return record(current_thread, current_thread->last_frame(), skip);
342 }
343 
344 void JfrStackFrame::resolve_lineno() const {
345   assert(_klass, "no klass pointer");
346   assert(_line == 0, "already have linenumber");
347   const Method* const method = JfrMethodLookup::lookup(_klass, _methodid);
348   assert(method != nullptr, "invariant");
349   assert(method->method_holder() == _klass, "invariant");
350   _line = method->line_number_from_bci(_bci);
351 }
352 
353 void JfrStackTrace::resolve_linenos() const {
354   assert(!_lineno, "invariant");
355   for (unsigned int i = 0; i < _nr_of_frames; i++) {
356     _frames[i].resolve_lineno();
357   }
358   _lineno = true;
359 }