8166806: Add intrinsic support for writer used in event based tracing
Reviewed-by: kvn, egahlin
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri Oct 21 12:30:12 2016 +0300
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Fri Oct 21 16:20:18 2016 +0200
@@ -223,6 +223,7 @@
case vmIntrinsics::_putCharStringU:
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
+ case vmIntrinsics::_getBufferWriter:
#if defined(_LP64) || !defined(TRACE_ID_CLASS_SHIFT)
case vmIntrinsics::_getClassId:
#endif
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Oct 21 12:30:12 2016 +0300
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Fri Oct 21 16:20:18 2016 +0200
@@ -3120,6 +3120,22 @@
__ move(id, rlock_result(x));
}
+
+void LIRGenerator::do_getBufferWriter(Intrinsic* x) {
+ LabelObj* L_end = new LabelObj();
+
+ LIR_Address* jobj_addr = new LIR_Address(getThreadPointer(),
+ in_bytes(TRACE_THREAD_DATA_WRITER_OFFSET),
+ T_OBJECT);
+ LIR_Opr result = rlock_result(x);
+ __ move_wide(jobj_addr, result);
+ __ cmp(lir_cond_equal, result, LIR_OprFact::oopConst(NULL));
+ __ branch(lir_cond_equal, T_OBJECT, L_end->label());
+ __ move_wide(new LIR_Address(result, T_OBJECT), result);
+
+ __ branch_destination(L_end->label());
+}
+
#endif
@@ -3151,6 +3167,9 @@
case vmIntrinsics::_getClassId:
do_ClassIDIntrinsic(x);
break;
+ case vmIntrinsics::_getBufferWriter:
+ do_getBufferWriter(x);
+ break;
case vmIntrinsics::_counterTime:
do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), x);
break;
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Fri Oct 21 12:30:12 2016 +0300
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Fri Oct 21 16:20:18 2016 +0200
@@ -441,6 +441,7 @@
#ifdef TRACE_HAVE_INTRINSICS
void do_ClassIDIntrinsic(Intrinsic* x);
+ void do_getBufferWriter(Intrinsic* x);
#endif
void do_RuntimeCall(address routine, Intrinsic* x);
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Fri Oct 21 12:30:12 2016 +0300
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Fri Oct 21 16:20:18 2016 +0200
@@ -537,6 +537,7 @@
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime:
case vmIntrinsics::_getClassId:
+ case vmIntrinsics::_getBufferWriter:
#endif
case vmIntrinsics::_currentTimeMillis:
case vmIntrinsics::_nanoTime:
--- a/hotspot/src/share/vm/opto/library_call.cpp Fri Oct 21 12:30:12 2016 +0300
+++ b/hotspot/src/share/vm/opto/library_call.cpp Fri Oct 21 16:20:18 2016 +0200
@@ -256,6 +256,7 @@
bool inline_native_time_funcs(address method, const char* funcName);
#ifdef TRACE_HAVE_INTRINSICS
bool inline_native_classID();
+ bool inline_native_getBufferWriter();
#endif
bool inline_native_isInterrupted();
bool inline_native_Class_query(vmIntrinsics::ID id);
@@ -713,6 +714,7 @@
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_counterTime: return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime");
case vmIntrinsics::_getClassId: return inline_native_classID();
+ case vmIntrinsics::_getBufferWriter: return inline_native_getBufferWriter();
#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");
@@ -3198,6 +3200,44 @@
}
+bool LibraryCallKit::inline_native_getBufferWriter() {
+ Node* tls_ptr = _gvn.transform(new ThreadLocalNode());
+
+ Node* jobj_ptr = basic_plus_adr(top(), tls_ptr,
+ in_bytes(TRACE_THREAD_DATA_WRITER_OFFSET)
+ );
+
+ Node* jobj = make_load(control(), jobj_ptr, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
+
+ Node* jobj_cmp_null = _gvn.transform( new CmpPNode(jobj, null()) );
+ Node* test_jobj_eq_null = _gvn.transform( new BoolNode(jobj_cmp_null, BoolTest::eq) );
+
+ IfNode* iff_jobj_null =
+ create_and_map_if(control(), test_jobj_eq_null, PROB_NEVER, COUNT_UNKNOWN);
+
+ enum { _normal_path = 1,
+ _null_path = 2,
+ PATH_LIMIT };
+
+ RegionNode* result_rgn = new RegionNode(PATH_LIMIT);
+ PhiNode* result_val = new PhiNode(result_rgn, TypePtr::BOTTOM);
+ record_for_igvn(result_rgn);
+
+ Node* jobj_is_null = _gvn.transform( new 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 IfFalseNode(iff_jobj_null) );
+ result_rgn->init_req(_normal_path, jobj_is_not_null);
+
+ Node* res = make_load(NULL, jobj, TypeInstPtr::BOTTOM, T_OBJECT, MemNode::unordered);
+ result_val->init_req(_normal_path, res);
+
+ set_result(result_rgn, result_val);
+
+ return true;
+}
+
#endif
//------------------------inline_native_currentThread------------------
--- a/hotspot/src/share/vm/trace/traceMacros.hpp Fri Oct 21 12:30:12 2016 +0300
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp Fri Oct 21 16:20:18 2016 +0200
@@ -57,6 +57,8 @@
#define TRACE_DEFINE_THREAD_TRACE_ID_OFFSET typedef int ___IGNORED_hs_trace_type5
#define TRACE_THREAD_TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
#define TRACE_DEFINE_THREAD_ID_SIZE typedef int ___IGNORED_hs_trace_type6
+#define TRACE_DEFINE_THREAD_DATA_WRITER_OFFSET typedef int ___IGNORED_hs_trace_type7
+#define TRACE_THREAD_DATA_WRITER_OFFSET in_ByteSize(0); ShouldNotReachHere()
#define TRACE_TEMPLATES(template)
#define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)