< prev index next >

src/hotspot/share/c1/c1_GraphBuilder.cpp

Print this page

  23  */
  24 
  25 #include "c1/c1_Canonicalizer.hpp"
  26 #include "c1/c1_CFGPrinter.hpp"
  27 #include "c1/c1_Compilation.hpp"
  28 #include "c1/c1_GraphBuilder.hpp"
  29 #include "c1/c1_InstructionPrinter.hpp"
  30 #include "ci/ciCallSite.hpp"
  31 #include "ci/ciField.hpp"
  32 #include "ci/ciKlass.hpp"
  33 #include "ci/ciMemberName.hpp"
  34 #include "ci/ciSymbols.hpp"
  35 #include "ci/ciUtilities.inline.hpp"
  36 #include "classfile/javaClasses.hpp"
  37 #include "compiler/compilationPolicy.hpp"
  38 #include "compiler/compileBroker.hpp"
  39 #include "compiler/compilerEvent.hpp"
  40 #include "interpreter/bytecode.hpp"
  41 #include "jfr/jfrEvents.hpp"
  42 #include "memory/resourceArea.hpp"


  43 #include "runtime/sharedRuntime.hpp"
  44 #include "utilities/checkedCast.hpp"
  45 #include "utilities/macros.hpp"
  46 #if INCLUDE_JFR
  47 #include "jfr/jfr.hpp"
  48 #endif
  49 
  50 class BlockListBuilder {
  51  private:
  52   Compilation* _compilation;
  53   IRScope*     _scope;
  54 
  55   BlockList    _blocks;                // internal list of all blocks
  56   BlockList*   _bci2block;             // mapping from bci to blocks for GraphBuilder
  57   GrowableArray<BlockList> _bci2block_successors; // Mapping bcis to their blocks successors while we dont have a blockend
  58 
  59   // fields used by mark_loops
  60   ResourceBitMap _active;              // for iteration of control flow graph
  61   ResourceBitMap _visited;             // for iteration of control flow graph
  62   GrowableArray<ResourceBitMap> _loop_map; // caches the information if a block is contained in a loop

1694         return new Constant(value);
1695       }
1696       return nullptr; // Not a constant.
1697     default:
1698       return new Constant(value);
1699   }
1700 }
1701 
1702 void GraphBuilder::access_field(Bytecodes::Code code) {
1703   bool will_link;
1704   ciField* field = stream()->get_field(will_link);
1705   ciInstanceKlass* holder = field->holder();
1706   BasicType field_type = field->type()->basic_type();
1707   ValueType* type = as_ValueType(field_type);
1708   // call will_link again to determine if the field is valid.
1709   const bool needs_patching = !holder->is_loaded() ||
1710                               !field->will_link(method(), code) ||
1711                               PatchALot;
1712 
1713   ValueStack* state_before = nullptr;
1714   if (!holder->is_initialized() || needs_patching) {
1715     // save state before instruction for debug info when
1716     // deoptimization happens during patching
1717     state_before = copy_state_before();
1718   }
1719 
1720   Value obj = nullptr;
1721   if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
1722     if (state_before != nullptr) {
1723       // build a patching constant
1724       obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
1725     } else {
1726       obj = new Constant(new InstanceConstant(holder->java_mirror()));
1727     }
1728   }
1729 
1730   if (code == Bytecodes::_putfield) {
1731     scope()->set_wrote_fields();
1732     if (field->is_volatile()) {
1733       scope()->set_wrote_volatile();
1734     }

2103 
2104   if (cha_monomorphic_target != nullptr) {
2105     assert(!target->can_be_statically_bound() || target == cha_monomorphic_target, "");
2106     assert(!cha_monomorphic_target->is_abstract(), "");
2107     if (!cha_monomorphic_target->can_be_statically_bound(actual_recv)) {
2108       // If we inlined because CHA revealed only a single target method,
2109       // then we are dependent on that target method not getting overridden
2110       // by dynamic class loading.  Be sure to test the "static" receiver
2111       // dest_method here, as opposed to the actual receiver, which may
2112       // falsely lead us to believe that the receiver is final or private.
2113       dependency_recorder()->assert_unique_concrete_method(actual_recv, cha_monomorphic_target, callee_holder, target);
2114     }
2115     code = Bytecodes::_invokespecial;
2116   }
2117 
2118   // check if we could do inlining
2119   if (!PatchALot && Inline && target->is_loaded() && !patch_for_appendix &&
2120       callee_holder->is_loaded()) { // the effect of symbolic reference resolution
2121 
2122     // callee is known => check if we have static binding
2123     if ((code == Bytecodes::_invokestatic && klass->is_initialized()) || // invokestatic involves an initialization barrier on declaring class

2124         code == Bytecodes::_invokespecial ||
2125         (code == Bytecodes::_invokevirtual && target->is_final_method()) ||
2126         code == Bytecodes::_invokedynamic) {
2127       // static binding => check if callee is ok
2128       ciMethod* inline_target = (cha_monomorphic_target != nullptr) ? cha_monomorphic_target : target;
2129       bool holder_known = (cha_monomorphic_target != nullptr) || (exact_target != nullptr);
2130       bool success = try_inline(inline_target, holder_known, false /* ignore_return */, code, better_receiver);
2131 
2132       CHECK_BAILOUT();
2133       clear_inline_bailout();
2134 
2135       if (success) {
2136         // Register dependence if JVMTI has either breakpoint
2137         // setting or hotswapping of methods capabilities since they may
2138         // cause deoptimization.
2139         if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
2140           dependency_recorder()->assert_evol_method(inline_target);
2141         }
2142         return;
2143       }

3846   block()->set_end(end);
3847 
3848   _block = orig_block;
3849   _state = orig_state;
3850   _last = orig_last;
3851 }
3852 
3853 
3854 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
3855   assert(!callee->is_native(), "callee must not be native");
3856   if (CompilationPolicy::should_not_inline(compilation()->env(), callee)) {
3857     INLINE_BAILOUT("inlining prohibited by policy");
3858   }
3859   // first perform tests of things it's not possible to inline
3860   if (callee->has_exception_handlers() &&
3861       !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
3862   if (callee->is_synchronized() &&
3863       !InlineSynchronizedMethods         ) INLINE_BAILOUT("callee is synchronized");
3864   if (!callee->holder()->is_linked())      INLINE_BAILOUT("callee's klass not linked yet");
3865   if (bc == Bytecodes::_invokestatic &&
3866       !callee->holder()->is_initialized()) INLINE_BAILOUT("callee's klass not initialized yet");

3867   if (!callee->has_balanced_monitors())    INLINE_BAILOUT("callee's monitors do not match");
3868 
3869   // Proper inlining of methods with jsrs requires a little more work.
3870   if (callee->has_jsrs()                 ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
3871 
3872   if (is_profiling() && !callee->ensure_method_data()) {
3873     INLINE_BAILOUT("mdo allocation failed");
3874   }
3875 
3876   const bool is_invokedynamic = (bc == Bytecodes::_invokedynamic);
3877   const bool has_receiver = (bc != Bytecodes::_invokestatic && !is_invokedynamic);
3878 
3879   const int args_base = state()->stack_size() - callee->arg_size();
3880   assert(args_base >= 0, "stack underflow during inlining");
3881 
3882   Value recv = nullptr;
3883   if (has_receiver) {
3884     assert(!callee->is_static(), "callee must not be static");
3885     assert(callee->arg_size() > 0, "must have at least a receiver");
3886 

4021   caller_state->truncate_stack(args_base);
4022   assert(callee_state->stack_size() == 0, "callee stack must be empty");
4023 
4024   Value lock = nullptr;
4025   BlockBegin* sync_handler = nullptr;
4026 
4027   // Inline the locking of the receiver if the callee is synchronized
4028   if (callee->is_synchronized()) {
4029     lock = callee->is_static() ? append(new Constant(new InstanceConstant(callee->holder()->java_mirror())))
4030                                : state()->local_at(0);
4031     sync_handler = new BlockBegin(SynchronizationEntryBCI);
4032     inline_sync_entry(lock, sync_handler);
4033   }
4034 
4035   if (compilation()->env()->dtrace_method_probes()) {
4036     Values* args = new Values(1);
4037     args->push(append(new Constant(new MethodConstant(method()))));
4038     append(new RuntimeCall(voidType, "dtrace_method_entry", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), args));
4039   }
4040 








4041   if (profile_inlined_calls()) {
4042     profile_invocation(callee, copy_state_before_with_bci(SynchronizationEntryBCI));
4043   }
4044 
4045   BlockBegin* callee_start_block = block_at(0);
4046   if (callee_start_block != nullptr) {
4047     assert(callee_start_block->is_set(BlockBegin::parser_loop_header_flag), "must be loop header");
4048     Goto* goto_callee = new Goto(callee_start_block, false);
4049     // The state for this goto is in the scope of the callee, so use
4050     // the entry bci for the callee instead of the call site bci.
4051     append_with_bci(goto_callee, 0);
4052     _block->set_end(goto_callee);
4053     callee_start_block->merge(callee_state, compilation()->has_irreducible_loops());
4054 
4055     _last = _block = callee_start_block;
4056 
4057     scope_data()->add_to_work_list(callee_start_block);
4058   }
4059 
4060   // Clear out bytecode stream

  23  */
  24 
  25 #include "c1/c1_Canonicalizer.hpp"
  26 #include "c1/c1_CFGPrinter.hpp"
  27 #include "c1/c1_Compilation.hpp"
  28 #include "c1/c1_GraphBuilder.hpp"
  29 #include "c1/c1_InstructionPrinter.hpp"
  30 #include "ci/ciCallSite.hpp"
  31 #include "ci/ciField.hpp"
  32 #include "ci/ciKlass.hpp"
  33 #include "ci/ciMemberName.hpp"
  34 #include "ci/ciSymbols.hpp"
  35 #include "ci/ciUtilities.inline.hpp"
  36 #include "classfile/javaClasses.hpp"
  37 #include "compiler/compilationPolicy.hpp"
  38 #include "compiler/compileBroker.hpp"
  39 #include "compiler/compilerEvent.hpp"
  40 #include "interpreter/bytecode.hpp"
  41 #include "jfr/jfrEvents.hpp"
  42 #include "memory/resourceArea.hpp"
  43 #include "oops/oop.inline.hpp"
  44 #include "runtime/runtimeUpcalls.hpp"
  45 #include "runtime/sharedRuntime.hpp"
  46 #include "utilities/checkedCast.hpp"
  47 #include "utilities/macros.hpp"
  48 #if INCLUDE_JFR
  49 #include "jfr/jfr.hpp"
  50 #endif
  51 
  52 class BlockListBuilder {
  53  private:
  54   Compilation* _compilation;
  55   IRScope*     _scope;
  56 
  57   BlockList    _blocks;                // internal list of all blocks
  58   BlockList*   _bci2block;             // mapping from bci to blocks for GraphBuilder
  59   GrowableArray<BlockList> _bci2block_successors; // Mapping bcis to their blocks successors while we dont have a blockend
  60 
  61   // fields used by mark_loops
  62   ResourceBitMap _active;              // for iteration of control flow graph
  63   ResourceBitMap _visited;             // for iteration of control flow graph
  64   GrowableArray<ResourceBitMap> _loop_map; // caches the information if a block is contained in a loop

1696         return new Constant(value);
1697       }
1698       return nullptr; // Not a constant.
1699     default:
1700       return new Constant(value);
1701   }
1702 }
1703 
1704 void GraphBuilder::access_field(Bytecodes::Code code) {
1705   bool will_link;
1706   ciField* field = stream()->get_field(will_link);
1707   ciInstanceKlass* holder = field->holder();
1708   BasicType field_type = field->type()->basic_type();
1709   ValueType* type = as_ValueType(field_type);
1710   // call will_link again to determine if the field is valid.
1711   const bool needs_patching = !holder->is_loaded() ||
1712                               !field->will_link(method(), code) ||
1713                               PatchALot;
1714 
1715   ValueStack* state_before = nullptr;
1716   if (!holder->is_initialized() || needs_patching || compilation()->env()->is_precompile()) {
1717     // save state before instruction for debug info when
1718     // deoptimization happens during patching
1719     state_before = copy_state_before();
1720   }
1721 
1722   Value obj = nullptr;
1723   if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
1724     if (state_before != nullptr) {
1725       // build a patching constant
1726       obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
1727     } else {
1728       obj = new Constant(new InstanceConstant(holder->java_mirror()));
1729     }
1730   }
1731 
1732   if (code == Bytecodes::_putfield) {
1733     scope()->set_wrote_fields();
1734     if (field->is_volatile()) {
1735       scope()->set_wrote_volatile();
1736     }

2105 
2106   if (cha_monomorphic_target != nullptr) {
2107     assert(!target->can_be_statically_bound() || target == cha_monomorphic_target, "");
2108     assert(!cha_monomorphic_target->is_abstract(), "");
2109     if (!cha_monomorphic_target->can_be_statically_bound(actual_recv)) {
2110       // If we inlined because CHA revealed only a single target method,
2111       // then we are dependent on that target method not getting overridden
2112       // by dynamic class loading.  Be sure to test the "static" receiver
2113       // dest_method here, as opposed to the actual receiver, which may
2114       // falsely lead us to believe that the receiver is final or private.
2115       dependency_recorder()->assert_unique_concrete_method(actual_recv, cha_monomorphic_target, callee_holder, target);
2116     }
2117     code = Bytecodes::_invokespecial;
2118   }
2119 
2120   // check if we could do inlining
2121   if (!PatchALot && Inline && target->is_loaded() && !patch_for_appendix &&
2122       callee_holder->is_loaded()) { // the effect of symbolic reference resolution
2123 
2124     // callee is known => check if we have static binding
2125     if ((code == Bytecodes::_invokestatic && klass->is_initialized() &&
2126         !compilation()->env()->is_precompile()) || // invokestatic involves an initialization barrier on declaring class
2127         code == Bytecodes::_invokespecial ||
2128         (code == Bytecodes::_invokevirtual && target->is_final_method()) ||
2129         code == Bytecodes::_invokedynamic) {
2130       // static binding => check if callee is ok
2131       ciMethod* inline_target = (cha_monomorphic_target != nullptr) ? cha_monomorphic_target : target;
2132       bool holder_known = (cha_monomorphic_target != nullptr) || (exact_target != nullptr);
2133       bool success = try_inline(inline_target, holder_known, false /* ignore_return */, code, better_receiver);
2134 
2135       CHECK_BAILOUT();
2136       clear_inline_bailout();
2137 
2138       if (success) {
2139         // Register dependence if JVMTI has either breakpoint
2140         // setting or hotswapping of methods capabilities since they may
2141         // cause deoptimization.
2142         if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
2143           dependency_recorder()->assert_evol_method(inline_target);
2144         }
2145         return;
2146       }

3849   block()->set_end(end);
3850 
3851   _block = orig_block;
3852   _state = orig_state;
3853   _last = orig_last;
3854 }
3855 
3856 
3857 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, bool ignore_return, Bytecodes::Code bc, Value receiver) {
3858   assert(!callee->is_native(), "callee must not be native");
3859   if (CompilationPolicy::should_not_inline(compilation()->env(), callee)) {
3860     INLINE_BAILOUT("inlining prohibited by policy");
3861   }
3862   // first perform tests of things it's not possible to inline
3863   if (callee->has_exception_handlers() &&
3864       !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
3865   if (callee->is_synchronized() &&
3866       !InlineSynchronizedMethods         ) INLINE_BAILOUT("callee is synchronized");
3867   if (!callee->holder()->is_linked())      INLINE_BAILOUT("callee's klass not linked yet");
3868   if (bc == Bytecodes::_invokestatic &&
3869       (!callee->holder()->is_initialized() ||
3870        compilation()->env()->is_precompile())) INLINE_BAILOUT("callee's klass not initialized yet");
3871   if (!callee->has_balanced_monitors())    INLINE_BAILOUT("callee's monitors do not match");
3872 
3873   // Proper inlining of methods with jsrs requires a little more work.
3874   if (callee->has_jsrs()                 ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
3875 
3876   if (is_profiling() && !callee->ensure_method_data()) {
3877     INLINE_BAILOUT("mdo allocation failed");
3878   }
3879 
3880   const bool is_invokedynamic = (bc == Bytecodes::_invokedynamic);
3881   const bool has_receiver = (bc != Bytecodes::_invokestatic && !is_invokedynamic);
3882 
3883   const int args_base = state()->stack_size() - callee->arg_size();
3884   assert(args_base >= 0, "stack underflow during inlining");
3885 
3886   Value recv = nullptr;
3887   if (has_receiver) {
3888     assert(!callee->is_static(), "callee must not be static");
3889     assert(callee->arg_size() > 0, "must have at least a receiver");
3890 

4025   caller_state->truncate_stack(args_base);
4026   assert(callee_state->stack_size() == 0, "callee stack must be empty");
4027 
4028   Value lock = nullptr;
4029   BlockBegin* sync_handler = nullptr;
4030 
4031   // Inline the locking of the receiver if the callee is synchronized
4032   if (callee->is_synchronized()) {
4033     lock = callee->is_static() ? append(new Constant(new InstanceConstant(callee->holder()->java_mirror())))
4034                                : state()->local_at(0);
4035     sync_handler = new BlockBegin(SynchronizationEntryBCI);
4036     inline_sync_entry(lock, sync_handler);
4037   }
4038 
4039   if (compilation()->env()->dtrace_method_probes()) {
4040     Values* args = new Values(1);
4041     args->push(append(new Constant(new MethodConstant(method()))));
4042     append(new RuntimeCall(voidType, "dtrace_method_entry", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), args));
4043   }
4044 
4045   MethodDetails method_details(callee);
4046   RuntimeUpcallInfo* upcall = RuntimeUpcalls::get_first_upcall(RuntimeUpcallType::onMethodEntry, method_details);
4047   while (upcall != nullptr) {
4048     Values* args = new Values(0);
4049     append(new RuntimeCall(voidType, upcall->upcall_name(), upcall->upcall_address(), args));
4050     upcall = RuntimeUpcalls::get_next_upcall(RuntimeUpcallType::onMethodEntry, method_details, upcall);
4051   }
4052 
4053   if (profile_inlined_calls()) {
4054     profile_invocation(callee, copy_state_before_with_bci(SynchronizationEntryBCI));
4055   }
4056 
4057   BlockBegin* callee_start_block = block_at(0);
4058   if (callee_start_block != nullptr) {
4059     assert(callee_start_block->is_set(BlockBegin::parser_loop_header_flag), "must be loop header");
4060     Goto* goto_callee = new Goto(callee_start_block, false);
4061     // The state for this goto is in the scope of the callee, so use
4062     // the entry bci for the callee instead of the call site bci.
4063     append_with_bci(goto_callee, 0);
4064     _block->set_end(goto_callee);
4065     callee_start_block->merge(callee_state, compilation()->has_irreducible_loops());
4066 
4067     _last = _block = callee_start_block;
4068 
4069     scope_data()->add_to_work_list(callee_start_block);
4070   }
4071 
4072   // Clear out bytecode stream
< prev index next >