1 /*
 2  * Copyright (c) 2023, 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 "runtime/globals_extension.hpp"
26 #include "runtime/interfaceSupport.inline.hpp"
27 #include "runtime/runtimeUpcallNop.hpp"
28 #include "runtime/runtimeUpcalls.hpp"
29 
30 bool RuntimeUpcallNop::_method_filter_result = false;
31 
32 bool runtimeUpcallNop_register_upcalls()
33 {
34   return RuntimeUpcallNop::register_upcalls();
35 }
36 
37 bool RuntimeUpcallNop::register_upcalls()
38 {
39   if(AddRuntimeUpcallsNOP == nullptr || FLAG_IS_DEFAULT(AddRuntimeUpcallsNOP)) return true;
40 
41   const char* method_entry = "onMethodEntry:";
42   const size_t method_entry_len = strlen(method_entry);
43   const char* method_exit = "onMethodExit:";
44   const size_t method_exit_len = strlen(method_exit);
45 
46   const char* filter_all = "all";
47   const size_t filter_all_len = strlen(filter_all);
48   const char* filter_none = "none";
49   const size_t filter_none_len = strlen(filter_none);
50 
51   const char* filter_option = nullptr;
52   RuntimeUpcallType upcall_type = RuntimeUpcallType::onMethodEntry;
53   const char* command = AddRuntimeUpcallsNOP == nullptr ? "" : AddRuntimeUpcallsNOP;
54 
55   if (strncmp(command, method_entry, method_entry_len) == 0) {
56     filter_option = command + method_entry_len;
57     upcall_type = RuntimeUpcallType::onMethodEntry;
58   } else if (strncmp(command, method_exit, method_exit_len) == 0) {
59     filter_option = command + method_exit_len;
60     upcall_type = RuntimeUpcallType::onMethodExit;
61   } else {
62     ttyLocker ttyl;
63     tty->print_cr("An error occurred during parsing AddRuntimeUpcallsNOP");
64     tty->print_cr("Error! Expected 'onMethodEntry:' or 'onMethodExit:'");
65     return false;
66   }
67 
68   assert(filter_option != nullptr, "sanity");
69   if (strncmp(filter_option, filter_all, filter_all_len) == 0) {
70     _method_filter_result = true;
71   } else if (strncmp(filter_option, filter_none, filter_none_len) == 0) {
72     _method_filter_result = false;
73   } else {
74     ttyLocker ttyl;
75     tty->print_cr("An error occurred during parsing AddRuntimeUpcallsNOP");
76     tty->print_cr("Error! Expected 'all' or 'none'");
77     return false;
78   }
79 
80   if (RuntimeUpcalls::register_upcall(
81         upcall_type,
82         "nop_method",
83         RuntimeUpcallNop::nop_method,
84         RuntimeUpcallNop::filter_method_callback)) {
85     return true;
86   }
87   return false;
88 }
89 
90 bool RuntimeUpcallNop::filter_method_callback(MethodDetails& method_details)
91 {
92   return _method_filter_result;
93 }
94 
95 JRT_ENTRY(void, RuntimeUpcallNop::nop_method(JavaThread* current))
96 {
97 }
98 JRT_END