src/hotspot/share/jfr/jni/jfrJniMethod.cpp
changeset 50113 caf115bb98ad
child 50163 268ea94772da
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2014, 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 #include "precompiled.hpp"
       
    26 #include "jni.h"
       
    27 #include "jvm.h"
       
    28 #include "jfr/jfr.hpp"
       
    29 #include "jfr/jfrEvents.hpp"
       
    30 #include "jfr/periodic/sampling/jfrThreadSampler.hpp"
       
    31 #include "jfr/recorder/jfrEventSetting.hpp"
       
    32 #include "jfr/recorder/jfrRecorder.hpp"
       
    33 #include "jfr/recorder/checkpoint/jfrMetadataEvent.hpp"
       
    34 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
       
    35 #include "jfr/recorder/repository/jfrRepository.hpp"
       
    36 #include "jfr/recorder/repository/jfrChunkSizeNotifier.hpp"
       
    37 #include "jfr/recorder/repository/jfrChunkWriter.hpp"
       
    38 #include "jfr/recorder/service/jfrOptionSet.hpp"
       
    39 #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
       
    40 #include "jfr/recorder/stringpool/jfrStringPool.hpp"
       
    41 #include "jfr/jni/jfrGetAllEventClasses.hpp"
       
    42 #include "jfr/jni/jfrJavaSupport.hpp"
       
    43 #include "jfr/jni/jfrJniMethodRegistration.hpp"
       
    44 #include "jfr/instrumentation/jfrEventClassTransformer.hpp"
       
    45 #include "jfr/instrumentation/jfrJvmtiAgent.hpp"
       
    46 #include "jfr/leakprofiler/leakProfiler.hpp"
       
    47 #include "jfr/utilities/jfrJavaLog.hpp"
       
    48 #include "jfr/utilities/jfrTimeConverter.hpp"
       
    49 #include "jfr/utilities/jfrTime.hpp"
       
    50 #include "jfr/writers/jfrJavaEventWriter.hpp"
       
    51 #include "jfrfiles/jfrPeriodic.hpp"
       
    52 #include "logging/log.hpp"
       
    53 #include "memory/resourceArea.hpp"
       
    54 #include "runtime/interfaceSupport.inline.hpp"
       
    55 #include "runtime/mutexLocker.hpp"
       
    56 #include "runtime/os.hpp"
       
    57 #include "runtime/thread.hpp"
       
    58 #include "utilities/debug.hpp"
       
    59 
       
    60 #define NO_TRANSITION(result_type, header) extern "C" { result_type JNICALL header {
       
    61 #define NO_TRANSITION_END } }
       
    62 
       
    63 /*
       
    64  * NO_TRANSITION entries
       
    65  *
       
    66  * Thread remains _thread_in_native
       
    67  */
       
    68 
       
    69 NO_TRANSITION(void, jfr_register_natives(JNIEnv* env, jclass jvmclass))
       
    70   JfrJniMethodRegistration register_native_methods(env);
       
    71 NO_TRANSITION_END
       
    72 
       
    73 NO_TRANSITION(jboolean, jfr_is_enabled())
       
    74   return Jfr::is_enabled() ? JNI_TRUE : JNI_FALSE;
       
    75 NO_TRANSITION_END
       
    76 
       
    77 NO_TRANSITION(jboolean, jfr_is_disabled())
       
    78   return Jfr::is_disabled() ? JNI_TRUE : JNI_FALSE;
       
    79 NO_TRANSITION_END
       
    80 
       
    81 NO_TRANSITION(jboolean, jfr_is_started())
       
    82   return JfrRecorder::is_created() ? JNI_TRUE : JNI_FALSE;
       
    83 NO_TRANSITION_END
       
    84 
       
    85 NO_TRANSITION(jstring, jfr_get_pid(JNIEnv* env, jobject jvm))
       
    86   char pid_buf[32] = { 0 };
       
    87   jio_snprintf(pid_buf, sizeof(pid_buf), "%d", os::current_process_id());
       
    88   jstring pid_string = env->NewStringUTF(pid_buf);
       
    89   return pid_string; // exception pending if NULL
       
    90 NO_TRANSITION_END
       
    91 
       
    92 NO_TRANSITION(jlong, jfr_elapsed_frequency(JNIEnv* env, jobject jvm))
       
    93   return JfrTime::frequency();
       
    94 NO_TRANSITION_END
       
    95 
       
    96 NO_TRANSITION(jlong, jfr_elapsed_counter(JNIEnv* env, jobject jvm))
       
    97   return JfrTicks::now();
       
    98 NO_TRANSITION_END
       
    99 
       
   100 NO_TRANSITION(void, jfr_retransform_classes(JNIEnv* env, jobject jvm, jobjectArray classes))
       
   101   JfrJvmtiAgent::retransform_classes(env, classes, JavaThread::thread_from_jni_environment(env));
       
   102 NO_TRANSITION_END
       
   103 
       
   104 NO_TRANSITION(void, jfr_set_enabled(JNIEnv* env, jobject jvm, jlong event_type_id, jboolean enabled))
       
   105   JfrEventSetting::set_enabled(event_type_id, JNI_TRUE == enabled);
       
   106   if (EventOldObjectSample::eventId == event_type_id) {
       
   107     ThreadInVMfromNative transition(JavaThread::thread_from_jni_environment(env));
       
   108     if (JNI_TRUE == enabled) {
       
   109       LeakProfiler::start(JfrOptionSet::old_object_queue_size());
       
   110     } else {
       
   111       LeakProfiler::stop();
       
   112     }
       
   113   }
       
   114 NO_TRANSITION_END
       
   115 
       
   116 NO_TRANSITION(void, jfr_set_file_notification(JNIEnv* env, jobject jvm, jlong threshold))
       
   117   JfrChunkSizeNotifier::set_chunk_size_threshold((size_t)threshold);
       
   118 NO_TRANSITION_END
       
   119 
       
   120 NO_TRANSITION(void, jfr_set_sample_threads(JNIEnv* env, jobject jvm, jboolean sampleThreads))
       
   121   JfrOptionSet::set_sample_threads(sampleThreads);
       
   122 NO_TRANSITION_END
       
   123 
       
   124 NO_TRANSITION(void, jfr_set_stack_depth(JNIEnv* env, jobject jvm, jint depth))
       
   125   JfrOptionSet::set_stackdepth((jlong)depth);
       
   126 NO_TRANSITION_END
       
   127 
       
   128 NO_TRANSITION(void, jfr_set_stacktrace_enabled(JNIEnv* env, jobject jvm, jlong event_type_id, jboolean enabled))
       
   129   JfrEventSetting::set_stacktrace(event_type_id, JNI_TRUE == enabled);
       
   130 NO_TRANSITION_END
       
   131 
       
   132 NO_TRANSITION(void, jfr_set_global_buffer_count(JNIEnv* env, jobject jvm, jlong count))
       
   133   JfrOptionSet::set_num_global_buffers(count);
       
   134 NO_TRANSITION_END
       
   135 
       
   136 NO_TRANSITION(void, jfr_set_global_buffer_size(JNIEnv* env, jobject jvm, jlong size))
       
   137 JfrOptionSet::set_global_buffer_size(size);
       
   138 NO_TRANSITION_END
       
   139 
       
   140 NO_TRANSITION(void, jfr_set_thread_buffer_size(JNIEnv* env, jobject jvm, jlong size))
       
   141   JfrOptionSet::set_thread_buffer_size(size);
       
   142 NO_TRANSITION_END
       
   143 
       
   144 NO_TRANSITION(void, jfr_set_memory_size(JNIEnv* env, jobject jvm, jlong size))
       
   145   JfrOptionSet::set_memory_size(size);
       
   146 NO_TRANSITION_END
       
   147 
       
   148 NO_TRANSITION(jboolean, jfr_set_threshold(JNIEnv* env, jobject jvm, jlong event_type_id, jlong thresholdTicks))
       
   149   return JfrEventSetting::set_threshold(event_type_id, thresholdTicks) ? JNI_TRUE : JNI_FALSE;
       
   150 NO_TRANSITION_END
       
   151 
       
   152 NO_TRANSITION(jboolean, jfr_allow_event_retransforms(JNIEnv* env, jobject jvm))
       
   153   return JfrOptionSet::allow_event_retransforms() ? JNI_TRUE : JNI_FALSE;
       
   154 NO_TRANSITION_END
       
   155 
       
   156 NO_TRANSITION(jboolean, jfr_is_available(JNIEnv* env, jclass jvm))
       
   157   return !Jfr::is_disabled() ? JNI_TRUE : JNI_FALSE;
       
   158 NO_TRANSITION_END
       
   159 
       
   160 NO_TRANSITION(jlong, jfr_get_epoch_address(JNIEnv* env, jobject jvm))
       
   161   return JfrTraceIdEpoch::epoch_address();
       
   162 NO_TRANSITION_END
       
   163 
       
   164 NO_TRANSITION(jlong, jfr_get_unloaded_event_classes_count(JNIEnv* env, jobject jvm))
       
   165   return JfrEventClasses::unloaded_event_classes_count();
       
   166 NO_TRANSITION_END
       
   167 
       
   168 NO_TRANSITION(jdouble, jfr_time_conv_factor(JNIEnv* env, jobject jvm))
       
   169   return (jdouble)JfrTimeConverter::nano_to_counter_multiplier();
       
   170 NO_TRANSITION_END
       
   171 
       
   172 NO_TRANSITION(jboolean, jfr_set_cutoff(JNIEnv* env, jobject jvm, jlong event_type_id, jlong cutoff_ticks))
       
   173   return JfrEventSetting::set_cutoff(event_type_id, cutoff_ticks) ? JNI_TRUE : JNI_FALSE;
       
   174 NO_TRANSITION_END
       
   175 
       
   176 
       
   177 /*
       
   178  * JVM_ENTRY_NO_ENV entries
       
   179  *
       
   180  * Transitions:
       
   181  *   Entry: _thread_in_native -> _thread_in_vm
       
   182  *   Exit:  _thread_in_vm -> _thread_in_native
       
   183  *
       
   184  * Current JavaThread available as "thread" variable
       
   185  */
       
   186 
       
   187 JVM_ENTRY_NO_ENV(jboolean, jfr_create_jfr(JNIEnv* env, jobject jvm, jboolean simulate_failure))
       
   188   if (JfrRecorder::is_created()) {
       
   189     return JNI_TRUE;
       
   190   }
       
   191   if (!JfrRecorder::create(simulate_failure == JNI_TRUE)) {
       
   192     JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread);
       
   193     return JNI_FALSE;
       
   194   }
       
   195   return JNI_TRUE;
       
   196 JVM_END
       
   197 
       
   198 JVM_ENTRY_NO_ENV(jboolean, jfr_destroy_jfr(JNIEnv* env, jobject jvm))
       
   199   JfrRecorder::destroy();
       
   200   return JNI_TRUE;
       
   201 JVM_END
       
   202 
       
   203 JVM_ENTRY_NO_ENV(void, jfr_begin_recording(JNIEnv* env, jobject jvm))
       
   204   if (JfrRecorder::is_recording()) {
       
   205     return;
       
   206   }
       
   207   JfrRecorder::start_recording();
       
   208 JVM_END
       
   209 
       
   210 JVM_ENTRY_NO_ENV(void, jfr_end_recording(JNIEnv* env, jobject jvm))
       
   211   if (!JfrRecorder::is_recording()) {
       
   212     return;
       
   213   }
       
   214   JfrRecorder::stop_recording();
       
   215 JVM_END
       
   216 
       
   217 
       
   218 JVM_ENTRY_NO_ENV(jboolean, jfr_emit_event(JNIEnv* env, jobject jvm, jlong eventTypeId, jlong timeStamp, jlong when))
       
   219   JfrPeriodicEventSet::requestEvent((JfrEventId)eventTypeId);
       
   220   return thread->has_pending_exception() ? JNI_FALSE : JNI_TRUE;
       
   221 JVM_END
       
   222 
       
   223 JVM_ENTRY_NO_ENV(jobject, jfr_get_all_event_classes(JNIEnv* env, jobject jvm))
       
   224   return JfrEventClasses::get_all_event_classes(thread);
       
   225 JVM_END
       
   226 
       
   227 JVM_ENTRY_NO_ENV(jlong, jfr_class_id(JNIEnv* env, jclass jvm, jclass jc))
       
   228   return JfrTraceId::use(jc);
       
   229 JVM_END
       
   230 
       
   231 JVM_ENTRY_NO_ENV(jlong, jfr_stacktrace_id(JNIEnv* env, jobject jvm, jint skip))
       
   232   return JfrStackTraceRepository::record(thread, skip);
       
   233 JVM_END
       
   234 
       
   235 JVM_ENTRY_NO_ENV(void, jfr_log(JNIEnv* env, jobject jvm, jint tag_set, jint level, jstring message))
       
   236   JfrJavaLog::log(tag_set, level, message, thread);
       
   237 JVM_END
       
   238 
       
   239 JVM_ENTRY_NO_ENV(void, jfr_subscribe_log_level(JNIEnv* env, jobject jvm, jobject log_tag, jint id))
       
   240   JfrJavaLog::subscribe_log_level(log_tag, id, thread);
       
   241 JVM_END
       
   242 
       
   243 JVM_ENTRY_NO_ENV(void, jfr_set_output(JNIEnv* env, jobject jvm, jstring path))
       
   244   JfrRepository::set_chunk_path(path, thread);
       
   245 JVM_END
       
   246 
       
   247 JVM_ENTRY_NO_ENV(void, jfr_set_method_sampling_interval(JNIEnv* env, jobject jvm, jlong type, jlong intervalMillis))
       
   248   if (intervalMillis < 0) {
       
   249     intervalMillis = 0;
       
   250   }
       
   251   JfrEventId typed_event_id = (JfrEventId)type;
       
   252   assert(EventExecutionSample::eventId == typed_event_id || EventNativeMethodSample::eventId == typed_event_id, "invariant");
       
   253   if (intervalMillis > 0) {
       
   254     JfrEventSetting::set_enabled(typed_event_id, true); // ensure sampling event is enabled
       
   255   }
       
   256   if (EventExecutionSample::eventId == type) {
       
   257     JfrThreadSampling::set_java_sample_interval(intervalMillis);
       
   258   } else {
       
   259     JfrThreadSampling::set_native_sample_interval(intervalMillis);
       
   260   }
       
   261 JVM_END
       
   262 
       
   263 JVM_ENTRY_NO_ENV(void, jfr_store_metadata_descriptor(JNIEnv* env, jobject jvm, jbyteArray descriptor))
       
   264   JfrMetadataEvent::update(descriptor);
       
   265 JVM_END
       
   266 
       
   267 // trace thread id for a thread object
       
   268 JVM_ENTRY_NO_ENV(jlong, jfr_id_for_thread(JNIEnv* env, jobject jvm, jobject t))
       
   269   return JfrJavaSupport::jfr_thread_id(t);
       
   270 JVM_END
       
   271 
       
   272 JVM_ENTRY_NO_ENV(jobject, jfr_get_event_writer(JNIEnv* env, jclass cls))
       
   273   return JfrJavaEventWriter::event_writer(thread);
       
   274 JVM_END
       
   275 
       
   276 JVM_ENTRY_NO_ENV(jobject, jfr_new_event_writer(JNIEnv* env, jclass cls))
       
   277   return JfrJavaEventWriter::new_event_writer(thread);
       
   278 JVM_END
       
   279 
       
   280 JVM_ENTRY_NO_ENV(jboolean, jfr_event_writer_flush(JNIEnv* env, jclass cls, jobject writer, jint used_size, jint requested_size))
       
   281   return JfrJavaEventWriter::flush(writer, used_size, requested_size, thread);
       
   282 JVM_END
       
   283 
       
   284 JVM_ENTRY_NO_ENV(void, jfr_set_repository_location(JNIEnv* env, jobject repo, jstring location))
       
   285   return JfrRepository::set_path(location, thread);
       
   286 JVM_END
       
   287 
       
   288 JVM_ENTRY_NO_ENV(void, jfr_uncaught_exception(JNIEnv* env, jobject jvm, jobject t, jthrowable throwable))
       
   289   JfrJavaSupport::uncaught_exception(throwable, thread);
       
   290 JVM_END
       
   291 
       
   292 JVM_ENTRY_NO_ENV(void, jfr_abort(JNIEnv* env, jobject jvm, jstring errorMsg))
       
   293   JfrJavaSupport::abort(errorMsg, thread);
       
   294 JVM_END
       
   295 
       
   296 JVM_ENTRY_NO_ENV(jlong, jfr_type_id(JNIEnv* env, jobject jvm, jclass jc))
       
   297   return JfrTraceId::get(jc);
       
   298 JVM_END
       
   299 
       
   300 JVM_ENTRY_NO_ENV(jboolean, jfr_add_string_constant(JNIEnv* env, jclass jvm, jboolean epoch, jlong id, jstring string))
       
   301   return JfrStringPool::add(epoch == JNI_TRUE, id, string, thread);
       
   302 JVM_END
       
   303 
       
   304 JVM_ENTRY_NO_ENV(void, jfr_set_force_instrumentation(JNIEnv* env, jobject jvm, jboolean force_instrumentation))
       
   305   JfrEventClassTransformer::set_force_instrumentation(force_instrumentation == JNI_TRUE ? true : false);
       
   306 JVM_END
       
   307 
       
   308 JVM_ENTRY_NO_ENV(void, jfr_emit_old_object_samples(JNIEnv* env, jobject jvm, jlong cutoff_ticks, jboolean emit_all))
       
   309   LeakProfiler::emit_events(cutoff_ticks, emit_all == JNI_TRUE);
       
   310 JVM_END