src/share/vm/jfr/jni/jfrJavaCall.cpp

Fri, 27 Sep 2019 10:27:29 +0800

author
egahlin
date
Fri, 27 Sep 2019 10:27:29 +0800
changeset 9883
02a4c08a8777
parent 9858
b985cbb00e68
permissions
-rw-r--r--

8216064: -XX:StartFlightRecording:settings= doesn't work properly
Reviewed-by: mgronlun

apetushkov@9858 1 /*
apetushkov@9858 2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
apetushkov@9858 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
apetushkov@9858 4 *
apetushkov@9858 5 * This code is free software; you can redistribute it and/or modify it
apetushkov@9858 6 * under the terms of the GNU General Public License version 2 only, as
apetushkov@9858 7 * published by the Free Software Foundation.
apetushkov@9858 8 *
apetushkov@9858 9 * This code is distributed in the hope that it will be useful, but WITHOUT
apetushkov@9858 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
apetushkov@9858 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
apetushkov@9858 12 * version 2 for more details (a copy is included in the LICENSE file that
apetushkov@9858 13 * accompanied this code).
apetushkov@9858 14 *
apetushkov@9858 15 * You should have received a copy of the GNU General Public License version
apetushkov@9858 16 * 2 along with this work; if not, write to the Free Software Foundation,
apetushkov@9858 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
apetushkov@9858 18 *
apetushkov@9858 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
apetushkov@9858 20 * or visit www.oracle.com if you need additional information or have any
apetushkov@9858 21 * questions.
apetushkov@9858 22 *
apetushkov@9858 23 */
apetushkov@9858 24
apetushkov@9858 25 #include "precompiled.hpp"
apetushkov@9858 26 #include "classfile/symbolTable.hpp"
apetushkov@9858 27 #include "classfile/systemDictionary.hpp"
apetushkov@9858 28 #include "jfr/jni/jfrJavaCall.hpp"
apetushkov@9858 29 #include "jfr/jni/jfrJavaSupport.hpp"
apetushkov@9858 30 #include "memory/resourceArea.hpp"
apetushkov@9858 31 #include "runtime/handles.inline.hpp"
apetushkov@9858 32 #include "runtime/javaCalls.hpp"
apetushkov@9858 33 #include "utilities/globalDefinitions.hpp"
apetushkov@9858 34
apetushkov@9858 35 #ifdef ASSERT
apetushkov@9858 36 static bool is_large_value(const JavaValue& value) {
apetushkov@9858 37 return value.get_type() == T_LONG || value.get_type() == T_DOUBLE;
apetushkov@9858 38 }
apetushkov@9858 39 #endif // ASSERT
apetushkov@9858 40
apetushkov@9858 41 static Symbol* resolve(const char* str, TRAPS) {
apetushkov@9858 42 assert(str != NULL, "invariant");
apetushkov@9858 43 return SymbolTable::lookup(str, (int)strlen(str), THREAD);
apetushkov@9858 44 }
apetushkov@9858 45
apetushkov@9858 46 static Klass* resolve(Symbol* k_sym, TRAPS) {
apetushkov@9858 47 assert(k_sym != NULL, "invariant");
apetushkov@9858 48 return SystemDictionary::resolve_or_fail(k_sym, true, THREAD);
apetushkov@9858 49 }
apetushkov@9858 50
apetushkov@9858 51 JfrJavaArguments::Parameters::Parameters() : _storage_index(0), _java_stack_slots(0) {
apetushkov@9858 52 JavaValue value(T_VOID);
apetushkov@9858 53 push(value);
apetushkov@9858 54 }
apetushkov@9858 55
apetushkov@9858 56 void JfrJavaArguments::Parameters::push(const JavaValue& value) {
apetushkov@9858 57 assert(_storage != NULL, "invariant");
apetushkov@9858 58 assert(!is_large_value(value), "invariant");
apetushkov@9858 59 assert(_storage_index < SIZE, "invariant");
apetushkov@9858 60 _storage[_storage_index++] = value;
apetushkov@9858 61 _java_stack_slots++;
apetushkov@9858 62 }
apetushkov@9858 63
apetushkov@9858 64 void JfrJavaArguments::Parameters::push_large(const JavaValue& value) {
apetushkov@9858 65 assert(_storage != NULL, "invariant");
apetushkov@9858 66 assert(is_large_value(value), "invariant");
apetushkov@9858 67 assert(_storage_index < SIZE, "invariant");
apetushkov@9858 68 _storage[_storage_index++] = value;
apetushkov@9858 69 _java_stack_slots += 2;
apetushkov@9858 70 }
apetushkov@9858 71
apetushkov@9858 72 void JfrJavaArguments::Parameters::set_receiver(const oop receiver) {
apetushkov@9858 73 assert(_storage != NULL, "invariant");
apetushkov@9858 74 assert(receiver != NULL, "invariant");
apetushkov@9858 75 JavaValue value(T_OBJECT);
apetushkov@9858 76 value.set_jobject((jobject)receiver);
apetushkov@9858 77 _storage[0] = value;
apetushkov@9858 78 }
apetushkov@9858 79
apetushkov@9858 80 void JfrJavaArguments::Parameters::set_receiver(Handle receiver) {
apetushkov@9858 81 set_receiver(receiver());
apetushkov@9858 82 }
apetushkov@9858 83
apetushkov@9858 84 oop JfrJavaArguments::Parameters::receiver() const {
apetushkov@9858 85 assert(has_receiver(), "invariant");
apetushkov@9858 86 assert(_storage[0].get_type() == T_OBJECT, "invariant");
apetushkov@9858 87 return (oop)_storage[0].get_jobject();
apetushkov@9858 88 }
apetushkov@9858 89
apetushkov@9858 90 bool JfrJavaArguments::Parameters::has_receiver() const {
apetushkov@9858 91 assert(_storage != NULL, "invariant");
apetushkov@9858 92 assert(_storage_index >= 1, "invariant");
apetushkov@9858 93 assert(_java_stack_slots >= 1, "invariant");
apetushkov@9858 94 return _storage[0].get_type() == T_OBJECT;
apetushkov@9858 95 }
apetushkov@9858 96
apetushkov@9858 97 void JfrJavaArguments::Parameters::push_oop(const oop obj) {
apetushkov@9858 98 JavaValue value(T_OBJECT);
apetushkov@9858 99 value.set_jobject((jobject)obj);
apetushkov@9858 100 push(value);
apetushkov@9858 101 }
apetushkov@9858 102
apetushkov@9858 103 void JfrJavaArguments::Parameters::push_oop(Handle h_obj) {
apetushkov@9858 104 push_oop(h_obj());
apetushkov@9858 105 }
apetushkov@9858 106
apetushkov@9858 107 void JfrJavaArguments::Parameters::push_jobject(jobject h) {
apetushkov@9858 108 JavaValue value(T_ADDRESS);
apetushkov@9858 109 value.set_jobject(h);
apetushkov@9858 110 push(value);
apetushkov@9858 111 }
apetushkov@9858 112
apetushkov@9858 113 void JfrJavaArguments::Parameters::push_jint(jint i) {
apetushkov@9858 114 JavaValue value(T_INT);
apetushkov@9858 115 value.set_jint(i);
apetushkov@9858 116 push(value);
apetushkov@9858 117 }
apetushkov@9858 118
apetushkov@9858 119 void JfrJavaArguments::Parameters::push_jfloat(jfloat f) {
apetushkov@9858 120 JavaValue value(T_FLOAT);
apetushkov@9858 121 value.set_jfloat(f);
apetushkov@9858 122 push(value);
apetushkov@9858 123 }
apetushkov@9858 124
apetushkov@9858 125 void JfrJavaArguments::Parameters::push_jdouble(jdouble d) {
apetushkov@9858 126 JavaValue value(T_DOUBLE);
apetushkov@9858 127 value.set_jdouble(d);
apetushkov@9858 128 push_large(value);
apetushkov@9858 129 }
apetushkov@9858 130
apetushkov@9858 131 void JfrJavaArguments::Parameters::push_jlong(jlong l) {
apetushkov@9858 132 JavaValue value(T_LONG);
apetushkov@9858 133 value.set_jlong(l);
apetushkov@9858 134 push_large(value);
apetushkov@9858 135 }
apetushkov@9858 136
apetushkov@9858 137 // including receiver (even if there is none)
apetushkov@9858 138 inline int JfrJavaArguments::Parameters::length() const {
apetushkov@9858 139 assert(_storage_index >= 1, "invariant");
apetushkov@9858 140 return _storage_index;
apetushkov@9858 141 }
apetushkov@9858 142
apetushkov@9858 143 inline int JfrJavaArguments::Parameters::java_stack_slots() const {
apetushkov@9858 144 return _java_stack_slots;
apetushkov@9858 145 }
apetushkov@9858 146
apetushkov@9858 147 const JavaValue& JfrJavaArguments::Parameters::values(int idx) const {
apetushkov@9858 148 assert(idx >= 0, "invariant");
apetushkov@9858 149 assert(idx < SIZE, "invariant");
apetushkov@9858 150 return _storage[idx];
apetushkov@9858 151 }
apetushkov@9858 152
apetushkov@9858 153 void JfrJavaArguments::Parameters::copy(JavaCallArguments& args, TRAPS) const {
apetushkov@9858 154 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 155 if (has_receiver()) {
apetushkov@9858 156 args.set_receiver(Handle(THREAD, receiver()));
apetushkov@9858 157 }
apetushkov@9858 158 for (int i = 1; i < length(); ++i) {
apetushkov@9858 159 switch(values(i).get_type()) {
apetushkov@9858 160 case T_BOOLEAN:
apetushkov@9858 161 case T_CHAR:
apetushkov@9858 162 case T_SHORT:
apetushkov@9858 163 case T_INT:
apetushkov@9858 164 args.push_int(values(i).get_jint());
apetushkov@9858 165 break;
apetushkov@9858 166 case T_LONG:
apetushkov@9858 167 args.push_long(values(i).get_jlong());
apetushkov@9858 168 break;
apetushkov@9858 169 case T_FLOAT:
apetushkov@9858 170 args.push_float(values(i).get_jfloat());
apetushkov@9858 171 break;
apetushkov@9858 172 case T_DOUBLE:
apetushkov@9858 173 args.push_double(values(i).get_jdouble());
apetushkov@9858 174 break;
apetushkov@9858 175 case T_OBJECT:
apetushkov@9858 176 args.push_oop(Handle(THREAD, (oop)values(i).get_jobject()));
apetushkov@9858 177 break;
apetushkov@9858 178 case T_ADDRESS:
apetushkov@9858 179 args.push_oop(Handle(THREAD, JNIHandles::resolve(values(i).get_jobject())));
apetushkov@9858 180 break;
apetushkov@9858 181 default:
apetushkov@9858 182 ShouldNotReachHere();
apetushkov@9858 183 }
apetushkov@9858 184 }
apetushkov@9858 185 }
apetushkov@9858 186
egahlin@9883 187 JfrJavaArguments::JfrJavaArguments(JavaValue* result) : _result(result), _klass(NULL), _name(NULL), _signature(NULL), _array_length(-1) {
apetushkov@9858 188 assert(result != NULL, "invariant");
apetushkov@9858 189 }
apetushkov@9858 190
apetushkov@9858 191 JfrJavaArguments::JfrJavaArguments(JavaValue* result, const char* klass_name, const char* name, const char* signature, TRAPS) :
apetushkov@9858 192 _result(result),
apetushkov@9858 193 _klass(NULL),
apetushkov@9858 194 _name(NULL),
apetushkov@9858 195 _signature(NULL),
egahlin@9883 196 _array_length(-1) {
apetushkov@9858 197 assert(result != NULL, "invariant");
apetushkov@9858 198 if (klass_name != NULL) {
apetushkov@9858 199 set_klass(klass_name, CHECK);
apetushkov@9858 200 }
apetushkov@9858 201 if (name != NULL) {
apetushkov@9858 202 set_name(name, CHECK);
apetushkov@9858 203 }
apetushkov@9858 204 if (signature != NULL) {
apetushkov@9858 205 set_signature(signature, THREAD);
apetushkov@9858 206 }
apetushkov@9858 207 }
apetushkov@9858 208
apetushkov@9858 209 JfrJavaArguments::JfrJavaArguments(JavaValue* result, const Klass* klass, const Symbol* name, const Symbol* signature) : _result(result),
apetushkov@9858 210 _klass(NULL),
apetushkov@9858 211 _name(NULL),
apetushkov@9858 212 _signature(NULL),
egahlin@9883 213 _array_length(-1) {
apetushkov@9858 214 assert(result != NULL, "invariant");
apetushkov@9858 215 if (klass != NULL) {
apetushkov@9858 216 set_klass(klass);
apetushkov@9858 217 }
apetushkov@9858 218 if (name != NULL) {
apetushkov@9858 219 set_name(name);
apetushkov@9858 220 }
apetushkov@9858 221 if (signature != NULL) {
apetushkov@9858 222 set_signature(signature);
apetushkov@9858 223 }
apetushkov@9858 224 }
apetushkov@9858 225
apetushkov@9858 226 Klass* JfrJavaArguments::klass() const {
apetushkov@9858 227 assert(_klass != NULL, "invariant");
apetushkov@9858 228 return const_cast<Klass*>(_klass);
apetushkov@9858 229 }
apetushkov@9858 230
apetushkov@9858 231 void JfrJavaArguments::set_klass(const char* klass_name, TRAPS) {
apetushkov@9858 232 assert(klass_name != NULL, "invariant");
apetushkov@9858 233 Symbol* const k_sym = resolve(klass_name, CHECK);
apetushkov@9858 234 assert(k_sym != NULL, "invariant");
apetushkov@9858 235 const Klass* const klass = resolve(k_sym, CHECK);
apetushkov@9858 236 set_klass(klass);
apetushkov@9858 237 }
apetushkov@9858 238
apetushkov@9858 239 void JfrJavaArguments::set_klass(const Klass* klass) {
apetushkov@9858 240 assert(klass != NULL, "invariant");
apetushkov@9858 241 _klass = klass;
apetushkov@9858 242 }
apetushkov@9858 243
apetushkov@9858 244 Symbol* JfrJavaArguments::name() const {
apetushkov@9858 245 assert(_name != NULL, "invariant");
apetushkov@9858 246 return const_cast<Symbol*>(_name);
apetushkov@9858 247 }
apetushkov@9858 248
apetushkov@9858 249 void JfrJavaArguments::set_name(const char* name, TRAPS) {
apetushkov@9858 250 assert(name != NULL, "invariant");
apetushkov@9858 251 const Symbol* const sym = resolve(name, CHECK);
apetushkov@9858 252 set_name(sym);
apetushkov@9858 253 }
apetushkov@9858 254
apetushkov@9858 255 void JfrJavaArguments::set_name(const Symbol* name) {
apetushkov@9858 256 assert(name != NULL, "invariant");
apetushkov@9858 257 _name = name;
apetushkov@9858 258 }
apetushkov@9858 259
apetushkov@9858 260 Symbol* JfrJavaArguments::signature() const {
apetushkov@9858 261 assert(_signature != NULL, "invariant");
apetushkov@9858 262 return const_cast<Symbol*>(_signature);
apetushkov@9858 263 }
apetushkov@9858 264
apetushkov@9858 265 void JfrJavaArguments::set_signature(const char* signature, TRAPS) {
apetushkov@9858 266 assert(signature != NULL, "invariant");
apetushkov@9858 267 const Symbol* const sym = resolve(signature, CHECK);
apetushkov@9858 268 set_signature(sym);
apetushkov@9858 269 }
apetushkov@9858 270
apetushkov@9858 271 void JfrJavaArguments::set_signature(const Symbol* signature) {
apetushkov@9858 272 assert(signature != NULL, "invariant");
apetushkov@9858 273 _signature = signature;
apetushkov@9858 274 }
apetushkov@9858 275
apetushkov@9858 276 int JfrJavaArguments::array_length() const {
apetushkov@9858 277 return _array_length;
apetushkov@9858 278 }
apetushkov@9858 279
apetushkov@9858 280 void JfrJavaArguments::set_array_length(int length) {
apetushkov@9858 281 assert(length >= 0, "invariant");
apetushkov@9858 282 _array_length = length;
apetushkov@9858 283 }
apetushkov@9858 284
apetushkov@9858 285 JavaValue* JfrJavaArguments::result() const {
apetushkov@9858 286 assert(_result != NULL, "invariant");
apetushkov@9858 287 return const_cast<JavaValue*>(_result);
apetushkov@9858 288 }
apetushkov@9858 289
apetushkov@9858 290 int JfrJavaArguments::length() const {
apetushkov@9858 291 return _params.length();
apetushkov@9858 292 }
apetushkov@9858 293
apetushkov@9858 294 bool JfrJavaArguments::has_receiver() const {
apetushkov@9858 295 return _params.has_receiver();
apetushkov@9858 296 }
apetushkov@9858 297
apetushkov@9858 298 oop JfrJavaArguments::receiver() const {
apetushkov@9858 299 return _params.receiver();
apetushkov@9858 300 }
apetushkov@9858 301
apetushkov@9858 302 void JfrJavaArguments::set_receiver(const oop receiver) {
apetushkov@9858 303 _params.set_receiver(receiver);
apetushkov@9858 304 }
apetushkov@9858 305
apetushkov@9858 306 void JfrJavaArguments::set_receiver(Handle receiver) {
apetushkov@9858 307 _params.set_receiver(receiver);
apetushkov@9858 308 }
apetushkov@9858 309
apetushkov@9858 310 void JfrJavaArguments::push_oop(const oop obj) {
apetushkov@9858 311 _params.push_oop(obj);
apetushkov@9858 312 }
apetushkov@9858 313
apetushkov@9858 314 void JfrJavaArguments::push_oop(Handle h_obj) {
apetushkov@9858 315 _params.push_oop(h_obj);
apetushkov@9858 316 }
apetushkov@9858 317
apetushkov@9858 318 void JfrJavaArguments::push_jobject(jobject h) {
apetushkov@9858 319 _params.push_jobject(h);
apetushkov@9858 320 }
apetushkov@9858 321
apetushkov@9858 322 void JfrJavaArguments::push_int(jint i) {
apetushkov@9858 323 _params.push_jint(i);
apetushkov@9858 324 }
apetushkov@9858 325
apetushkov@9858 326 void JfrJavaArguments::push_float(jfloat f) {
apetushkov@9858 327 _params.push_jfloat(f);
apetushkov@9858 328 }
apetushkov@9858 329
apetushkov@9858 330 void JfrJavaArguments::push_double(jdouble d) {
apetushkov@9858 331 _params.push_jdouble(d);
apetushkov@9858 332 }
apetushkov@9858 333
apetushkov@9858 334 void JfrJavaArguments::push_long(jlong l) {
apetushkov@9858 335 _params.push_jlong(l);
apetushkov@9858 336 }
apetushkov@9858 337
apetushkov@9858 338 const JavaValue& JfrJavaArguments::param(int idx) const {
apetushkov@9858 339 return _params.values(idx);
apetushkov@9858 340 }
apetushkov@9858 341
apetushkov@9858 342 int JfrJavaArguments::java_call_arg_slots() const {
apetushkov@9858 343 return _params.java_stack_slots();
apetushkov@9858 344 }
apetushkov@9858 345
apetushkov@9858 346 void JfrJavaArguments::copy(JavaCallArguments& args, TRAPS) {
apetushkov@9858 347 _params.copy(args, THREAD);
apetushkov@9858 348 }
apetushkov@9858 349
apetushkov@9858 350 void JfrJavaCall::call_static(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 351 assert(args != NULL, "invariant");
apetushkov@9858 352 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 353 ResourceMark rm(THREAD);
apetushkov@9858 354 HandleMark hm(THREAD);
apetushkov@9858 355 JavaCallArguments jcas(args->java_call_arg_slots());
apetushkov@9858 356 args->copy(jcas, CHECK);
apetushkov@9858 357 JavaCalls::call_static(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);
apetushkov@9858 358 }
apetushkov@9858 359
apetushkov@9858 360 void JfrJavaCall::call_special(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 361 assert(args != NULL, "invariant");
apetushkov@9858 362 assert(args->has_receiver(), "invariant");
apetushkov@9858 363 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 364 ResourceMark rm(THREAD);
apetushkov@9858 365 HandleMark hm(THREAD);
apetushkov@9858 366 JavaCallArguments jcas(args->java_call_arg_slots());
apetushkov@9858 367 args->copy(jcas, CHECK);
apetushkov@9858 368 JavaCalls::call_special(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);
apetushkov@9858 369 }
apetushkov@9858 370
apetushkov@9858 371 void JfrJavaCall::call_virtual(JfrJavaArguments* args, TRAPS) {
apetushkov@9858 372 assert(args != NULL, "invariant");
apetushkov@9858 373 assert(args->has_receiver(), "invariant");
apetushkov@9858 374 DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
apetushkov@9858 375 ResourceMark rm(THREAD);
apetushkov@9858 376 HandleMark hm(THREAD);
apetushkov@9858 377 JavaCallArguments jcas(args->java_call_arg_slots());
apetushkov@9858 378 args->copy(jcas, CHECK);
apetushkov@9858 379 JavaCalls::call_virtual(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);
apetushkov@9858 380 }

mercurial