Path: blob/master/src/hotspot/share/jfr/jni/jfrJavaCall.cpp
41149 views
/*1* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/symbolTable.hpp"26#include "classfile/systemDictionary.hpp"27#include "jfr/jni/jfrJavaCall.hpp"28#include "jfr/jni/jfrJavaSupport.hpp"29#include "memory/resourceArea.hpp"30#include "runtime/handles.inline.hpp"31#include "runtime/javaCalls.hpp"32#include "utilities/globalDefinitions.hpp"3334#ifdef ASSERT35static bool is_large_value(const JavaValue& value) {36return value.get_type() == T_LONG || value.get_type() == T_DOUBLE;37}38#endif // ASSERT3940static Symbol* resolve(const char* str) {41assert(str != NULL, "invariant");42return SymbolTable::new_symbol(str);43}4445static Klass* resolve(Symbol* k_sym, TRAPS) {46assert(k_sym != NULL, "invariant");47return SystemDictionary::resolve_or_fail(k_sym, true, THREAD);48}4950JfrJavaArguments::Parameters::Parameters() : _storage_index(0), _java_stack_slots(0) {51JavaValue value(T_VOID);52push(value);53}5455void JfrJavaArguments::Parameters::push(const JavaValue& value) {56assert(_storage != NULL, "invariant");57assert(!is_large_value(value), "invariant");58assert(_storage_index < SIZE, "invariant");59_storage[_storage_index++] = value;60_java_stack_slots++;61}6263void JfrJavaArguments::Parameters::push_large(const JavaValue& value) {64assert(_storage != NULL, "invariant");65assert(is_large_value(value), "invariant");66assert(_storage_index < SIZE, "invariant");67_storage[_storage_index++] = value;68_java_stack_slots += 2;69}7071void JfrJavaArguments::Parameters::set_receiver(const oop receiver) {72assert(_storage != NULL, "invariant");73assert(receiver != NULL, "invariant");74JavaValue value(T_OBJECT);75value.set_oop(receiver);76_storage[0] = value;77}7879void JfrJavaArguments::Parameters::set_receiver(Handle receiver) {80set_receiver(receiver());81}8283oop JfrJavaArguments::Parameters::receiver() const {84assert(has_receiver(), "invariant");85assert(_storage[0].get_type() == T_OBJECT, "invariant");86return _storage[0].get_oop();87}8889bool JfrJavaArguments::Parameters::has_receiver() const {90assert(_storage != NULL, "invariant");91assert(_storage_index >= 1, "invariant");92assert(_java_stack_slots >= 1, "invariant");93return _storage[0].get_type() == T_OBJECT;94}9596void JfrJavaArguments::Parameters::push_oop(const oop obj) {97JavaValue value(T_OBJECT);98value.set_oop(obj);99push(value);100}101102void JfrJavaArguments::Parameters::push_oop(Handle h_obj) {103push_oop(h_obj());104}105106void JfrJavaArguments::Parameters::push_jobject(jobject h) {107JavaValue value(T_ADDRESS);108value.set_jobject(h);109push(value);110}111112void JfrJavaArguments::Parameters::push_jint(jint i) {113JavaValue value(T_INT);114value.set_jint(i);115push(value);116}117118void JfrJavaArguments::Parameters::push_jfloat(jfloat f) {119JavaValue value(T_FLOAT);120value.set_jfloat(f);121push(value);122}123124void JfrJavaArguments::Parameters::push_jdouble(jdouble d) {125JavaValue value(T_DOUBLE);126value.set_jdouble(d);127push_large(value);128}129130void JfrJavaArguments::Parameters::push_jlong(jlong l) {131JavaValue value(T_LONG);132value.set_jlong(l);133push_large(value);134}135136// including receiver (even if there is none)137inline int JfrJavaArguments::Parameters::length() const {138assert(_storage_index >= 1, "invariant");139return _storage_index;140}141142inline int JfrJavaArguments::Parameters::java_stack_slots() const {143return _java_stack_slots;144}145146const JavaValue& JfrJavaArguments::Parameters::values(int idx) const {147assert(idx >= 0, "invariant");148assert(idx < SIZE, "invariant");149return _storage[idx];150}151152void JfrJavaArguments::Parameters::copy(JavaCallArguments& args, TRAPS) const {153DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));154if (has_receiver()) {155args.set_receiver(Handle(THREAD, receiver()));156}157for (int i = 1; i < length(); ++i) {158switch(values(i).get_type()) {159case T_BOOLEAN:160case T_CHAR:161case T_SHORT:162case T_INT:163args.push_int(values(i).get_jint());164break;165case T_LONG:166args.push_long(values(i).get_jlong());167break;168case T_FLOAT:169args.push_float(values(i).get_jfloat());170break;171case T_DOUBLE:172args.push_double(values(i).get_jdouble());173break;174case T_OBJECT:175args.push_oop(Handle(THREAD, values(i).get_oop()));176break;177case T_ADDRESS:178args.push_jobject(values(i).get_jobject());179break;180default:181ShouldNotReachHere();182}183}184}185186JfrJavaArguments::JfrJavaArguments(JavaValue* result) : _result(result), _klass(NULL), _name(NULL), _signature(NULL), _array_length(-1) {187assert(result != NULL, "invariant");188}189190JfrJavaArguments::JfrJavaArguments(JavaValue* result, const char* klass_name, const char* name, const char* signature, TRAPS) :191_result(result),192_klass(NULL),193_name(NULL),194_signature(NULL),195_array_length(-1) {196assert(result != NULL, "invariant");197if (klass_name != NULL) {198set_klass(klass_name, CHECK);199}200if (name != NULL) {201set_name(name);202}203if (signature != NULL) {204set_signature(signature);205}206}207208JfrJavaArguments::JfrJavaArguments(JavaValue* result, const Klass* klass, const Symbol* name, const Symbol* signature) : _result(result),209_klass(NULL),210_name(NULL),211_signature(NULL),212_array_length(-1) {213assert(result != NULL, "invariant");214if (klass != NULL) {215set_klass(klass);216}217if (name != NULL) {218set_name(name);219}220if (signature != NULL) {221set_signature(signature);222}223}224225Klass* JfrJavaArguments::klass() const {226assert(_klass != NULL, "invariant");227return const_cast<Klass*>(_klass);228}229230void JfrJavaArguments::set_klass(const char* klass_name, TRAPS) {231assert(klass_name != NULL, "invariant");232Symbol* const k_sym = resolve(klass_name);233assert(k_sym != NULL, "invariant");234const Klass* const klass = resolve(k_sym, CHECK);235set_klass(klass);236}237238void JfrJavaArguments::set_klass(const Klass* klass) {239assert(klass != NULL, "invariant");240_klass = klass;241}242243Symbol* JfrJavaArguments::name() const {244assert(_name != NULL, "invariant");245return const_cast<Symbol*>(_name);246}247248void JfrJavaArguments::set_name(const char* name) {249assert(name != NULL, "invariant");250const Symbol* const sym = resolve(name);251set_name(sym);252}253254void JfrJavaArguments::set_name(const Symbol* name) {255assert(name != NULL, "invariant");256_name = name;257}258259Symbol* JfrJavaArguments::signature() const {260assert(_signature != NULL, "invariant");261return const_cast<Symbol*>(_signature);262}263264void JfrJavaArguments::set_signature(const char* signature) {265assert(signature != NULL, "invariant");266const Symbol* const sym = resolve(signature);267set_signature(sym);268}269270void JfrJavaArguments::set_signature(const Symbol* signature) {271assert(signature != NULL, "invariant");272_signature = signature;273}274275int JfrJavaArguments::array_length() const {276return _array_length;277}278279void JfrJavaArguments::set_array_length(int length) {280assert(length >= 0, "invariant");281_array_length = length;282}283284JavaValue* JfrJavaArguments::result() const {285assert(_result != NULL, "invariant");286return const_cast<JavaValue*>(_result);287}288289int JfrJavaArguments::length() const {290return _params.length();291}292293bool JfrJavaArguments::has_receiver() const {294return _params.has_receiver();295}296297oop JfrJavaArguments::receiver() const {298return _params.receiver();299}300301void JfrJavaArguments::set_receiver(const oop receiver) {302_params.set_receiver(receiver);303}304305void JfrJavaArguments::set_receiver(Handle receiver) {306_params.set_receiver(receiver);307}308309void JfrJavaArguments::push_oop(const oop obj) {310_params.push_oop(obj);311}312313void JfrJavaArguments::push_oop(Handle h_obj) {314_params.push_oop(h_obj);315}316317void JfrJavaArguments::push_jobject(jobject h) {318_params.push_jobject(h);319}320321void JfrJavaArguments::push_int(jint i) {322_params.push_jint(i);323}324325void JfrJavaArguments::push_float(jfloat f) {326_params.push_jfloat(f);327}328329void JfrJavaArguments::push_double(jdouble d) {330_params.push_jdouble(d);331}332333void JfrJavaArguments::push_long(jlong l) {334_params.push_jlong(l);335}336337const JavaValue& JfrJavaArguments::param(int idx) const {338return _params.values(idx);339}340341int JfrJavaArguments::java_call_arg_slots() const {342return _params.java_stack_slots();343}344345void JfrJavaArguments::copy(JavaCallArguments& args, TRAPS) {346_params.copy(args, THREAD);347}348349void JfrJavaCall::call_static(JfrJavaArguments* args, TRAPS) {350assert(args != NULL, "invariant");351DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));352ResourceMark rm(THREAD);353HandleMark hm(THREAD);354JavaCallArguments jcas(args->java_call_arg_slots());355args->copy(jcas, CHECK);356JavaCalls::call_static(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);357}358359void JfrJavaCall::call_special(JfrJavaArguments* args, TRAPS) {360assert(args != NULL, "invariant");361assert(args->has_receiver(), "invariant");362DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));363ResourceMark rm(THREAD);364HandleMark hm(THREAD);365JavaCallArguments jcas(args->java_call_arg_slots());366args->copy(jcas, CHECK);367JavaCalls::call_special(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);368}369370void JfrJavaCall::call_virtual(JfrJavaArguments* args, TRAPS) {371assert(args != NULL, "invariant");372assert(args->has_receiver(), "invariant");373DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));374ResourceMark rm(THREAD);375HandleMark hm(THREAD);376JavaCallArguments jcas(args->java_call_arg_slots());377args->copy(jcas, CHECK);378JavaCalls::call_virtual(args->result(), args->klass(), args->name(), args->signature(), &jcas, THREAD);379}380381382