/*
 * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_MANAGEMENT
#include "classfile/classLoaderDataGraph.hpp"
#include "jfr/jfrEvents.hpp"
#include "jfr/periodic/jfrFinalizerStatisticsEvent.hpp"
#include "jfr/support/jfrSymbolTable.hpp"
#include "jfr/utilities/jfrTime.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/mutexLocker.hpp"
#include "services/finalizerService.hpp"

static void send_event(const FinalizerEntry* fe, const InstanceKlass* ik, const JfrTicks& timestamp, Thread* thread) {
  assert(ik != nullptr, "invariant");
  assert(ik->has_finalizer(), "invariant");
  assert(thread != nullptr, "invariant");
  const char* const url = fe != nullptr ? fe->codesource() : nullptr;
  const traceid url_symbol_id = url != nullptr ? JfrSymbolTable::add(url) : 0;
  EventFinalizerStatistics event(UNTIMED);
  event.set_starttime(timestamp);
  event.set_endtime(timestamp);
  event.set_finalizableClass(ik);
  event.set_codeSource(url_symbol_id);
  if (fe == nullptr) {
    event.set_objects(0);
    event.set_totalFinalizersRun(0);
  } else {
    assert(fe->klass() == ik, "invariant");
    event.set_objects(fe->objects_on_heap());
    event.set_totalFinalizersRun(fe->total_finalizers_run());
  }
  event.commit();
}

void JfrFinalizerStatisticsEvent::send_unload_event(const InstanceKlass* ik) {
  if (!EventFinalizerStatistics::is_enabled()) {
    return;
  }
  Thread* const thread = Thread::current();
  ResourceMark rm(thread);
  send_event(FinalizerService::lookup(ik, thread), ik, JfrTicks::now(), thread);
}

// Finalizer events generated by the periodic task will all have the same timestamp.

class FinalizerStatisticsEventClosure : public FinalizerEntryClosure {
 private:
  Thread* _thread;
  const JfrTicks _timestamp;
 public:
  FinalizerStatisticsEventClosure(Thread* thread) : _thread(thread), _timestamp(JfrTicks::now()) {}
  virtual bool do_entry(const FinalizerEntry* fe) {
    assert(fe != nullptr, "invariant");
    send_event(fe, fe->klass(), _timestamp, _thread);
    return true;
  }
};

void JfrFinalizerStatisticsEvent::generate_events() {
  Thread* const thread = Thread::current();
  ResourceMark rm(thread);
  FinalizerStatisticsEventClosure fsec(thread);
  MutexLocker lock(ClassLoaderDataGraph_lock); // To prevent entries from being removed by class unloading.
  FinalizerService::do_entries(&fsec, thread);
}

#endif // INCLUDE_MANAGEMENT
