--- a/hotspot/src/share/vm/opto/parse1.cpp Wed Mar 19 11:37:58 2014 -0700
+++ b/hotspot/src/share/vm/opto/parse1.cpp Thu Mar 20 17:49:27 2014 -0700
@@ -567,6 +567,10 @@
set_map(entry_map);
do_method_entry();
}
+ if (depth() == 1) {
+ // Add check to deoptimize the nmethod if RTM state was changed
+ rtm_deopt();
+ }
// Check for bailouts during method entry.
if (failing()) {
@@ -2006,6 +2010,42 @@
set_control( _gvn.transform(result_rgn) );
}
+// Add check to deoptimize if RTM state is not ProfileRTM
+void Parse::rtm_deopt() {
+#if INCLUDE_RTM_OPT
+ if (C->profile_rtm()) {
+ assert(C->method() != NULL, "only for normal compilations");
+ assert(!C->method()->method_data()->is_empty(), "MDO is needed to record RTM state");
+ assert(depth() == 1, "generate check only for main compiled method");
+
+ // Set starting bci for uncommon trap.
+ set_parse_bci(is_osr_parse() ? osr_bci() : 0);
+
+ // Load the rtm_state from the MethodData.
+ const TypePtr* adr_type = TypeMetadataPtr::make(C->method()->method_data());
+ Node* mdo = makecon(adr_type);
+ int offset = MethodData::rtm_state_offset_in_bytes();
+ Node* adr_node = basic_plus_adr(mdo, mdo, offset);
+ Node* rtm_state = make_load(control(), adr_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
+
+ // Separate Load from Cmp by Opaque.
+ // In expand_macro_nodes() it will be replaced either
+ // with this load when there are locks in the code
+ // or with ProfileRTM (cmp->in(2)) otherwise so that
+ // the check will fold.
+ Node* profile_state = makecon(TypeInt::make(ProfileRTM));
+ Node* opq = _gvn.transform( new (C) Opaque3Node(C, rtm_state, Opaque3Node::RTM_OPT) );
+ Node* chk = _gvn.transform( new (C) CmpINode(opq, profile_state) );
+ Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) );
+ // Branch to failure if state was changed
+ { BuildCutout unless(this, tst, PROB_ALWAYS);
+ uncommon_trap(Deoptimization::Reason_rtm_state_change,
+ Deoptimization::Action_make_not_entrant);
+ }
+ }
+#endif
+}
+
//------------------------------return_current---------------------------------
// Append current _map to _exit_return
void Parse::return_current(Node* value) {