1 /*
  2  * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2021, Datadog, Inc. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #include "precompiled.hpp"
 27 #include "jfr/jfrEvents.hpp"
 28 #include "jfr/leakprofiler/chains/edgeStore.hpp"
 29 #include "jfr/leakprofiler/chains/pathToGcRootsOperation.hpp"
 30 #include "jfr/leakprofiler/checkpoint/eventEmitter.hpp"
 31 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
 32 #include "jfr/leakprofiler/sampling/objectSample.hpp"
 33 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
 34 #include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
 35 #include "logging/log.hpp"
 36 #include "memory/resourceArea.hpp"
 37 #include "oops/markWord.hpp"
 38 #include "oops/oop.inline.hpp"
 39 #include "runtime/mutexLocker.hpp"
 40 #include "runtime/thread.inline.hpp"
 41 #include "runtime/vmThread.hpp"
 42 
 43 EventEmitter::EventEmitter(const JfrTicks& start_time, const JfrTicks& end_time) :
 44   _start_time(start_time),
 45   _end_time(end_time),
 46   _thread(Thread::current()),
 47   _jfr_thread_local(_thread->jfr_thread_local()),
 48   _thread_id(_thread->jfr_thread_local()->thread_id()) {}
 49 
 50 EventEmitter::~EventEmitter() {
 51   // restore / reset thread local stack trace and thread id
 52   _jfr_thread_local->set_thread_id(_thread_id);
 53   _jfr_thread_local->clear_cached_stack_trace();
 54 }
 55 
 56 void EventEmitter::emit(ObjectSampler* sampler, int64_t cutoff_ticks, bool emit_all, bool skip_bfs) {
 57   assert(sampler != NULL, "invariant");
 58   ResourceMark rm;
 59   EdgeStore edge_store;
 60   if (cutoff_ticks <= 0) {
 61     // no reference chains
 62     JfrTicks time_stamp = JfrTicks::now();
 63     EventEmitter emitter(time_stamp, time_stamp);
 64     emitter.write_events(sampler, &edge_store, emit_all);
 65     return;
 66   }
 67   // events emitted with reference chains require a safepoint operation
 68   PathToGcRootsOperation op(sampler, &edge_store, cutoff_ticks, emit_all, skip_bfs);
 69   VMThread::execute(&op);
 70 }
 71 
 72 size_t EventEmitter::write_events(ObjectSampler* object_sampler, EdgeStore* edge_store, bool emit_all) {
 73   assert(_thread == Thread::current(), "invariant");
 74   assert(_thread->jfr_thread_local() == _jfr_thread_local, "invariant");
 75   assert(object_sampler != NULL, "invariant");
 76   assert(edge_store != NULL, "invariant");
 77 
 78   const jlong last_sweep = emit_all ? max_jlong : ObjectSampler::last_sweep();
 79   size_t count = 0;
 80 
 81   // First pass associates a live sample with its immediate edge
 82   // in preparation for writing checkpoint information.
 83   const ObjectSample* current = object_sampler->first();
 84   while (current != NULL) {
 85     ObjectSample* prev = current->prev();
 86     if (current->is_alive_and_older_than(last_sweep)) {
 87       link_sample_with_edge(current, edge_store);
 88       ++count;
 89     }
 90     current = prev;
 91   }
 92   if (count > 0) {
 93     // We need to serialize the associated checkpoints and potential chains
 94     // before writing the events to ensure constants are available for resolution
 95     // at the time old object sample events appear in the stream.
 96     ObjectSampleCheckpoint::write(object_sampler, edge_store, emit_all, _thread);
 97 
 98     // Now we are ready to write the events
 99     const ObjectSample* current = object_sampler->first();
100     while (current != NULL) {
101       ObjectSample* prev = current->prev();
102       if (current->is_alive_and_older_than(last_sweep)) {
103         write_event(current, edge_store);
104       }
105       current = prev;
106     }
107   }
108   return count;
109 }
110 
111 static int array_size(const oop object) {
112   assert(object != NULL, "invariant");
113   if (object->is_array()) {
114     return arrayOop(object)->length();
115   }
116   return min_jint;
117 }
118 
119 void EventEmitter::link_sample_with_edge(const ObjectSample* sample, EdgeStore* edge_store) {
120   assert(sample != NULL, "invariant");
121   assert(!sample->is_dead(), "invariant");
122   assert(edge_store != NULL, "invariant");
123   if (SafepointSynchronize::is_at_safepoint()) {
124     if (!sample->object()->mark().is_marked()) {
125       // Associated with an edge (chain) already during heap traversal.
126       return;
127     }
128   }
129   // In order to dump out a representation of the event
130   // even though the sample object was found not reachable / too long to reach,
131   // we need to register a top level edge.
132   edge_store->put(UnifiedOopRef::encode_in_native(sample->object_addr()));
133 }
134 
135 void EventEmitter::write_event(const ObjectSample* sample, EdgeStore* edge_store) {
136   assert(sample != NULL, "invariant");
137   assert(!sample->is_dead(), "invariant");
138   assert(edge_store != NULL, "invariant");
139   assert(_jfr_thread_local != NULL, "invariant");
140 
141   traceid gc_root_id = 0;
142   const Edge* edge = NULL;
143   if (SafepointSynchronize::is_at_safepoint()) {
144     if (!sample->object()->mark().is_marked()) {
145       edge = (const Edge*)(sample->object())->mark().to_pointer();
146     }
147   }
148   if (edge == NULL) {
149     edge = edge_store->get(UnifiedOopRef::encode_in_native(sample->object_addr()));
150   } else {
151     gc_root_id = edge_store->gc_root_id(edge);
152   }
153   assert(edge != NULL, "invariant");
154   const traceid object_id = edge_store->get_id(edge);
155   assert(object_id != 0, "invariant");
156 
157   Tickspan object_age = Ticks(_start_time.value()) - sample->allocation_time();
158 
159   EventOldObjectSample e(UNTIMED);
160   e.set_starttime(_start_time);
161   e.set_endtime(_end_time);
162   e.set_allocationTime(sample->allocation_time());
163   e.set_objectSize(sample->allocated());
164   e.set_objectAge(object_age);
165   e.set_lastKnownHeapUsage(sample->heap_used_at_last_gc());
166   e.set_object(object_id);
167   e.set_arrayElements(array_size(edge->pointee()));
168   e.set_root(gc_root_id);
169 
170   // Temporarily assigning both the stack trace id and thread id
171   // onto the thread local data structure of the emitter thread (for the duration
172   // of the commit() call). This trick provides a means to override
173   // the event generation mechanism by injecting externally provided id's.
174   // At this particular location, it allows us to emit an old object event
175   // supplying information from where the actual sampling occurred.
176   _jfr_thread_local->set_cached_stack_trace_id(sample->stack_trace_id());
177   assert(sample->has_thread(), "invariant");
178   _jfr_thread_local->set_thread_id(sample->thread_id());
179   e.commit();
180 }