1 /*
2 * Copyright (c) 2003, 2025, 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 "classfile/classLoader.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "classfile/vmClasses.hpp"
28 #include "compiler/compileBroker.hpp"
29 #include "gc/shared/collectedHeap.hpp"
30 #include "jmm.h"
31 #include "memory/allocation.inline.hpp"
32 #include "memory/iterator.hpp"
33 #include "memory/oopFactory.hpp"
34 #include "memory/resourceArea.hpp"
35 #include "memory/universe.hpp"
36 #include "oops/klass.hpp"
37 #include "oops/klass.inline.hpp"
38 #include "oops/objArrayKlass.hpp"
39 #include "oops/objArrayOop.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "oops/oopHandle.inline.hpp"
42 #include "oops/typeArrayOop.inline.hpp"
43 #include "runtime/flags/jvmFlag.hpp"
44 #include "runtime/globals.hpp"
45 #include "runtime/handles.inline.hpp"
46 #include "runtime/interfaceSupport.inline.hpp"
47 #include "runtime/javaCalls.hpp"
48 #include "runtime/jniHandles.inline.hpp"
49 #include "runtime/mutexLocker.hpp"
50 #include "runtime/notificationThread.hpp"
51 #include "runtime/os.hpp"
52 #include "runtime/thread.inline.hpp"
53 #include "runtime/threads.hpp"
54 #include "runtime/threadSMR.hpp"
55 #include "runtime/vmOperations.hpp"
56 #include "services/classLoadingService.hpp"
57 #include "services/cpuTimeUsage.hpp"
58 #include "services/diagnosticCommand.hpp"
59 #include "services/diagnosticFramework.hpp"
60 #include "services/finalizerService.hpp"
61 #include "services/gcNotifier.hpp"
1426
1427 JavaThread* java_thread = nullptr;
1428 if (thread_id == 0) {
1429 // current thread
1430 return os::current_thread_cpu_time();
1431 } else {
1432 ThreadsListHandle tlh;
1433 java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);
1434 if (is_platform_thread(java_thread)) {
1435 return os::thread_cpu_time((Thread*) java_thread);
1436 }
1437 }
1438 return -1;
1439 JVM_END
1440
1441 // Returns a String array of all VM global flag names
1442 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
1443 // last flag entry is always null, so subtract 1
1444 int nFlags = (int) JVMFlag::numFlags - 1;
1445 // allocate a temp array
1446 objArrayOop r = oopFactory::new_objArray(vmClasses::String_klass(),
1447 nFlags, CHECK_NULL);
1448 objArrayHandle flags_ah(THREAD, r);
1449 int num_entries = 0;
1450 for (int i = 0; i < nFlags; i++) {
1451 JVMFlag* flag = &JVMFlag::flags[i];
1452 // Exclude develop flags in product builds.
1453 if (flag->is_constant_in_binary()) {
1454 continue;
1455 }
1456 // Exclude the locked (experimental, diagnostic) flags
1457 if (flag->is_unlocked() || flag->is_unlocker()) {
1458 Handle s = java_lang_String::create_from_str(flag->name(), CHECK_NULL);
1459 flags_ah->obj_at_put(num_entries, s());
1460 num_entries++;
1461 }
1462 }
1463
1464 if (num_entries < nFlags) {
1465 // Return array of right length
1466 objArrayOop res = oopFactory::new_objArray(vmClasses::String_klass(), num_entries, CHECK_NULL);
1467 for(int i = 0; i < num_entries; i++) {
1468 res->obj_at_put(i, flags_ah->obj_at(i));
1469 }
1470 return (jobjectArray)JNIHandles::make_local(THREAD, res);
1471 }
1472
1473 return (jobjectArray)JNIHandles::make_local(THREAD, flags_ah());
1474 JVM_END
1475
1476 // Utility function used by jmm_GetVMGlobals. Returns false if flag type
1477 // can't be determined, true otherwise. If false is returned, then *global
1478 // will be incomplete and invalid.
1479 static bool add_global_entry(Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) {
1480 Handle flag_name;
1481 if (name() == nullptr) {
1482 flag_name = java_lang_String::create_from_str(flag->name(), CHECK_false);
1483 } else {
1484 flag_name = name;
1485 }
1486 global->name = (jstring)JNIHandles::make_local(THREAD, flag_name());
1552 // Fill globals array of count length with jmmVMGlobal entries
1553 // specified by names. If names == null, fill globals array
1554 // with all Flags. Return value is number of entries
1555 // created in globals.
1556 // If a JVMFlag with a given name in an array element does not
1557 // exist, globals[i].name will be set to null.
1558 JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env,
1559 jobjectArray names,
1560 jmmVMGlobal *globals,
1561 jint count))
1562
1563
1564 if (globals == nullptr) {
1565 THROW_(vmSymbols::java_lang_NullPointerException(), 0);
1566 }
1567
1568 ResourceMark rm(THREAD);
1569
1570 if (names != nullptr) {
1571 // return the requested globals
1572 objArrayOop ta = objArrayOop(JNIHandles::resolve_non_null(names));
1573 objArrayHandle names_ah(THREAD, ta);
1574 // Make sure we have a String array
1575 Klass* element_klass = ObjArrayKlass::cast(names_ah->klass())->element_klass();
1576 if (element_klass != vmClasses::String_klass()) {
1577 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1578 "Array element type is not String class", 0);
1579 }
1580
1581 int names_length = names_ah->length();
1582 int num_entries = 0;
1583 for (int i = 0; i < names_length && i < count; i++) {
1584 oop s = names_ah->obj_at(i);
1585 if (s == nullptr) {
1586 THROW_(vmSymbols::java_lang_NullPointerException(), 0);
1587 }
1588
1589 Handle sh(THREAD, s);
1590 char* str = java_lang_String::as_utf8_string(s);
1591 JVMFlag* flag = JVMFlag::find_flag(str);
1592 if (flag != nullptr &&
1593 add_global_entry(sh, &globals[i], flag, THREAD)) {
1594 num_entries++;
1595 } else {
1979 ResourceMark rm(THREAD);
1980 GrowableArray<const char *>* dcmd_list = DCmdFactory::DCmd_list(DCmd_Source_MBean);
1981 objArrayOop cmd_array_oop = oopFactory::new_objArray(vmClasses::String_klass(),
1982 dcmd_list->length(), CHECK_NULL);
1983 objArrayHandle cmd_array(THREAD, cmd_array_oop);
1984 for (int i = 0; i < dcmd_list->length(); i++) {
1985 oop cmd_name = java_lang_String::create_oop_from_str(dcmd_list->at(i), CHECK_NULL);
1986 cmd_array->obj_at_put(i, cmd_name);
1987 }
1988 return (jobjectArray) JNIHandles::make_local(THREAD, cmd_array());
1989 JVM_END
1990
1991 JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds,
1992 dcmdInfo* infoArray))
1993 if (cmds == nullptr || infoArray == nullptr) {
1994 THROW(vmSymbols::java_lang_NullPointerException());
1995 }
1996
1997 ResourceMark rm(THREAD);
1998
1999 objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(cmds));
2000 objArrayHandle cmds_ah(THREAD, ca);
2001
2002 // Make sure we have a String array
2003 Klass* element_klass = ObjArrayKlass::cast(cmds_ah->klass())->element_klass();
2004 if (element_klass != vmClasses::String_klass()) {
2005 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2006 "Array element type is not String class");
2007 }
2008
2009 GrowableArray<DCmdInfo *>* info_list = DCmdFactory::DCmdInfo_list(DCmd_Source_MBean);
2010
2011 int num_cmds = cmds_ah->length();
2012 for (int i = 0; i < num_cmds; i++) {
2013 oop cmd = cmds_ah->obj_at(i);
2014 if (cmd == nullptr) {
2015 THROW_MSG(vmSymbols::java_lang_NullPointerException(),
2016 "Command name cannot be null.");
2017 }
2018 char* cmd_name = java_lang_String::as_utf8_string(cmd);
2019 if (cmd_name == nullptr) {
2020 THROW_MSG(vmSymbols::java_lang_NullPointerException(),
2021 "Command name cannot be null.");
2022 }
2023 int pos = info_list->find_if([&](DCmdInfo* info) {
|
1 /*
2 * Copyright (c) 2003, 2026, 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 "classfile/classLoader.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "classfile/vmClasses.hpp"
28 #include "compiler/compileBroker.hpp"
29 #include "gc/shared/collectedHeap.hpp"
30 #include "jmm.h"
31 #include "memory/allocation.inline.hpp"
32 #include "memory/iterator.hpp"
33 #include "memory/oopFactory.hpp"
34 #include "memory/resourceArea.hpp"
35 #include "memory/universe.hpp"
36 #include "oops/klass.hpp"
37 #include "oops/klass.inline.hpp"
38 #include "oops/objArrayKlass.hpp"
39 #include "oops/objArrayOop.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "oops/oopCast.inline.hpp"
42 #include "oops/oopHandle.inline.hpp"
43 #include "oops/refArrayOop.inline.hpp"
44 #include "oops/typeArrayOop.inline.hpp"
45 #include "runtime/flags/jvmFlag.hpp"
46 #include "runtime/globals.hpp"
47 #include "runtime/handles.inline.hpp"
48 #include "runtime/interfaceSupport.inline.hpp"
49 #include "runtime/javaCalls.hpp"
50 #include "runtime/jniHandles.inline.hpp"
51 #include "runtime/mutexLocker.hpp"
52 #include "runtime/notificationThread.hpp"
53 #include "runtime/os.hpp"
54 #include "runtime/thread.inline.hpp"
55 #include "runtime/threads.hpp"
56 #include "runtime/threadSMR.hpp"
57 #include "runtime/vmOperations.hpp"
58 #include "services/classLoadingService.hpp"
59 #include "services/cpuTimeUsage.hpp"
60 #include "services/diagnosticCommand.hpp"
61 #include "services/diagnosticFramework.hpp"
62 #include "services/finalizerService.hpp"
63 #include "services/gcNotifier.hpp"
1428
1429 JavaThread* java_thread = nullptr;
1430 if (thread_id == 0) {
1431 // current thread
1432 return os::current_thread_cpu_time();
1433 } else {
1434 ThreadsListHandle tlh;
1435 java_thread = tlh.list()->find_JavaThread_from_java_tid(thread_id);
1436 if (is_platform_thread(java_thread)) {
1437 return os::thread_cpu_time((Thread*) java_thread);
1438 }
1439 }
1440 return -1;
1441 JVM_END
1442
1443 // Returns a String array of all VM global flag names
1444 JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
1445 // last flag entry is always null, so subtract 1
1446 int nFlags = (int) JVMFlag::numFlags - 1;
1447 // allocate a temp array
1448 refArrayOop r = oopFactory::new_refArray(vmClasses::String_klass(),
1449 nFlags,
1450 CHECK_NULL);
1451 refArrayHandle flags_ah(THREAD, r);
1452 int num_entries = 0;
1453 for (int i = 0; i < nFlags; i++) {
1454 JVMFlag* flag = &JVMFlag::flags[i];
1455 // Exclude develop flags in product builds.
1456 if (flag->is_constant_in_binary()) {
1457 continue;
1458 }
1459 // Exclude the locked (experimental, diagnostic) flags
1460 if (flag->is_unlocked() || flag->is_unlocker()) {
1461 Handle s = java_lang_String::create_from_str(flag->name(), CHECK_NULL);
1462 flags_ah->obj_at_put(num_entries, s());
1463 num_entries++;
1464 }
1465 }
1466
1467 if (num_entries < nFlags) {
1468 // Return array of right length
1469 refArrayOop res = oopFactory::new_refArray(vmClasses::String_klass(), num_entries, CHECK_NULL);
1470 for(int i = 0; i < num_entries; i++) {
1471 res->obj_at_put(i, flags_ah->obj_at(i));
1472 }
1473 return (jobjectArray)JNIHandles::make_local(THREAD, res);
1474 }
1475
1476 return (jobjectArray)JNIHandles::make_local(THREAD, flags_ah());
1477 JVM_END
1478
1479 // Utility function used by jmm_GetVMGlobals. Returns false if flag type
1480 // can't be determined, true otherwise. If false is returned, then *global
1481 // will be incomplete and invalid.
1482 static bool add_global_entry(Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) {
1483 Handle flag_name;
1484 if (name() == nullptr) {
1485 flag_name = java_lang_String::create_from_str(flag->name(), CHECK_false);
1486 } else {
1487 flag_name = name;
1488 }
1489 global->name = (jstring)JNIHandles::make_local(THREAD, flag_name());
1555 // Fill globals array of count length with jmmVMGlobal entries
1556 // specified by names. If names == null, fill globals array
1557 // with all Flags. Return value is number of entries
1558 // created in globals.
1559 // If a JVMFlag with a given name in an array element does not
1560 // exist, globals[i].name will be set to null.
1561 JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env,
1562 jobjectArray names,
1563 jmmVMGlobal *globals,
1564 jint count))
1565
1566
1567 if (globals == nullptr) {
1568 THROW_(vmSymbols::java_lang_NullPointerException(), 0);
1569 }
1570
1571 ResourceMark rm(THREAD);
1572
1573 if (names != nullptr) {
1574 // return the requested globals
1575 refArrayOop ta = oop_cast<refArrayOop>(JNIHandles::resolve_non_null(names));
1576 refArrayHandle names_ah(THREAD, ta);
1577 // Make sure we have a String array
1578 Klass* element_klass = names_ah->klass()->element_klass();
1579 if (element_klass != vmClasses::String_klass()) {
1580 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
1581 "Array element type is not String class", 0);
1582 }
1583
1584 int names_length = names_ah->length();
1585 int num_entries = 0;
1586 for (int i = 0; i < names_length && i < count; i++) {
1587 oop s = names_ah->obj_at(i);
1588 if (s == nullptr) {
1589 THROW_(vmSymbols::java_lang_NullPointerException(), 0);
1590 }
1591
1592 Handle sh(THREAD, s);
1593 char* str = java_lang_String::as_utf8_string(s);
1594 JVMFlag* flag = JVMFlag::find_flag(str);
1595 if (flag != nullptr &&
1596 add_global_entry(sh, &globals[i], flag, THREAD)) {
1597 num_entries++;
1598 } else {
1982 ResourceMark rm(THREAD);
1983 GrowableArray<const char *>* dcmd_list = DCmdFactory::DCmd_list(DCmd_Source_MBean);
1984 objArrayOop cmd_array_oop = oopFactory::new_objArray(vmClasses::String_klass(),
1985 dcmd_list->length(), CHECK_NULL);
1986 objArrayHandle cmd_array(THREAD, cmd_array_oop);
1987 for (int i = 0; i < dcmd_list->length(); i++) {
1988 oop cmd_name = java_lang_String::create_oop_from_str(dcmd_list->at(i), CHECK_NULL);
1989 cmd_array->obj_at_put(i, cmd_name);
1990 }
1991 return (jobjectArray) JNIHandles::make_local(THREAD, cmd_array());
1992 JVM_END
1993
1994 JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds,
1995 dcmdInfo* infoArray))
1996 if (cmds == nullptr || infoArray == nullptr) {
1997 THROW(vmSymbols::java_lang_NullPointerException());
1998 }
1999
2000 ResourceMark rm(THREAD);
2001
2002 refArrayOop ca = oop_cast<refArrayOop>(JNIHandles::resolve_non_null(cmds));
2003 refArrayHandle cmds_ah(THREAD, ca);
2004
2005 // Make sure we have a String array
2006 Klass* element_klass = cmds_ah->klass()->element_klass();
2007 if (element_klass != vmClasses::String_klass()) {
2008 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2009 "Array element type is not String class");
2010 }
2011
2012 GrowableArray<DCmdInfo *>* info_list = DCmdFactory::DCmdInfo_list(DCmd_Source_MBean);
2013
2014 int num_cmds = cmds_ah->length();
2015 for (int i = 0; i < num_cmds; i++) {
2016 oop cmd = cmds_ah->obj_at(i);
2017 if (cmd == nullptr) {
2018 THROW_MSG(vmSymbols::java_lang_NullPointerException(),
2019 "Command name cannot be null.");
2020 }
2021 char* cmd_name = java_lang_String::as_utf8_string(cmd);
2022 if (cmd_name == nullptr) {
2023 THROW_MSG(vmSymbols::java_lang_NullPointerException(),
2024 "Command name cannot be null.");
2025 }
2026 int pos = info_list->find_if([&](DCmdInfo* info) {
|