8277573: VmObjectAlloc is not generated by intrinsics methods which allocate objects

Reviewed-by: kvn, sspitsyn
This commit is contained in:
Leonid Mesnik 2023-04-11 13:55:20 +00:00
parent e5ce7d9e43
commit 7a5597c34f
11 changed files with 69 additions and 9 deletions

@ -1031,10 +1031,14 @@ void ConnectionGraph::add_call_node(CallNode* call) {
ciMethod* meth = call->as_CallJava()->method();
if (meth == nullptr) {
const char* name = call->as_CallStaticJava()->_name;
assert(strncmp(name, "_multianewarray", 15) == 0, "TODO: add failed case check");
// Returns a newly allocated non-escaped object.
add_java_object(call, PointsToNode::NoEscape);
set_not_scalar_replaceable(ptnode_adr(call_idx) NOT_PRODUCT(COMMA "is result of multinewarray"));
if (strncmp(name, "_notify_jvmti_object_alloc", 26) == 0) { // Object escapes to JVMTI
add_java_object(call, PointsToNode::GlobalEscape);
} else {
assert(strncmp(name, "_multianewarray", 15) == 0, "TODO: add failed case check");
// Returns a newly allocated non-escaped object.
add_java_object(call, PointsToNode::NoEscape);
set_not_scalar_replaceable(ptnode_adr(call_idx) NOT_PRODUCT(COMMA "is result of multinewarray"));
}
} else if (meth->is_boxing_method()) {
// Returns boxing object
PointsToNode::EscapeState es;

@ -50,6 +50,7 @@
#include "opto/runtime.hpp"
#include "opto/rootnode.hpp"
#include "opto/subnode.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "prims/unsafe.hpp"
#include "runtime/jniHandles.inline.hpp"
@ -2828,8 +2829,29 @@ bool LibraryCallKit::inline_unsafe_allocate() {
test = _gvn.transform(new SubINode(inst, bits));
// The 'test' is non-zero if we need to take a slow path.
}
Node* obj = new_instance(kls, test);
#if INCLUDE_JVMTI
// Check if JvmtiExport::_should_notify_object_alloc is enabled and post notifications
IdealKit ideal(this);
IdealVariable result(ideal); ideal.declarations_done();
Node* ONE = ideal.ConI(1);
Node* addr = makecon(TypeRawPtr::make((address) &JvmtiExport::_should_notify_object_alloc));
Node* should_post_vm_object_alloc = ideal.load(ideal.ctrl(), addr, TypeInt::BOOL, T_BOOLEAN, Compile::AliasIdxRaw);
ideal.sync_kit(this);
ideal.if_then(should_post_vm_object_alloc, BoolTest::eq, ONE); {
const TypeFunc *tf = OptoRuntime::notify_jvmti_object_alloc_Type();
address funcAddr = OptoRuntime::notify_jvmti_object_alloc();
sync_kit(ideal);
Node* call = make_runtime_call(RC_NO_LEAF, tf, funcAddr, "_notify_jvmti_object_alloc", TypePtr::BOTTOM, obj);
ideal.sync_kit(this);
ideal.set(result,_gvn.transform(new ProjNode(call, TypeFunc::Parms+0)));
} ideal.else_(); {
ideal.set(result,obj);
} ideal.end_if();
final_sync(ideal);
obj = ideal.value(result);
#endif //INCLUDE_JVMTI
set_result(obj);
return true;
}

@ -110,6 +110,7 @@ address OptoRuntime::_rethrow_Java = nullptr;
address OptoRuntime::_slow_arraycopy_Java = nullptr;
address OptoRuntime::_register_finalizer_Java = nullptr;
#if INCLUDE_JVMTI
address OptoRuntime::_notify_jvmti_object_alloc = nullptr;
address OptoRuntime::_notify_jvmti_mount = nullptr;
address OptoRuntime::_notify_jvmti_unmount = nullptr;
#endif
@ -153,6 +154,7 @@ bool OptoRuntime::generate(ciEnv* env) {
gen(env, _multianewarray5_Java , multianewarray5_Type , multianewarray5_C , 0 , true, false);
gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true, false);
#if INCLUDE_JVMTI
gen(env, _notify_jvmti_object_alloc , notify_jvmti_object_alloc_Type, SharedRuntime::notify_jvmti_object_alloc, 0, true, false);
gen(env, _notify_jvmti_mount , notify_jvmti_Type , SharedRuntime::notify_jvmti_mount, 0 , true, false);
gen(env, _notify_jvmti_unmount , notify_jvmti_Type , SharedRuntime::notify_jvmti_unmount, 0 , true, false);
#endif
@ -474,6 +476,22 @@ const TypeFunc *OptoRuntime::new_instance_Type() {
return TypeFunc::make(domain, range);
}
#if INCLUDE_JVMTI
const TypeFunc *OptoRuntime::notify_jvmti_object_alloc_Type() {
// create input type (domain)
const Type **fields = TypeTuple::fields(1);
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
// create result type (range)
fields = TypeTuple::fields(1);
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // Returned oop
const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
return TypeFunc::make(domain, range);
}
#endif
const TypeFunc *OptoRuntime::athrow_Type() {
// create input type (domain)

@ -136,6 +136,7 @@ class OptoRuntime : public AllStatic {
static address _slow_arraycopy_Java;
static address _register_finalizer_Java;
#if INCLUDE_JVMTI
static address _notify_jvmti_object_alloc;
static address _notify_jvmti_mount;
static address _notify_jvmti_unmount;
#endif
@ -213,6 +214,7 @@ private:
static address slow_arraycopy_Java() { return _slow_arraycopy_Java; }
static address register_finalizer_Java() { return _register_finalizer_Java; }
#if INCLUDE_JVMTI
static address notify_jvmti_object_alloc() { return _notify_jvmti_object_alloc; }
static address notify_jvmti_mount() { return _notify_jvmti_mount; }
static address notify_jvmti_unmount() { return _notify_jvmti_unmount; }
#endif
@ -303,6 +305,7 @@ private:
JFR_ONLY(static const TypeFunc* class_id_load_barrier_Type();)
#if INCLUDE_JVMTI
static const TypeFunc* notify_jvmti_object_alloc_Type();
static const TypeFunc* notify_jvmti_Type();
#endif

@ -724,6 +724,7 @@ JvmtiEventControllerPrivate::recompute_enabled() {
// set global should_post_on_exceptions
JvmtiExport::set_should_post_on_exceptions((any_env_thread_enabled & SHOULD_POST_ON_EXCEPTIONS_BITS) != 0);
JvmtiExport::_should_notify_object_alloc = JvmtiExport::should_post_vm_object_alloc();
}
EC_TRACE(("[-] # recompute enabled - after " JULONG_FORMAT_X, any_env_thread_enabled));

@ -1046,6 +1046,10 @@ bool JvmtiExport::has_early_class_hook_env() {
bool JvmtiExport::_should_post_class_file_load_hook = false;
// This flag is read by C2 during VM internal objects allocation
bool JvmtiExport::_should_notify_object_alloc = false;
// this entry is for class file load hook on class load, redefine and retransform
bool JvmtiExport::post_class_file_load_hook(Symbol* h_name,
Handle class_loader,

@ -396,6 +396,9 @@ class JvmtiExport : public AllStatic {
}
}
// Used by C2 to post vm_object_alloc
static bool _should_notify_object_alloc;
static void record_sampled_internal_object_allocation(oop object) NOT_JVMTI_RETURN;
// Post objects collected by sampled_object_alloc_event_collector.
static void post_sampled_object_alloc(JavaThread *thread, oop object) NOT_JVMTI_RETURN;

@ -628,6 +628,14 @@ void SharedRuntime::throw_and_post_jvmti_exception(JavaThread* current, Symbol*
}
#if INCLUDE_JVMTI
JRT_ENTRY(void, SharedRuntime::notify_jvmti_object_alloc(oopDesc* o, JavaThread* current))
Handle h = Handle(current, o);
if (JvmtiExport::should_post_vm_object_alloc()) {
JvmtiExport::post_vm_object_alloc(current, o);
}
current->set_vm_result(h());
JRT_END
JRT_ENTRY(void, SharedRuntime::notify_jvmti_mount(oopDesc* vt, jboolean hide, jboolean first_mount, JavaThread* current))
jobject vthread = JNIHandles::make_local(const_cast<oopDesc*>(vt));

@ -265,6 +265,7 @@ class SharedRuntime: AllStatic {
static void throw_and_post_jvmti_exception(JavaThread* current, Symbol* name, const char *message = nullptr);
#if INCLUDE_JVMTI
static void notify_jvmti_object_alloc(oopDesc* o, JavaThread* current);
// Functions for JVMTI notifications
static void notify_jvmti_mount(oopDesc* vt, jboolean hide, jboolean first_mount, JavaThread* current);
static void notify_jvmti_unmount(oopDesc* vt, jboolean hide, jboolean last_unmount, JavaThread* current);

@ -27,7 +27,6 @@
#
#############################################################################
vmTestbase/nsk/jvmti/AttachOnDemand/attach022/TestDescription.java 8277573 generic-all
vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all
vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw001/TestDescription.java 8205957 linux-x64,windows-x64
vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 8245680 windows-x64
@ -38,8 +37,6 @@ serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java 8303168 linux-x64
serviceability/sa/TestJhsdbJstackMixed.java 8248675 linux-aarch64
serviceability/jvmti/VMObjectAlloc/VMObjectAllocTest.java 8288430 generic-all
gc/cslocker/TestCSLocker.java 8293289 generic-x64
serviceability/sa/ClhsdbInspect.java 8283578 windows-x64

@ -147,7 +147,6 @@ vmTestbase/metaspace/gc/firstGC_50m/TestDescription.java 8208250 generic-all
vmTestbase/metaspace/gc/firstGC_99m/TestDescription.java 8208250 generic-all
vmTestbase/metaspace/gc/firstGC_default/TestDescription.java 8208250 generic-all
vmTestbase/nsk/jvmti/AttachOnDemand/attach002a/TestDescription.java 8277573 generic-all
vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java 8202971 generic-all
vmTestbase/nsk/jvmti/scenarios/jni_interception/JI05/ji05t001/TestDescription.java 8219652 aix-ppc64
vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64