1 /*
2  * Copyright (c) 2015, 2020, 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 #ifndef SHARE_LOGGING_LOGPREFIX_HPP
25 #define SHARE_LOGGING_LOGPREFIX_HPP
26 
27 #include "gc/shared/gcId.hpp"
28 #include "logging/logTag.hpp"
29 
30 // Prefixes prepend each log message for a specified tagset with a given prefix.
31 // These prefixes are written before the log message but after the log decorations.
32 //
33 // A prefix is defined as a function that takes a buffer (with some size) as argument.
34 // This function will be called for each log message, and should write the prefix
35 // to the given buffer. The function should return how many characters it wrote,
36 // which should never exceed the given size.
37 //
38 // List of prefixes for specific tags and/or tagsets.
39 // Syntax: LOG_PREFIX(<name of prefixer function>, LOG_TAGS(<chosen log tags>))
40 // Where the prefixer function matches the following signature: size_t (*)(char*, size_t)
41 
42 // Prefix function for internal vm test
43 DEBUG_ONLY(size_t Test_log_prefix_prefixer(char* buf, size_t len);)
44 
45 #define LOG_PREFIX_LIST \
46   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc)) \
47   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, age)) \
48   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, alloc)) \
49   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, alloc, region)) \
50   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, barrier)) \
51   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, breakpoint)) \
52   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, classhisto)) \
53   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, compaction)) \
54   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, cpu)) \
55   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo)) \
56   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, cset)) \
57   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, heap)) \
58   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, ihop)) \
59   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ergo, refine)) \
60   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap)) \
61   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap, numa)) \
62   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, heap, region)) \
63   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, freelist)) \
64   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, humongous)) \
65   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ihop)) \
66   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, liveness)) \
67   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, load)) \
68   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, marking)) \
69   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, metaspace)) \
70   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, mmu)) \
71   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, nmethod)) \
72   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases)) \
73   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, ref)) \
74   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, start)) \
75   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, task)) \
76   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, verify)) \
77   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, verify, start)) \
78   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, plab)) \
79   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, promotion)) \
80   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, region)) \
81   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, remset)) \
82   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, remset, tracking)) \
83   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref)) \
84   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref, start)) \
85   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, refine, stats)) \
86   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, reloc)) \
87   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, start)) \
88   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, symboltable)) \
89   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, sweep)) \
90   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task)) \
91   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, start)) \
92   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, stats)) \
93   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, time)) \
94   DEBUG_ONLY(LOG_PREFIX(Test_log_prefix_prefixer, LOG_TAGS(logging, test))) \
95   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, tlab)) \
96   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, verify)) \
97   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, verify, start)) \
98   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, workgang))
99 
100 
101 // The empty prefix, used when there's no prefix defined.
102 template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag = LogTag::__NO_TAG>
103 struct LogPrefix : public AllStatic {
104   STATIC_ASSERT(GuardTag == LogTag::__NO_TAG);
prefixLogPrefix105   static size_t prefix(char* buf, size_t len) {
106     return 0;
107   }
108 };
109 
110 #define LOG_PREFIX(fn, ...) \
111 template <> struct LogPrefix<__VA_ARGS__> { \
112   static size_t prefix(char* buf, size_t len) { \
113     size_t ret = fn(buf, len); \
114     /* Either prefix did fit (strlen(buf) == ret && ret < len) */ \
115     /* or the prefix didn't fit in buffer (ret > len && strlen(buf) < len) */ \
116     assert(ret == 0 || strlen(buf) < len, \
117            "Buffer overrun by prefix function."); \
118     assert(ret == 0 || strlen(buf) == ret || ret >= len, \
119            "Prefix function should return length of prefix written," \
120            " or the intended length of prefix if the buffer was too small."); \
121     return ret; \
122   } \
123 };
124 LOG_PREFIX_LIST
125 #undef LOG_PREFIX
126 
127 #endif // SHARE_LOGGING_LOGPREFIX_HPP
128