Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
77ad69d
8259316: [REDO] C1/C2 compiler support for blackholes
shipilev Jan 11, 2021
64de179
Reshuffle tests
shipilev Jan 11, 2021
e6f6830
Update copyright years
shipilev Jan 11, 2021
ba537d7
Simplify ProblemList-Xcomp
shipilev Jan 11, 2021
bcd90c4
Improve comments
shipilev Jan 11, 2021
2392029
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev Feb 1, 2021
e4fb7a0
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev Feb 2, 2021
869cd3f
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev Mar 4, 2021
e15da76
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev Mar 25, 2021
b47443e
Remove blocks from Xcomp
shipilev Mar 25, 2021
07ccf85
Extend JVMCI with shouldBlackholeMethod
shipilev Mar 25, 2021
9a8d21e
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev Mar 29, 2021
0909593
Binding JVMCI through get_jvmci_method
shipilev Mar 29, 2021
a5c95ac
Common the blackhole checks
shipilev Mar 29, 2021
c6ab6ed
Simplify intrinsic test and add warning test
shipilev Mar 29, 2021
0e725c9
Add more checks for C2 intrinsic
shipilev Mar 29, 2021
71bfd89
Do not print double-warning on blackhole already set
shipilev Mar 29, 2021
46d435d
BlackholeStaticTest should unlock blackholes
shipilev Mar 29, 2021
1ff8b68
Rename BlackholeStaticTest to BlackholeIntrinsicTest
shipilev Mar 29, 2021
2fa4941
Redo BlackholeIntrinsicTest to see if target blackhole methods were i…
shipilev Mar 29, 2021
7f4f94d
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev Apr 21, 2021
6aef9d4
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev Apr 22, 2021
46c84b1
Stray whitespace
shipilev Apr 22, 2021
71235fb
Add vm.flagless requirement to tests
shipilev Apr 22, 2021
00c199b
Update copyrights where needed
shipilev Apr 22, 2021
f8bc827
Remove @build in favor of @library
shipilev Apr 22, 2021
65e865a
Merge branch 'master' into JDK-8259316-blackholes-redo
shipilev May 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/hotspot/share/c1/c1_Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ bool Compiler::is_intrinsic_supported(const methodHandle& method) {
break;
case vmIntrinsics::_getObjectSize:
break;
case vmIntrinsics::_blackhole:
break;
default:
return false; // Intrinsics not on the previous list are not available.
}
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/c1/c1_GraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3419,7 +3419,7 @@ bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_r

// handle intrinsics
if (callee->intrinsic_id() != vmIntrinsics::_none &&
(CheckIntrinsics ? callee->intrinsic_candidate() : true)) {
callee->check_intrinsic_candidate()) {
if (try_inline_intrinsics(callee, ignore_return)) {
print_inlining(callee, "intrinsic");
if (callee->has_reserved_stack_access()) {
Expand Down
13 changes: 13 additions & 0 deletions src/hotspot/share/c1/c1_LIRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3202,6 +3202,10 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) {
do_vectorizedMismatch(x);
break;

case vmIntrinsics::_blackhole:
do_blackhole(x);
break;

default: ShouldNotReachHere(); break;
}
}
Expand Down Expand Up @@ -3621,6 +3625,15 @@ void LIRGenerator::do_RangeCheckPredicate(RangeCheckPredicate *x) {
}
}

void LIRGenerator::do_blackhole(Intrinsic *x) {
assert(!x->has_receiver(), "Should have been checked before: only static methods here");
for (int c = 0; c < x->number_of_arguments(); c++) {
// Load the argument
LIRItem vitem(x->argument_at(c), this);
vitem.load_item();
// ...and leave it unused.
}
}

LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
LIRItemList args(1);
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/c1/c1_LIRGenerator.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -265,6 +265,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
void do_update_CRC32(Intrinsic* x);
void do_update_CRC32C(Intrinsic* x);
void do_vectorizedMismatch(Intrinsic* x);
void do_blackhole(Intrinsic* x);

public:
LIR_Opr call_runtime(BasicTypeArray* signature, LIRItemList* args, address entry, ValueType* result_type, CodeEmitInfo* info);
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/ci/ciMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
ciReplay::initialize(this);
}
#endif

CompilerOracle::tag_blackhole_if_possible(h_m);
Copy link

