Tue, 29 Oct 2019 19:53:30 -0300
8231995: two jtreg tests failed after 8229366 is fixed
Reviewed-by: jbachorik
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 */
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "classfile/symbolTable.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "jfr/jni/jfrJavaSupport.hpp"
30 #include "jfr/jni/jfrUpcalls.hpp"
31 #include "jfr/support/jfrEventClass.hpp"
32 #include "memory/oopFactory.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "oops/typeArrayKlass.hpp"
35 #include "oops/typeArrayOop.hpp"
36 #include "runtime/handles.inline.hpp"
37 #include "runtime/os.hpp"
38 #include "runtime/thread.inline.hpp"
39 #include "utilities/exceptions.hpp"
41 static Symbol* jvm_upcalls_class_sym = NULL;
42 static Symbol* on_retransform_method_sym = NULL;
43 static Symbol* on_retransform_signature_sym = NULL;
44 static Symbol* bytes_for_eager_instrumentation_sym = NULL;
45 static Symbol* bytes_for_eager_instrumentation_sig_sym = NULL;
47 static bool initialize(TRAPS) {
48 static bool initialized = false;
49 if (!initialized) {
50 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
51 jvm_upcalls_class_sym = SymbolTable::new_permanent_symbol("jdk/jfr/internal/JVMUpcalls", CHECK_false);
52 on_retransform_method_sym = SymbolTable::new_permanent_symbol("onRetransform", CHECK_false);
53 on_retransform_signature_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B", CHECK_false);
54 bytes_for_eager_instrumentation_sym = SymbolTable::new_permanent_symbol("bytesForEagerInstrumentation", CHECK_false);
55 bytes_for_eager_instrumentation_sig_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B", THREAD);
56 initialized = bytes_for_eager_instrumentation_sig_sym != NULL;
57 }
58 return initialized;
59 }
61 static const typeArrayOop invoke(jlong trace_id,
62 jboolean force_instrumentation,
63 jclass class_being_redefined,
64 jint class_data_len,
65 const unsigned char* class_data,
66 Symbol* method_sym,
67 Symbol* signature_sym,
68 jint& new_bytes_length,
69 TRAPS) {
70 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
71 const Klass* klass = SystemDictionary::resolve_or_fail(jvm_upcalls_class_sym, true, CHECK_NULL);
72 assert(klass != NULL, "invariant");
73 typeArrayOop old_byte_array = oopFactory::new_byteArray(class_data_len, CHECK_NULL);
74 memcpy(old_byte_array->byte_at_addr(0), class_data, class_data_len);
75 JavaValue result(T_OBJECT);
76 JfrJavaArguments args(&result, klass, method_sym, signature_sym);
77 args.push_long(trace_id);
78 args.push_int(force_instrumentation);
79 args.push_jobject(class_being_redefined);
80 args.push_oop(old_byte_array);
81 JfrJavaSupport::call_static(&args, THREAD);
82 if (HAS_PENDING_EXCEPTION) {
83 if (true) tty->print_cr("JfrUpcall failed");
84 return NULL;
85 }
86 // The result should be a [B
87 const oop res = (oop)result.get_jobject();
88 assert(res != NULL, "invariant");
89 assert(res->is_typeArray(), "invariant");
90 assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "invariant");
91 const typeArrayOop new_byte_array = typeArrayOop(res);
92 new_bytes_length = (jint)new_byte_array->length();
93 return new_byte_array;
94 }
96 static const size_t ERROR_MSG_BUFFER_SIZE = 256;
97 static void log_error_and_throw_oom(jint new_bytes_length, TRAPS) {
98 char error_buffer[ERROR_MSG_BUFFER_SIZE];
99 jio_snprintf(error_buffer, ERROR_MSG_BUFFER_SIZE,
100 "Thread local allocation (native) for " SIZE_FORMAT " bytes failed in JfrUpcalls", (size_t)new_bytes_length);
101 if (true) tty->print_cr("%s", error_buffer);
102 JfrJavaSupport::throw_out_of_memory_error(error_buffer, CHECK);
103 }
105 void JfrUpcalls::on_retransform(jlong trace_id,
106 jclass class_being_redefined,
107 jint class_data_len,
108 const unsigned char* class_data,
109 jint* new_class_data_len,
110 unsigned char** new_class_data,
111 TRAPS) {
112 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
113 assert(class_being_redefined != NULL, "invariant");
114 assert(class_data != NULL, "invariant");
115 assert(new_class_data_len != NULL, "invariant");
116 assert(new_class_data != NULL, "invariant");
117 if (!JdkJfrEvent::is_visible(class_being_redefined)) {
118 return;
119 }
120 jint new_bytes_length = 0;
121 initialize(THREAD);
122 const typeArrayOop new_byte_array = invoke(trace_id,
123 false,
124 class_being_redefined,
125 class_data_len,
126 class_data,
127 on_retransform_method_sym,
128 on_retransform_signature_sym,
129 new_bytes_length,
130 CHECK);
131 assert(new_byte_array != NULL, "invariant");
132 assert(new_bytes_length > 0, "invariant");
133 // memory space must be malloced as mtInternal
134 // as it will be deallocated by JVMTI routines
135 unsigned char* const new_bytes = (unsigned char* const)os::malloc(new_bytes_length, mtInternal);
136 if (new_bytes == NULL) {
137 log_error_and_throw_oom(new_bytes_length, THREAD); // unwinds
138 }
139 assert(new_bytes != NULL, "invariant");
140 memcpy(new_bytes, new_byte_array->byte_at_addr(0), (size_t)new_bytes_length);
141 *new_class_data_len = new_bytes_length;
142 *new_class_data = new_bytes;
143 }
145 void JfrUpcalls::new_bytes_eager_instrumentation(jlong trace_id,
146 jboolean force_instrumentation,
147 jclass super,
148 jint class_data_len,
149 const unsigned char* class_data,
150 jint* new_class_data_len,
151 unsigned char** new_class_data,
152 TRAPS) {
153 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
154 assert(super != NULL, "invariant");
155 assert(class_data != NULL, "invariant");
156 assert(new_class_data_len != NULL, "invariant");
157 assert(new_class_data != NULL, "invariant");
158 jint new_bytes_length = 0;
159 initialize(THREAD);
160 const typeArrayOop new_byte_array = invoke(trace_id,
161 force_instrumentation,
162 super,
163 class_data_len,
164 class_data,
165 bytes_for_eager_instrumentation_sym,
166 bytes_for_eager_instrumentation_sig_sym,
167 new_bytes_length,
168 CHECK);
169 assert(new_byte_array != NULL, "invariant");
170 assert(new_bytes_length > 0, "invariant");
171 unsigned char* const new_bytes = NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, unsigned char, new_bytes_length);
172 if (new_bytes == NULL) {
173 log_error_and_throw_oom(new_bytes_length, THREAD); // this unwinds
174 }
175 assert(new_bytes != NULL, "invariant");
176 memcpy(new_bytes, new_byte_array->byte_at_addr(0), (size_t)new_bytes_length);
177 *new_class_data_len = new_bytes_length;
178 *new_class_data = new_bytes;
179 }
181 instanceKlassHandle JfrUpcalls::load_event_handler_proxy_class(TRAPS) {
182 JavaValue result(T_OBJECT);
183 JfrJavaArguments call_args(&result, "jdk/jfr/internal/JVMUpcalls",
184 "getEventHandlerProxyClass", "()Ljava/lang/Class;", CHECK_NULL);
185 JfrJavaSupport::call_static(&call_args, CHECK_NULL);
186 assert(result.get_type() == T_OBJECT, "invariant");
187 instanceHandle h_java_proxy(THREAD, (instanceOop)result.get_jobject());
188 assert(h_java_proxy.not_null(), "invariant");
189 return java_lang_Class::as_Klass(h_java_proxy());
190 }