1 /* 2 * Copyright (c) 2011, 2018, 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 #ifndef SHARE_VM_JFR_RECORDER_STACKTRACE_JFRSTACKTRACEREPOSITORY_HPP 26 #define SHARE_VM_JFR_RECORDER_STACKTRACE_JFRSTACKTRACEREPOSITORY_HPP 27 28 #include "jfr/utilities/jfrAllocation.hpp" 29 #include "jfr/utilities/jfrTypes.hpp" 30 31 class frame; 32 class JavaThread; 33 class JfrCheckpointSystem; 34 class JfrCheckpointWriter; 35 class JfrChunkWriter; 36 class Method; 37 38 class JfrStackFrame { 39 private: 40 const Method* _method; 41 traceid _methodid; 42 int _line; 43 int _bci; 44 u1 _type; 45 46 public: 47 enum { 48 FRAME_INTERPRETER = 0, 49 FRAME_JIT, 50 FRAME_INLINE, 51 FRAME_NATIVE, 52 NUM_FRAME_TYPES 53 }; 54 55 JfrStackFrame(const traceid& id, int bci, int type, const Method* method) : 56 _method(method), _methodid(id), _line(0), _bci(bci), _type(type) {} 57 JfrStackFrame(const traceid& id, int bci, int type, int lineno) : 58 _method(NULL), _methodid(id), _line(0), _bci(bci), _type(type) {} 59 bool equals(const JfrStackFrame& rhs) const; 60 void write(JfrChunkWriter& cw) const; 61 void write(JfrCheckpointWriter& cpw) const; 62 void resolve_lineno(); 63 }; 64 65 class JfrStackTrace : public StackObj { 66 friend class JfrStackTraceRepository; 67 private: 68 JfrStackFrame* _frames; 69 traceid _id; 70 u4 _nr_of_frames; 71 unsigned int _hash; 72 const u4 _max_frames; 73 bool _reached_root; 74 bool _lineno; 75 76 public: 77 JfrStackTrace(JfrStackFrame* frames, u4 max_frames) : _frames(frames), 78 _id(0), 79 _nr_of_frames(0), 80 _hash(0), 81 _reached_root(false), 82 _max_frames(max_frames), 83 _lineno(false) {} 84 bool record_thread(JavaThread& thread, frame& frame); 85 bool record_safe(JavaThread* thread, int skip, bool leakp = false); 86 void resolve_linenos(); 87 void set_nr_of_frames(u4 nr_of_frames) { _nr_of_frames = nr_of_frames; } 88 void set_hash(unsigned int hash) { _hash = hash; } 89 void set_frame(u4 frame_pos, JfrStackFrame& frame); 90 void set_reached_root(bool reached_root) { _reached_root = reached_root; } 91 bool full_stacktrace() const { return _reached_root; } 92 bool have_lineno() const { return _lineno; } 93 }; 94 95 class JfrStackTraceRepository : public JfrCHeapObj { 96 friend class JfrRecorder; 97 friend class JfrRecorderService; 98 friend class ObjectSampler; 99 friend class WriteObjectSampleStacktrace; 100 101 class StackTrace : public JfrCHeapObj { 102 friend class JfrStackTrace; 103 friend class JfrStackTraceRepository; 104 private: 105 StackTrace* _next; 106 JfrStackFrame* _frames; 107 const traceid _id; 108 u4 _nr_of_frames; 109 unsigned int _hash; 110 bool _reached_root; 111 mutable bool _written; 112 113 unsigned int hash() const { return _hash; } 114 bool should_write() const { return !_written; } 115 116 public: 117 StackTrace(traceid id, const JfrStackTrace& trace, StackTrace* next); 118 ~StackTrace(); 119 traceid id() const { return _id; } 120 StackTrace* next() const { return _next; } 121 void write(JfrChunkWriter& cw) const; 122 void write(JfrCheckpointWriter& cpw) const; 123 bool equals(const JfrStackTrace& rhs) const; 124 }; 125 126 private: 127 static const u4 TABLE_SIZE = 2053; 128 StackTrace* _table[TABLE_SIZE]; 129 traceid _next_id; 130 u4 _entries; 131 132 size_t write_impl(JfrChunkWriter& cw, bool clear); 133 traceid record_for(JavaThread* thread, int skip, JfrStackFrame* frames, u4 max_frames); 134 traceid record_for(JavaThread* thread, int skip, JfrStackFrame* frames, u4 max_frames, unsigned int* hash); 135 traceid add_trace(const JfrStackTrace& stacktrace); 136 const StackTrace* resolve_entry(unsigned int hash, traceid id) const; 137 138 static void write_metadata(JfrCheckpointWriter& cpw); 139 140 JfrStackTraceRepository(); 141 static JfrStackTraceRepository& instance(); 142 public: 143 static JfrStackTraceRepository* create(); 144 bool initialize(); 145 static void destroy(); 146 static traceid add(const JfrStackTrace& stacktrace); 147 static traceid record(Thread* thread, int skip = 0); 148 static traceid record(Thread* thread, int skip, unsigned int* hash); 149 traceid write(JfrCheckpointWriter& cpw, traceid id, unsigned int hash); 150 size_t write(JfrChunkWriter& cw, bool clear); 151 size_t clear(); 152 }; 153 154 #endif // SHARE_VM_JFR_RECORDER_STACKTRACE_JFRSTACKTRACEREPOSITORY_HPP