@danilaml danilaml Mar 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for why not updating _intrinsic_id = h_m->intrinsic_id(); with the potentially updated id after calling this is fine?
Wouldn't it still contain the old id set here (at least for the first instance): https://github.com/openjdk/jdk/pull/2024/files#diff-c08baec11bce860df907b1edd944889e3778519fdd7c7a5b9d00e10eb267667fR84 ?

}


Expand Down Expand Up @@ -1214,6 +1216,7 @@ bool ciMethod::is_getter () const { FETCH_FLAG_FROM_VM(is_getter);
bool ciMethod::is_setter () const { FETCH_FLAG_FROM_VM(is_setter); }
bool ciMethod::is_accessor () const { FETCH_FLAG_FROM_VM(is_accessor); }
bool ciMethod::is_initializer () const { FETCH_FLAG_FROM_VM(is_initializer); }
bool ciMethod::is_empty () const { FETCH_FLAG_FROM_VM(is_empty_method); }

bool ciMethod::is_boxing_method() const {
if (intrinsic_id() != vmIntrinsics::_none && holder()->is_box_klass()) {
Expand Down
10 changes: 10 additions & 0 deletions src/hotspot/share/ci/ciMethod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ class ciMethod : public ciMetadata {
bool intrinsic_candidate() const { return get_Method()->intrinsic_candidate(); }
bool is_static_initializer() const { return get_Method()->is_static_initializer(); }

bool check_intrinsic_candidate() const {
if (intrinsic_id() == vmIntrinsics::_blackhole) {
// This is the intrinsic without an associated method, so no intrinsic_candidate
// flag is set. The intrinsic is still correct.
return true;
}
return (CheckIntrinsics ? intrinsic_candidate() : true);
}

int highest_osr_comp_level();

Bytecodes::Code java_code_at_bci(int bci) {
Expand Down Expand Up @@ -346,6 +355,7 @@ class ciMethod : public ciMetadata {
bool is_setter () const;
bool is_accessor () const;
bool is_initializer () const;
bool is_empty () const;
bool can_be_statically_bound() const { return _can_be_statically_bound; }
bool has_reserved_stack_access() const { return _has_reserved_stack_access; }
bool is_boxing_method() const;
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/classfile/classFileParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5304,6 +5304,11 @@ static void check_methods_for_intrinsics(const InstanceKlass* ik,
// is defined for it.
continue;
}
if (vmIntrinsics::_blackhole == id) {
// The _blackhole intrinsic is a special marker. No explicit method
// is defined for it.
continue;
}

if (vmIntrinsics::class_for(id) == klass_id) {
// Check if the current class contains a method with the same
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/classfile/vmIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ bool vmIntrinsics::should_be_pinned(vmIntrinsics::ID id) {
#endif
case vmIntrinsics::_currentTimeMillis:
case vmIntrinsics::_nanoTime:
case vmIntrinsics::_blackhole:
return true;
default:
return false;
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/classfile/vmIntrinsics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,9 @@ class methodHandle;
do_name( getObjectSize_name, "getObjectSize0") \
do_alias( getObjectSize_signature, long_object_long_signature) \
\
/* special marker for blackholed methods: */ \
do_intrinsic(_blackhole, java_lang_Object, blackhole_name, star_name, F_S) \
\
/* unsafe memory references (there are a lot of them...) */ \
do_signature(getReference_signature, "(Ljava/lang/Object;J)Ljava/lang/Object;") \
do_signature(putReference_signature, "(Ljava/lang/Object;JLjava/lang/Object;)V") \
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/classfile/vmSymbols.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@
template(signature_name, "signature") \
template(slot_name, "slot") \
template(trusted_final_name, "trustedFinal") \
template(blackhole_name, "<blackhole>") /*fake name*/ \
\
/* Support for annotations (JDK 1.5 and above) */ \
\
Expand Down
38 changes: 37 additions & 1 deletion src/hotspot/share/compiler/compilerOracle.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -306,6 +306,11 @@ static void register_command(TypedMethodOptionMatcher* matcher,
}
assert(CompilerOracle::option_matches_type(option, value), "Value must match option type");

if (option == CompileCommand::Blackhole && !UnlockExperimentalVMOptions) {
warning("Blackhole compile option is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions");
return;
}

matcher->init(option, option_list);
matcher->set_value<T>(value);
option_list = matcher;
Expand Down Expand Up @@ -417,6 +422,37 @@ bool CompilerOracle::should_break_at(const methodHandle& method) {
return check_predicate(CompileCommand::Break, method);
}

void CompilerOracle::tag_blackhole_if_possible(const methodHandle& method) {
if (!check_predicate(CompileCommand::Blackhole, method)) {
return;
}
guarantee(UnlockExperimentalVMOptions, "Checked during initial parsing");
if (method->result_type() != T_VOID) {
warning("Blackhole compile option only works for methods with void type: %s",
method->name_and_sig_as_C_string());
return;
}
if (!method->is_empty_method()) {
warning("Blackhole compile option only works for empty methods: %s",
method->name_and_sig_as_C_string());
return;
}
if (!method->is_static()) {
warning("Blackhole compile option only works for static methods: %s",
method->name_and_sig_as_C_string());
return;
}
if (method->intrinsic_id() == vmIntrinsics::_blackhole) {
return;
}
if (method->intrinsic_id() != vmIntrinsics::_none) {
warning("Blackhole compile option only works for methods that do not have intrinsic set: %s, %s",
method->name_and_sig_as_C_string(), vmIntrinsics::name_at(method->intrinsic_id()));
return;
}
method->set_intrinsic_id(vmIntrinsics::_blackhole);
}

static enum CompileCommand match_option_name(const char* line, int* bytes_read, char* errorbuf, int bufsize) {
assert(ARRAY_SIZE(option_names) == static_cast<int>(CompileCommand::Count), "option_names size mismatch");

Expand Down
6 changes: 5 additions & 1 deletion src/hotspot/share/compiler/compilerOracle.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -51,6 +51,7 @@ class methodHandle;
option(Print, "print", Bool) \
option(Inline, "inline", Bool) \
option(DontInline, "dontinline", Bool) \
option(Blackhole, "blackhole", Bool) \
option(CompileOnly, "compileonly", Bool)\
option(Exclude, "exclude", Bool) \
option(Break, "break", Bool) \
Expand Down Expand Up @@ -144,6 +145,9 @@ class CompilerOracle : AllStatic {
// Tells whether there are any methods to print for print_method_statistics()
static bool should_print_methods();

// Tags the method as blackhole candidate, if possible.
static void tag_blackhole_if_possible(const methodHandle& method);

// A wrapper for checking bool options
static bool has_option(const methodHandle& method, enum CompileCommand option);

Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/jvmci/jvmciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
#include "compiler/compilerOracle.hpp"
#include "compiler/compileTask.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
Expand Down Expand Up @@ -991,6 +992,7 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS)
jmetadata handle = _runtime->allocate_handle(method);
jboolean exception = false;
if (is_hotspot()) {
CompilerOracle::tag_blackhole_if_possible(method);
JavaValue result(T_OBJECT);
JavaCallArguments args;
args.push_long((jlong) handle);
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/opto/c2compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,8 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt
case vmIntrinsics::_VectorInsert:
case vmIntrinsics::_VectorExtract:
return EnableVectorSupport;
case vmIntrinsics::_blackhole:
break;

default:
return false;
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/opto/classes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ macro(ArrayCopy)
macro(AryEq)
macro(AtanD)
macro(Binary)
macro(Blackhole)
macro(Bool)
macro(BoxLock)
macro(ReverseBytesI)
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3519,6 +3519,8 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
}
break;
}
case Op_Blackhole:
break;
case Op_RangeCheck: {
RangeCheckNode* rc = n->as_RangeCheck();
Node* iff = new IfNode(rc->in(0), rc->in(1), rc->_prob, rc->_fcnt);
Expand Down
25 changes: 24 additions & 1 deletion src/hotspot/share/opto/library_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
Node* ctrl = kit.control();
#endif
// Try to inline the intrinsic.
if ((CheckIntrinsics ? callee->intrinsic_candidate() : true) &&
if (callee->check_intrinsic_candidate() &&
kit.try_to_inline(_last_predicate)) {
const char *inline_msg = is_virtual() ? "(intrinsic, virtual)"
: "(intrinsic)";
Expand Down Expand Up @@ -669,6 +669,9 @@ bool LibraryCallKit::try_to_inline(int predicate) {
case vmIntrinsics::_getObjectSize:
return inline_getObjectSize();

case vmIntrinsics::_blackhole:
return inline_blackhole();

default:
// If you get here, it may be that someone has added a new intrinsic
// to the list in vmIntrinsics.hpp without implementing it here.
Expand Down Expand Up @@ -6911,3 +6914,23 @@ bool LibraryCallKit::inline_getObjectSize() {

return true;
}

//------------------------------- inline_blackhole --------------------------------------
//
// Make sure all arguments to this node are alive.
// This matches methods that were requested to be blackholed through compile commands.
//
bool LibraryCallKit::inline_blackhole() {
assert(callee()->is_static(), "Should have been checked before: only static methods here");
assert(callee()->is_empty(), "Should have been checked before: only empty methods here");
assert(callee()->holder()->is_loaded(), "Should have been checked before: only methods for loaded classes here");

// Bind call arguments as blackhole arguments to keep them alive
Node* bh = insert_mem_bar(Op_Blackhole);
uint nargs = callee()->arg_size();
for (uint i = 0; i < nargs; i++) {
bh->add_req(argument(i));
}

return true;
}
2 changes: 2 additions & 0 deletions src/hotspot/share/opto/library_call.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,5 +344,7 @@ class LibraryCallKit : public GraphKit {
}

bool inline_getObjectSize();

bool inline_blackhole();
};

23 changes: 23 additions & 0 deletions src/hotspot/share/opto/memnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "opto/addnode.hpp"
#include "opto/arraycopynode.hpp"
#include "opto/cfgnode.hpp"
#include "opto/regalloc.hpp"
#include "opto/compile.hpp"
#include "opto/connode.hpp"
#include "opto/convertnode.hpp"
Expand Down Expand Up @@ -3305,6 +3306,7 @@ MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) {
case Op_OnSpinWait: return new OnSpinWaitNode(C, atp, pn);
case Op_Initialize: return new InitializeNode(C, atp, pn);
case Op_MemBarStoreStore: return new MemBarStoreStoreNode(C, atp, pn);
case Op_Blackhole: return new BlackholeNode(C, atp, pn);
default: ShouldNotReachHere(); return NULL;
}
}
Expand Down Expand Up @@ -3539,6 +3541,27 @@ MemBarNode* MemBarNode::leading_membar() const {
return mb;
}

#ifndef PRODUCT
void BlackholeNode::format(PhaseRegAlloc* ra, outputStream* st) const {
st->print("blackhole ");
bool first = true;
for (uint i = 0; i < req(); i++) {
Node* n = in(i);
if (n != NULL && OptoReg::is_valid(ra->get_reg_first(n))) {
if (first) {
first = false;
} else {
st->print(", ");
}
char buf[128];
ra->dump_register(n, buf);
st->print("%s", buf);
}
}
st->cr();
}
#endif

//===========================InitializeNode====================================
// SUMMARY:
// This node acts as a memory barrier on raw memory, after some raw stores.
Expand Down
22 changes: 21 additions & 1 deletion src/hotspot/share/opto/memnode.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1337,6 +1337,26 @@ class OnSpinWaitNode: public MemBarNode {
virtual int Opcode() const;
};

//------------------------------BlackholeNode----------------------------
// Blackhole all arguments. This node would survive through the compiler
// the effects on its arguments, and would be finally matched to nothing.
class BlackholeNode : public MemBarNode {
public:
BlackholeNode(Compile* C, int alias_idx, Node* precedent)
: MemBarNode(C, alias_idx, precedent) {}
virtual int Opcode() const;
virtual uint ideal_reg() const { return 0; } // not matched in the AD file
const RegMask &in_RegMask(uint idx) const {
// Fake the incoming arguments mask for blackholes: accept all registers
// and all stack slots. This would avoid any redundant register moves
// for blackhole inputs.
return RegMask::All;
}
#ifndef PRODUCT
virtual void format(PhaseRegAlloc* ra, outputStream* st) const;
#endif
};

// Isolation of object setup after an AllocateNode and before next safepoint.
// (See comment in memnode.cpp near InitializeNode::InitializeNode for semantics.)
class InitializeNode: public MemBarNode {
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/opto/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class AllocateNode;
class ArrayCopyNode;
class BaseCountedLoopNode;
class BaseCountedLoopEndNode;
class BlackholeNode;
class Block;
class BoolNode;
class BoxLockNode;
Expand Down
Loading