--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Aug 19 18:51:15 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Mon Aug 22 11:47:15 2016 -0700
@@ -683,6 +683,7 @@
, _cleanup_block(NULL)
, _cleanup_return_prev(NULL)
, _cleanup_state(NULL)
+ , _ignore_return(false)
{
if (parent != NULL) {
_max_inline_size = (intx) ((float) NestedInliningSizeRatio * (float) parent->max_inline_size() / 100.0f);
@@ -1445,7 +1446,7 @@
}
-void GraphBuilder::method_return(Value x) {
+void GraphBuilder::method_return(Value x, bool ignore_return) {
if (RegisterFinalizersAtInit &&
method()->intrinsic_id() == vmIntrinsics::_Object_init) {
call_register_finalizer();
@@ -1518,7 +1519,9 @@
int invoke_bci = state()->caller_state()->bci();
set_state(state()->caller_state()->copy_for_parsing());
if (x != NULL) {
- state()->push(x->type(), x);
+ if (!ignore_return) {
+ state()->push(x->type(), x);
+ }
if (profile_return() && x->type()->is_object_kind()) {
ciMethod* caller = state()->scope()->method();
ciMethodData* md = caller->method_data_or_null();
@@ -1563,6 +1566,7 @@
append(new MemBar(lir_membar_storestore));
}
+ assert(!ignore_return, "Ignoring return value works only for inlining");
append(new Return(x));
}
@@ -1981,7 +1985,7 @@
code == Bytecodes::_invokedynamic) {
ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
// static binding => check if callee is ok
- bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
+ bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), false, code, better_receiver);
CHECK_BAILOUT();
clear_inline_bailout();
@@ -2611,6 +2615,8 @@
push_exception = true;
}
+ bool ignore_return = scope_data()->ignore_return();
+
while (!bailed_out() && last()->as_BlockEnd() == NULL &&
(code = stream()->next()) != ciBytecodeStream::EOBC() &&
(block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
@@ -2806,12 +2812,12 @@
case Bytecodes::_ret : ret(s.get_index()); break;
case Bytecodes::_tableswitch : table_switch(); break;
case Bytecodes::_lookupswitch : lookup_switch(); break;
- case Bytecodes::_ireturn : method_return(ipop()); break;
- case Bytecodes::_lreturn : method_return(lpop()); break;
- case Bytecodes::_freturn : method_return(fpop()); break;
- case Bytecodes::_dreturn : method_return(dpop()); break;
- case Bytecodes::_areturn : method_return(apop()); break;
- case Bytecodes::_return : method_return(NULL ); break;
+ case Bytecodes::_ireturn : method_return(ipop(), ignore_return); break;
+ case Bytecodes::_lreturn : method_return(lpop(), ignore_return); break;
+ case Bytecodes::_freturn : method_return(fpop(), ignore_return); break;
+ case Bytecodes::_dreturn : method_return(dpop(), ignore_return); break;
+ case Bytecodes::_areturn : method_return(apop(), ignore_return); break;
+ case Bytecodes::_return : method_return(NULL , ignore_return); break;
case Bytecodes::_getstatic : // fall through
case Bytecodes::_putstatic : // fall through
case Bytecodes::_getfield : // fall through
@@ -3336,7 +3342,7 @@
}
-bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
+bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
const char* msg = NULL;
// clear out any existing inline bailout condition
@@ -3351,7 +3357,7 @@
// method handle invokes
if (callee->is_method_handle_intrinsic()) {
- if (try_method_handle_inline(callee)) {
+ if (try_method_handle_inline(callee, ignore_return)) {
if (callee->has_reserved_stack_access()) {
compilation()->set_has_reserved_stack_access(true);
}
@@ -3363,7 +3369,7 @@
// handle intrinsics
if (callee->intrinsic_id() != vmIntrinsics::_none &&
(CheckIntrinsics ? callee->intrinsic_candidate() : true)) {
- if (try_inline_intrinsics(callee)) {
+ if (try_inline_intrinsics(callee, ignore_return)) {
print_inlining(callee, "intrinsic");
if (callee->has_reserved_stack_access()) {
compilation()->set_has_reserved_stack_access(true);
@@ -3384,7 +3390,7 @@
if (bc == Bytecodes::_illegal) {
bc = code();
}
- if (try_inline_full(callee, holder_known, bc, receiver)) {
+ if (try_inline_full(callee, holder_known, ignore_return, bc, receiver)) {
if (callee->has_reserved_stack_access()) {
compilation()->set_has_reserved_stack_access(true);
}
@@ -3415,7 +3421,7 @@
return NULL;
}
-void GraphBuilder::build_graph_for_intrinsic(ciMethod* callee) {
+void GraphBuilder::build_graph_for_intrinsic(ciMethod* callee, bool ignore_return) {
vmIntrinsics::ID id = callee->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
@@ -3509,14 +3515,16 @@
vmIntrinsics::can_trap(id));
// append instruction & push result
Value value = append_split(result);
- if (result_type != voidType) push(result_type, value);
+ if (result_type != voidType && !ignore_return) {
+ push(result_type, value);
+ }
if (callee != method() && profile_return() && result_type->is_object_kind()) {
profile_return_type(result, callee);
}
}
-bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
+bool GraphBuilder::try_inline_intrinsics(ciMethod* callee, bool ignore_return) {
// For calling is_intrinsic_available we need to transition to
// the '_thread_in_vm' state because is_intrinsic_available()
// accesses critical VM-internal data.
@@ -3536,7 +3544,7 @@
return false;
}
}
- build_graph_for_intrinsic(callee);
+ build_graph_for_intrinsic(callee, ignore_return);
return true;
}
@@ -3691,7 +3699,7 @@
}
-bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
+bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
assert(!callee->is_native(), "callee must not be native");
if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
INLINE_BAILOUT("inlining prohibited by policy");
@@ -3889,6 +3897,7 @@
// Clear out bytecode stream
scope_data()->set_stream(NULL);
+ scope_data()->set_ignore_return(ignore_return);
CompileLog* log = compilation()->log();
if (log != NULL) log->head("parse method='%d'", log->identify(callee));
@@ -3958,7 +3967,7 @@
}
-bool GraphBuilder::try_method_handle_inline(ciMethod* callee) {
+bool GraphBuilder::try_method_handle_inline(ciMethod* callee, bool ignore_return) {
ValueStack* state_before = copy_state_before();
vmIntrinsics::ID iid = callee->intrinsic_id();
switch (iid) {
@@ -3972,7 +3981,8 @@
// We don't do CHA here so only inline static and statically bindable methods.
if (target->is_static() || target->can_be_statically_bound()) {
Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
- if (try_inline(target, /*holder_known*/ true, bc)) {
+ ignore_return = ignore_return || (callee->return_type()->is_void() && !target->return_type()->is_void());
+ if (try_inline(target, /*holder_known*/ true, ignore_return, bc)) {
return true;
}
} else {
@@ -3994,10 +4004,11 @@
ValueType* type = apop()->type();
if (type->is_constant()) {
ciMethod* target = type->as_ObjectType()->constant_value()->as_member_name()->get_vmtarget();
+ ignore_return = ignore_return || (callee->return_type()->is_void() && !target->return_type()->is_void());
// If the target is another method handle invoke, try to recursively get
// a better target.
if (target->is_method_handle_intrinsic()) {
- if (try_method_handle_inline(target)) {
+ if (try_method_handle_inline(target, ignore_return)) {
return true;
}
} else {
@@ -4032,7 +4043,7 @@
// We don't do CHA here so only inline static and statically bindable methods.
if (target->is_static() || target->can_be_statically_bound()) {
Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
- if (try_inline(target, /*holder_known*/ true, bc)) {
+ if (try_inline(target, /*holder_known*/ true, ignore_return, bc)) {
return true;
}
} else {
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Fri Aug 19 18:51:15 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Mon Aug 22 11:47:15 2016 -0700
@@ -100,6 +100,9 @@
Instruction* _cleanup_return_prev; // Instruction before return instruction
ValueStack* _cleanup_state; // State of that block (not yet pinned)
+ // When inlining do not push the result on the stack
+ bool _ignore_return;
+
public:
ScopeData(ScopeData* parent);
@@ -163,6 +166,9 @@
BlockBegin* inline_cleanup_block() const { return _cleanup_block; }
Instruction* inline_cleanup_return_prev() const{ return _cleanup_return_prev; }
ValueStack* inline_cleanup_state() const { return _cleanup_state; }
+
+ bool ignore_return() const { return _ignore_return; }
+ void set_ignore_return(bool ignore_return) { _ignore_return = ignore_return; }
};
// for all GraphBuilders
@@ -246,7 +252,7 @@
void ret(int local_index);
void table_switch();
void lookup_switch();
- void method_return(Value x);
+ void method_return(Value x, bool ignore_return = false);
void call_register_finalizer();
void access_field(Bytecodes::Code code);
void invoke(Bytecodes::Code code);
@@ -340,19 +346,19 @@
void inline_sync_entry(Value lock, BlockBegin* sync_handler);
void fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler = false);
- void build_graph_for_intrinsic(ciMethod* callee);
+ void build_graph_for_intrinsic(ciMethod* callee, bool ignore_return);
// inliners
- bool try_inline( ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
- bool try_inline_intrinsics(ciMethod* callee);
- bool try_inline_full( ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
+ bool try_inline( ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
+ bool try_inline_intrinsics(ciMethod* callee, bool ignore_return = false);
+ bool try_inline_full( ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
bool try_inline_jsr(int jsr_dest_bci);
const char* check_can_parse(ciMethod* callee) const;
const char* should_not_inline(ciMethod* callee) const;
// JSR 292 support
- bool try_method_handle_inline(ciMethod* callee);
+ bool try_method_handle_inline(ciMethod* callee, bool ignore_return);
// helpers
void inline_bailout(const char* msg);