src/hotspot/share/jfr/jni/jfrJavaCall.cpp
changeset 50113 caf115bb98ad
child 54847 59ea39bb2809
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2017, 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  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "classfile/symbolTable.hpp"
       
    27 #include "classfile/systemDictionary.hpp"
       
    28 #include "jfr/jni/jfrJavaCall.hpp"
       
    29 #include "jfr/jni/jfrJavaSupport.hpp"
       
    30 #include "memory/resourceArea.hpp"
       
    31 #include "runtime/handles.inline.hpp"
       
    32 #include "runtime/javaCalls.hpp"
       
    33 #include "utilities/globalDefinitions.hpp"
       
    34 
       
    35 #ifdef ASSERT
       
    36 static bool is_large_value(const JavaValue& value) {
       
    37   return value.get_type() == T_LONG || value.get_type() == T_DOUBLE;
       
    38 }
       
    39 #endif // ASSERT
       
    40 
       
    41 static Symbol* resolve(const char* str, TRAPS) {
       
    42   assert(str != NULL, "invariant");
       
    43   return SymbolTable::lookup(str, (int)strlen(str), THREAD);
       
    44 }
       
    45 
       
    46 static Klass* resolve(Symbol* k_sym, TRAPS) {
       
    47   assert(k_sym != NULL, "invariant");
       
    48   return SystemDictionary::resolve_or_fail(k_sym, true, THREAD);
       
    49 }
       
    50 
       
    51 JfrJavaArguments::Parameters::Parameters() : _storage_index(0), _java_stack_slots(0) {
       
    52   JavaValue value(T_VOID);
       
    53   push(value);
       
    54 }
       
    55 
       
    56 void JfrJavaArguments::Parameters::push(const JavaValue& value) {
       
    57   assert(_storage != NULL, "invariant");
       
    58   assert(!is_large_value(value), "invariant");
       
    59   assert(_storage_index < SIZE, "invariant");
       
    60   _storage[_storage_index++] = value;
       
    61   _java_stack_slots++;
       
    62 }
       
    63 
       
    64 void JfrJavaArguments::Parameters::push_large(const JavaValue& value) {
       
    65   assert(_storage != NULL, "invariant");
       
    66   assert(is_large_value(value), "invariant");
       
    67   assert(_storage_index < SIZE, "invariant");
       
    68   _storage[_storage_index++] = value;
       
    69   _java_stack_slots += 2;
       
    70 }
       
    71 
       
    72 void JfrJavaArguments::Parameters::set_receiver(const oop receiver) {
       
    73   assert(_storage != NULL, "invariant");
       
    74   assert(receiver != NULL, "invariant");
       
    75   JavaValue value(T_OBJECT);
       
    76   value.set_jobject((jobject)receiver);
       
    77   _storage[0] = value;
       
    78 }
       
    79 
       
    80 void JfrJavaArguments::Parameters::set_receiver(Handle receiver) {
       
    81   set_receiver(receiver());
       
    82 }
       
    83 
       
    84 oop JfrJavaArguments::Parameters::receiver() const {
       
    85   assert(has_receiver(), "invariant");
       
    86   assert(_storage[0].get_type() == T_OBJECT, "invariant");
       
    87   return (oop)_storage[0].get_jobject();
       
    88 }
       
    89 
       
    90 bool JfrJavaArguments::Parameters::has_receiver() const {
       
    91   assert(_storage != NULL, "invariant");
       
    92   assert(_storage_index >= 1, "invariant");
       
    93   assert(_java_stack_slots >= 1, "invariant");
       
    94   return _storage[0].get_type() == T_OBJECT;
       
    95 }
       
    96 
       
    97 void JfrJavaArguments::Parameters::push_oop(const oop obj) {
       
    98   JavaValue value(T_OBJECT);
       
    99   value.set_jobject((jobject)obj);
       
   100   push(value);
       
   101 }
       
   102 
       
   103 void JfrJavaArguments::Parameters::push_oop(Handle h_obj) {
       
   104   push_oop(h_obj());
       
   105 }
       
   106 
       
   107 void JfrJavaArguments::Parameters::push_jobject(jobject h) {
       
   108   JavaValue value(T_ADDRESS);
       
   109   value.set_jobject(h);
       
   110   push(value);
       
   111 }
       
   112 
       
   113 void JfrJavaArguments::Parameters::push_jint(jint i) {
       
   114   JavaValue value(T_INT);
       
   115   value.set_jint(i);
       
   116   push(value);
       
   117 }
       
   118 
       
   119 void JfrJavaArguments::Parameters::push_jfloat(jfloat f) {
       
   120   JavaValue value(T_FLOAT);
       
   121   value.set_jfloat(f);
       
   122   push(value);
       
   123 }
       
   124 
       
   125 void JfrJavaArguments::Parameters::push_jdouble(jdouble d) {
       
   126   JavaValue value(T_DOUBLE);
       
   127   value.set_jdouble(d);
       
   128   push_large(value);
       
   129 }
       
   130 
       
   131 void JfrJavaArguments::Parameters::push_jlong(jlong l) {
       
   132   JavaValue value(T_LONG);
       
   133   value.set_jlong(l);
       
   134   push_large(value);
       
   135 }
       
   136 
       
   137 // including receiver (even if there is none)
       
   138 inline int JfrJavaArguments::Parameters::length() const {
       
   139   assert(_storage_index >= 1, "invariant");
       
   140   return _storage_index;
       
   141 }
       
   142 
       
   143 inline int JfrJavaArguments::Parameters::java_stack_slots() const {
       
   144   return _java_stack_slots;
       
   145 }
       
   146 
       
   147 const JavaValue& JfrJavaArguments::Parameters::values(int idx) const {
       
   148   assert(idx >= 0, "invariant");
       
   149   assert(idx < SIZE, "invariant");
       
   150   return _storage[idx];
       
   151 }
       
   152 
       
   153 void JfrJavaArguments::Parameters::copy(JavaCallArguments& args, TRAPS) const {
       
   154   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   155   if (has_receiver()) {
       
   156     args.set_receiver(Handle(THREAD, receiver()));
       
   157   }
       
   158   for (int i = 1; i < length(); ++i) {
       
   159     switch(values(i).get_type()) {
       
   160       case T_BOOLEAN:
       
   161       case T_CHAR:
       
   162       case T_SHORT:
       
   163       case T_INT:
       
   164         args.push_int(values(i).get_jint());
       
   165         break;
       
   166       case T_LONG:
       
   167         args.push_long(values(i).get_jlong());
       
   168         break;
       
   169       case T_FLOAT:
       
   170         args.push_float(values(i).get_jfloat());
       
   171         break;
       
   172       case T_DOUBLE:
       
   173         args.push_double(values(i).get_jdouble());
       
   174         break;
       
   175       case T_OBJECT:
       
   176         args.push_oop(Handle(THREAD, (oop)values(i).get_jobject()));
       
   177         break;
       
   178       case T_ADDRESS:
       
   179         args.push_jobject(values(i).get_jobject());
       
   180         break;
       
   181       default:
       
   182         ShouldNotReachHere();
       
   183     }
       
   184   }
       
   185 }
       
   186 
       
   187 JfrJavaArguments::JfrJavaArguments(JavaValue* result) : _result(result), _klass(NULL), _name(NULL), _signature(NULL), _array_length(0) {
       
   188   assert(result != NULL, "invariant");
       
   189 }
       
   190 
       
   191 JfrJavaArguments::JfrJavaArguments(JavaValue* result, const char* klass_name, const char* name, const char* signature, TRAPS) :
       
   192   _result(result),
       
   193   _klass(NULL),
       
   194   _name(NULL),
       
   195   _signature(NULL),
       
   196   _array_length(0) {
       
   197   assert(result != NULL, "invariant");
       
   198   if (klass_name != NULL) {
       
   199     set_klass(klass_name, CHECK);
       
   200   }
       
   201   if (name != NULL) {
       
   202     set_name(name, CHECK);
       
   203   }
       
   204   if (signature != NULL) {
       
   205     set_signature(signature, THREAD);
       
   206   }
       
   207 }
       
   208 
       
   209 JfrJavaArguments::JfrJavaArguments(JavaValue* result, const Klass* klass, const Symbol* name, const Symbol* signature) : _result(result),
       
   210   _klass(NULL),
       
   211   _name(NULL),
       
   212   _signature(NULL),
       
   213   _array_length(0) {
       
   214   assert(result != NULL, "invariant");
       
   215   if (klass != NULL) {
       
   216     set_klass(klass);
       
   217   }
       
   218   if (name != NULL) {
       
   219     set_name(name);
       
   220   }
       
   221   if (signature != NULL) {
       
   222     set_signature(signature);
       
   223   }
       
   224 }
       
   225 
       
   226 Klass* JfrJavaArguments::klass() const {
       
   227   assert(_klass != NULL, "invariant");
       
   228   return const_cast<Klass*>(_klass);
       
   229 }
       
   230 
       
   231 void JfrJavaArguments::set_klass(const char* klass_name, TRAPS) {
       
   232   assert(klass_name != NULL, "invariant");
       
   233   Symbol* const k_sym = resolve(klass_name, CHECK);
       
   234   assert(k_sym != NULL, "invariant");
       
   235   const Klass* const klass = resolve(k_sym, CHECK);
       
   236   set_klass(klass);
       
   237 }
       
   238 
       
   239 void JfrJavaArguments::set_klass(const Klass* klass) {
       
   240   assert(klass != NULL, "invariant");
       
   241   _klass = klass;
       
   242 }
       
   243 
       
   244 Symbol* JfrJavaArguments::name() const {
       
   245   assert(_name != NULL, "invariant");
       
   246   return const_cast<Symbol*>(_name);
       
   247 }
       
   248 
       
   249 void JfrJavaArguments::set_name(const char* name, TRAPS) {
       
   250   assert(name != NULL, "invariant");
       
   251   const Symbol* const sym = resolve(name, CHECK);
       
   252   set_name(sym);
       
   253 }
       
   254 
       
   255 void JfrJavaArguments::set_name(const Symbol* name) {
       
   256   assert(name != NULL, "invariant");
       
   257   _name = name;
       
   258 }
       
   259 
       
   260 Symbol* JfrJavaArguments::signature() const {
       
   261   assert(_signature != NULL, "invariant");
       
   262   return const_cast<Symbol*>(_signature);
       
   263 }
       
   264 
       
   265 void JfrJavaArguments::set_signature(const char* signature, TRAPS) {
       
   266   assert(signature != NULL, "invariant");
       
   267   const Symbol* const sym = resolve(signature, CHECK);
       
   268   set_signature(sym);
       
   269 }
       
   270 
       
   271 void JfrJavaArguments::set_signature(const Symbol* signature) {
       
   272   assert(signature != NULL, "invariant");
       
   273   _signature = signature;
       
   274 }
       
   275 
       
   276 int JfrJavaArguments::array_length() const {
       
   277   return _array_length;
       
   278 }
       
   279 
       
   280 void JfrJavaArguments::set_array_length(int length) {
       
   281   assert(length >= 0, "invariant");
       
   282   _array_length = length;
       
   283 }
       
   284 
       
   285 JavaValue* JfrJavaArguments::result() const {
       
   286   assert(_result != NULL, "invariant");
       
   287   return const_cast<JavaValue*>(_result);
       
   288 }
       
   289 
       
   290 int JfrJavaArguments::length() const {
       
   291   return _params.length();
       
   292 }
       
   293 
       
   294 bool JfrJavaArguments::has_receiver() const {
       
   295   return _params.has_receiver();
       
   296 }
       
   297 
       
   298 oop JfrJavaArguments::receiver() const {
       
   299   return _params.receiver();
       
   300 }
       
   301 
       
   302 void JfrJavaArguments::set_receiver(const oop receiver) {
       
   303   _params.set_receiver(receiver);
       
   304 }
       
   305 
       
   306 void JfrJavaArguments::set_receiver(Handle receiver) {
       
   307   _params.set_receiver(receiver);
       
   308 }
       
   309 
       
   310 void JfrJavaArguments::push_oop(const oop obj) {
       
   311   _params.push_oop(obj);
       
   312 }
       
   313 
       
   314 void JfrJavaArguments::push_oop(Handle h_obj) {
       
   315   _params.push_oop(h_obj);
       
   316 }
       
   317 
       
   318 void JfrJavaArguments::push_jobject(jobject h) {
       
   319   _params.push_jobject(h);
       
   320 }
       
   321 
       
   322 void JfrJavaArguments::push_int(jint i) {
       
   323   _params.push_jint(i);
       
   324 }
       
   325 
       
   326 void JfrJavaArguments::push_float(jfloat f) {
       
   327   _params.push_jfloat(f);
       
   328 }
       
   329 
       
   330 void JfrJavaArguments::push_double(jdouble d) {
       
   331   _params.push_jdouble(d);
       
   332 }
       
   333 
       
   334 void JfrJavaArguments::push_long(jlong l) {
       
   335   _params.push_jlong(l);
       
   336 }
       
   337 
       
   338 const JavaValue& JfrJavaArguments::param(int idx) const {
       
   339   return _params.values(idx);
       
   340 }
       
   341 
       
   342 int JfrJavaArguments::java_call_arg_slots() const {
       
   343   return _params.java_stack_slots();
       
   344 }
       
   345 
       
   346 void JfrJavaArguments::copy(JavaCallArguments& args, TRAPS) {
       
   347   _params.copy(args, THREAD);
       
   348 }
       
   349 
       
   350 void JfrJavaCall::call_static(JfrJavaArguments* args, TRAPS) {
       
   351   assert(args != NULL, "invariant");
       
   352   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   353   ResourceMark rm(THREAD);
       
   354   HandleMark hm(THREAD);
       
   355   JavaCallArguments jcas(args->java_call_arg_slots());
       
   356   args->copy(jcas, CHECK);
       
   357   JavaCalls::call_static(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);
       
   358 }
       
   359 
       
   360 void JfrJavaCall::call_special(JfrJavaArguments* args, TRAPS) {
       
   361   assert(args != NULL, "invariant");
       
   362   assert(args->has_receiver(), "invariant");
       
   363   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   364   ResourceMark rm(THREAD);
       
   365   HandleMark hm(THREAD);
       
   366   JavaCallArguments jcas(args->java_call_arg_slots());
       
   367   args->copy(jcas, CHECK);
       
   368   JavaCalls::call_special(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);
       
   369 }
       
   370 
       
   371 void JfrJavaCall::call_virtual(JfrJavaArguments* args, TRAPS) {
       
   372   assert(args != NULL, "invariant");
       
   373   assert(args->has_receiver(), "invariant");
       
   374   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   375   ResourceMark rm(THREAD);
       
   376   HandleMark hm(THREAD);
       
   377   JavaCallArguments jcas(args->java_call_arg_slots());
       
   378   args->copy(jcas, CHECK);
       
   379   JavaCalls::call_virtual(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);
       
   380 }