diff --git a/src/arguments.cpp b/src/arguments.cpp index 507442fae..abecbe80c 100644 --- a/src/arguments.cpp +++ b/src/arguments.cpp @@ -353,6 +353,9 @@ Error Arguments::parse(const char* args) { CASE("meminfolog") _log_meminfo_on_dump = true; + CASE("includemm") + _includemm = true; + DEFAULT() if (_unknown_arg == NULL) _unknown_arg = arg; } diff --git a/src/arguments.h b/src/arguments.h index e5f81cc92..b36a6f31a 100644 --- a/src/arguments.h +++ b/src/arguments.h @@ -157,6 +157,7 @@ class Arguments { bool _sched; bool _live; bool _fdtransfer; + bool _includemm; const char* _fdtransfer_path; int _style; CStack _cstack; @@ -221,7 +222,8 @@ class Arguments { _title(NULL), _minwidth(0), _reverse(false), - _log_meminfo_on_dump(false) { + _log_meminfo_on_dump(false), + _includemm(false) { } ~Arguments(); diff --git a/src/frameName.cpp b/src/frameName.cpp index e6f0ca5b0..8d85d9227 100644 --- a/src/frameName.cpp +++ b/src/frameName.cpp @@ -28,6 +28,24 @@ static inline bool isDigit(char c) { } +// Based on: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#:~:text=Table%C2%A04.5.%C2%A0Method%20access%20and%20property%20flags +// Good practice order from: https://checkstyle.sourceforge.io/config_modifier.html#ModifierOrder +const static std::pair access_flags [] = { + std::make_pair(0x0001, "public"), + std::make_pair(0x0002, "private"), + std::make_pair(0x0004, "protected"), + std::make_pair(0x0400, "abstract"), + std::make_pair(0x0008, "static"), + std::make_pair(0x0010, "final"), + std::make_pair(0x0020, "synchronized"), + std::make_pair(0x0100, "native"), + std::make_pair(0x0800, "strict"), + std::make_pair(0x0040, "bridge"), + std::make_pair(0x0080, "varargs"), + std::make_pair(0x1000, "synthetic"), +}; + + Matcher::Matcher(const char* pattern) { if (pattern[0] == '*') { _type = MATCH_ENDS_WITH; @@ -95,7 +113,7 @@ FrameName::FrameName(Arguments& args, int style, int epoch, Mutex& thread_names_ { // Require printf to use standard C format regardless of system locale _saved_locale = uselocale(newlocale(LC_NUMERIC_MASK, "C", (locale_t)0)); - + _includemm = args._includemm; buildFilter(_include, args._buf, args._include); buildFilter(_exclude, args._buf, args._exclude); @@ -168,6 +186,7 @@ void FrameName::javaMethodName(jmethodID method) { char* class_name = NULL; char* method_name = NULL; char* method_sig = NULL; + jint modifiers = 0; jvmtiEnv* jvmti = VM::jvmti(); jvmtiError err; @@ -177,6 +196,16 @@ void FrameName::javaMethodName(jmethodID method) { (err = jvmti->GetClassSignature(method_class, &class_name, NULL)) == 0) { // Trim 'L' and ';' off the class descriptor like 'Ljava/lang/Object;' javaClassName(class_name + 1, strlen(class_name) - 2, _style); + if (_includemm) { + jvmti->GetMethodModifiers(method, &modifiers); + std::string modifiers_to_append = ""; + for (int i=0; i<(sizeof(access_flags) / sizeof(access_flags[0])); i++) { + if (modifiers & access_flags[i].first) { + modifiers_to_append.append(access_flags[i].second + " "); + } + } + _str.insert(0, modifiers_to_append); + } _str.append(".").append(method_name); if (_style & STYLE_SIGNATURES) { if (_style & STYLE_NO_SEMICOLON) { diff --git a/src/frameName.h b/src/frameName.h index 26d8e837c..e8cea7ad4 100644 --- a/src/frameName.h +++ b/src/frameName.h @@ -75,6 +75,7 @@ class FrameName { Mutex& _thread_names_lock; ThreadMap& _thread_names; locale_t _saved_locale; + bool _includemm; void buildFilter(std::vector& vector, const char* base, int offset); const char* decodeNativeSymbol(const char* name);