1 /* 2 * Copyright (c) 2016, 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 "jfr/jni/jfrJavaSupport.hpp" 27 #include "jfr/utilities/jfrJavaLog.hpp" 28 #include "memory/resourceArea.hpp" 29 #include "runtime/thread.inline.hpp" 30 31 // #define JFR_LOG_TAGS_CONCATED(T0, T1, T2, T3, T4, T5, ...) \ 32 // T0 ## _ ## T1 ## _ ## T2 ## _ ## T3 ## _ ## T4 ## _ ## T5 33 34 // enum JfrLogTagSetType { 35 // #define JFR_LOG_TAG(...) \ 36 // EXPAND_VARARGS(JFR_LOG_TAGS_CONCATED(__VA_ARGS__, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG)), 37 38 // JFR_LOG_TAG_SET_LIST 39 40 // #undef JFR_LOG_TAG 41 // JFR_LOG_TAG_SET_COUNT 42 // }; 43 44 // struct jfrLogSubscriber 45 // { 46 // jobject log_tag_enum_ref; 47 // LogTagSet* log_tag_set; 48 // }; 49 50 // static jfrLogSubscriber log_tag_sets[JFR_LOG_TAG_SET_COUNT]; 51 52 // static void log_cfg_update(LogLevelType llt, JfrLogTagSetType jflt, TRAPS) { 53 // DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 54 // if (log_tag_sets[jflt].log_tag_enum_ref == NULL) { 55 // return; 56 // } 57 // jobject lt = log_tag_sets[jflt].log_tag_enum_ref; 58 // // set field tagSetLevel to llt value 59 // JavaValue result(T_VOID); 60 // JfrJavaArguments args(&result); 61 // args.set_klass(JfrJavaSupport::klass(lt)); 62 // args.set_name("tagSetLevel", CHECK); 63 // args.set_signature("I", CHECK); 64 // args.set_receiver(JfrJavaSupport::resolve_non_null(lt)); 65 // args.push_int(llt); 66 // JfrJavaSupport::set_field(&args, THREAD); 67 // } 68 69 // static LogLevelType highest_level(const LogTagSet& lts) { 70 // for (size_t i = 0; i < LogLevel::Count; i++) { 71 // if (lts.is_level((LogLevelType)i)) { 72 // return (LogLevelType)i; 73 // } 74 // } 75 // return LogLevel::Off; 76 // } 77 78 // static void log_config_change_internal(bool init, TRAPS) { 79 // LogLevelType llt; 80 // LogTagSet* lts; 81 82 // #define JFR_LOG_TAG(...) \ 83 // lts = &LogTagSetMapping<LOG_TAGS(__VA_ARGS__)>::tagset(); \ 84 // if (init) { \ 85 // JfrLogTagSetType tagSetType = \ 86 // EXPAND_VARARGS(JFR_LOG_TAGS_CONCATED(__VA_ARGS__, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG)); \ 87 // assert(NULL == log_tag_sets[tagSetType].log_tag_set, "Init JFR LogTagSets twice"); \ 88 // log_tag_sets[tagSetType].log_tag_set = lts; \ 89 // } \ 90 // llt = highest_level(*lts); \ 91 // log_cfg_update(llt, \ 92 // EXPAND_VARARGS(JFR_LOG_TAGS_CONCATED(__VA_ARGS__, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG, _NO_TAG)), THREAD); 93 // JFR_LOG_TAG_SET_LIST 94 // #undef JFR_LOG_TAG 95 // } 96 97 // static void log_config_change() { 98 // Thread* t = Thread::current(); 99 // DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(t)); 100 // log_config_change_internal(false, t); 101 // } 102 103 void JfrJavaLog::subscribe_log_level(jobject log_tag, jint id, TRAPS) { 104 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 105 // static bool subscribed_updates = true; 106 // assert(id < JFR_LOG_TAG_SET_COUNT, 107 // "LogTag id, java and native not in synch, %d < %d", id, JFR_LOG_TAG_SET_COUNT); 108 // assert(NULL == log_tag_sets[id].log_tag_enum_ref, "Subscribing twice"); 109 // log_tag_sets[id].log_tag_enum_ref = JfrJavaSupport::global_jni_handle(log_tag, THREAD); 110 // if (subscribed_updates) { 111 // LogConfiguration::register_update_listener(&log_config_change); 112 // log_config_change_internal(true, THREAD); 113 // subscribed_updates = false; 114 // } else { 115 // log_config_change_internal(false, THREAD); 116 // } 117 } 118 119 void JfrJavaLog::log(jint tag_set, jint level, jstring message, TRAPS) { 120 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD)); 121 if (!LogJFR) { 122 return; 123 } 124 if (message == NULL) { 125 return; 126 } 127 // if (level < (jint)LogLevel::First || level > (jint)LogLevel::Last) { 128 // JfrJavaSupport::throw_illegal_argument_exception("LogLevel passed is outside valid range", THREAD); 129 // return; 130 // } 131 // if (tag_set < 0 || tag_set >= (jint)JFR_LOG_TAG_SET_COUNT) { 132 // JfrJavaSupport::throw_illegal_argument_exception("LogTagSet id is outside valid range", THREAD); 133 // return; 134 // } 135 ResourceMark rm(THREAD); 136 const char* const s = JfrJavaSupport::c_str(message, CHECK); 137 assert(s != NULL, "invariant"); 138 // assert(log_tag_sets[tag_set].log_tag_set != NULL, "LogTagSet is not init"); 139 // log_tag_sets[tag_set].log_tag_set->log((LogLevelType)level, s); 140 tty->print_cr("JFR: %s", s); 141 }