--- old/src/share/vm/opto/library_call.cpp 2019-02-15 19:02:37.302837717 +0300 +++ new/src/share/vm/opto/library_call.cpp 2019-02-15 19:02:37.206841071 +0300 @@ -27,6 +27,7 @@ #include "classfile/vmSymbols.hpp" #include "compiler/compileBroker.hpp" #include "compiler/compileLog.hpp" +#include "jfr/support/jfrIntrinsics.hpp" #include "oops/objArrayKlass.hpp" #include "opto/addnode.hpp" #include "opto/callGenerator.hpp" @@ -40,7 +41,7 @@ #include "opto/subnode.hpp" #include "prims/nativeLookup.hpp" #include "runtime/sharedRuntime.hpp" -#include "trace/traceMacros.hpp" +#include "utilities/macros.hpp" class LibraryIntrinsic : public InlineCallGenerator { // Extend the set of intrinsics known to the runtime: @@ -236,9 +237,9 @@ bool inline_unsafe_allocate(); bool inline_unsafe_copyMemory(); bool inline_native_currentThread(); -#ifdef TRACE_HAVE_INTRINSICS +#ifdef JFR_HAVE_INTRINSICS bool inline_native_classID(); - bool inline_native_threadID(); + bool inline_native_getEventWriter(); #endif bool inline_native_time_funcs(address method, const char* funcName); bool inline_native_isInterrupted(); @@ -879,10 +880,10 @@ case vmIntrinsics::_currentThread: return inline_native_currentThread(); case vmIntrinsics::_isInterrupted: return inline_native_isInterrupted(); -#ifdef TRACE_HAVE_INTRINSICS - case vmIntrinsics::_classID: return inline_native_classID(); - case vmIntrinsics::_threadID: return inline_native_threadID(); - case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime"); +#ifdef JFR_HAVE_INTRINSICS + case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, JFR_TIME_FUNCTION), "counterTime"); + case vmIntrinsics::_getClassId: return inline_native_classID(); + case vmIntrinsics::_getEventWriter: return inline_native_getEventWriter(); #endif case vmIntrinsics::_currentTimeMillis: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis"); case vmIntrinsics::_nanoTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeNanos), "nanoTime"); @@ -3265,51 +3266,76 @@ return true; } -#ifdef TRACE_HAVE_INTRINSICS +#ifdef JFR_HAVE_INTRINSICS /* * oop -> myklass * myklass->trace_id |= USED * return myklass->trace_id & ~0x3 */ bool LibraryCallKit::inline_native_classID() { - null_check_receiver(); // null-check, then ignore - Node* cls = null_check(argument(1), T_OBJECT); + Node* cls = null_check(argument(0), T_OBJECT); Node* kls = load_klass_from_mirror(cls, false, NULL, 0); kls = null_check(kls, T_OBJECT); - ByteSize offset = TRACE_ID_OFFSET; + + ByteSize offset = KLASS_TRACE_ID_OFFSET; Node* insp = basic_plus_adr(kls, in_bytes(offset)); Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered); - Node* bits = longcon(~0x03l); // ignore bit 0 & 1 - Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits)); + Node* clsused = longcon(0x01l); // set the class bit Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused)); - const TypePtr *adr_type = _gvn.type(insp)->isa_ptr(); store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered); - set_result(andl); + +#ifdef TRACE_ID_META_BITS + Node* mbits = longcon(~TRACE_ID_META_BITS); + tvalue = _gvn.transform(new (C) AndLNode(tvalue, mbits)); +#endif +#ifdef TRACE_ID_SHIFT + Node* cbits = intcon(TRACE_ID_SHIFT); + tvalue = _gvn.transform(new (C) URShiftLNode(tvalue, cbits)); +#endif + + set_result(tvalue); return true; } -bool LibraryCallKit::inline_native_threadID() { - Node* tls_ptr = NULL; - Node* cur_thr = generate_current_thread(tls_ptr); - Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset())); - Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered); - p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::thread_id_offset())); - - Node* threadid = NULL; - size_t thread_id_size = OSThread::thread_id_size(); - if (thread_id_size == (size_t) BytesPerLong) { - threadid = ConvL2I(make_load(control(), p, TypeLong::LONG, T_LONG, MemNode::unordered)); - } else if (thread_id_size == (size_t) BytesPerInt) { - threadid = make_load(control(), p, TypeInt::INT, T_INT, MemNode::unordered); - } else { - ShouldNotReachHere(); - } - set_result(threadid); +bool LibraryCallKit::inline_native_getEventWriter() { + Node* tls_ptr = _gvn.transform(new (C) ThreadLocalNode()); + + Node* jobj_ptr = basic_plus_adr(top(), tls_ptr, + in_bytes(THREAD_LOCAL_WRITER_OFFSET_JFR) + ); + + Node* jobj = make_load(control(), jobj_ptr, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered); + + Node* jobj_cmp_null = _gvn.transform( new (C) CmpPNode(jobj, null()) ); + Node* test_jobj_eq_null = _gvn.transform( new (C) BoolNode(jobj_cmp_null, BoolTest::eq) ); + + IfNode* iff_jobj_null = + create_and_map_if(control(), test_jobj_eq_null, PROB_MIN, COUNT_UNKNOWN); + + enum { _normal_path = 1, + _null_path = 2, + PATH_LIMIT }; + + RegionNode* result_rgn = new (C) RegionNode(PATH_LIMIT); + PhiNode* result_val = new (C) PhiNode(result_rgn, TypePtr::BOTTOM); + + Node* jobj_is_null = _gvn.transform(new (C) IfTrueNode(iff_jobj_null)); + result_rgn->init_req(_null_path, jobj_is_null); + result_val->init_req(_null_path, null()); + + Node* jobj_is_not_null = _gvn.transform(new (C) IfFalseNode(iff_jobj_null)); + result_rgn->init_req(_normal_path, jobj_is_not_null); + + Node* res = make_load(jobj_is_not_null, jobj, TypeInstPtr::NOTNULL, T_OBJECT, MemNode::unordered); + result_val->init_req(_normal_path, res); + + set_result(result_rgn, result_val); + return true; } -#endif +#endif // JFR_HAVE_INTRINSICS //------------------------inline_native_time_funcs-------------- // inline code for System.currentTimeMillis() and System.nanoTime()