1.1 --- a/src/share/vm/opto/parse1.cpp Tue Mar 25 12:54:21 2014 -0700 1.2 +++ b/src/share/vm/opto/parse1.cpp Tue Mar 25 17:07:36 2014 -0700 1.3 @@ -565,6 +565,10 @@ 1.4 set_map(entry_map); 1.5 do_method_entry(); 1.6 } 1.7 + if (depth() == 1) { 1.8 + // Add check to deoptimize the nmethod if RTM state was changed 1.9 + rtm_deopt(); 1.10 + } 1.11 1.12 // Check for bailouts during method entry. 1.13 if (failing()) { 1.14 @@ -1982,6 +1986,42 @@ 1.15 set_control( _gvn.transform(result_rgn) ); 1.16 } 1.17 1.18 +// Add check to deoptimize if RTM state is not ProfileRTM 1.19 +void Parse::rtm_deopt() { 1.20 +#if INCLUDE_RTM_OPT 1.21 + if (C->profile_rtm()) { 1.22 + assert(C->method() != NULL, "only for normal compilations"); 1.23 + assert(!C->method()->method_data()->is_empty(), "MDO is needed to record RTM state"); 1.24 + assert(depth() == 1, "generate check only for main compiled method"); 1.25 + 1.26 + // Set starting bci for uncommon trap. 1.27 + set_parse_bci(is_osr_parse() ? osr_bci() : 0); 1.28 + 1.29 + // Load the rtm_state from the MethodData. 1.30 + const TypePtr* adr_type = TypeMetadataPtr::make(C->method()->method_data()); 1.31 + Node* mdo = makecon(adr_type); 1.32 + int offset = MethodData::rtm_state_offset_in_bytes(); 1.33 + Node* adr_node = basic_plus_adr(mdo, mdo, offset); 1.34 + Node* rtm_state = make_load(control(), adr_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered); 1.35 + 1.36 + // Separate Load from Cmp by Opaque. 1.37 + // In expand_macro_nodes() it will be replaced either 1.38 + // with this load when there are locks in the code 1.39 + // or with ProfileRTM (cmp->in(2)) otherwise so that 1.40 + // the check will fold. 1.41 + Node* profile_state = makecon(TypeInt::make(ProfileRTM)); 1.42 + Node* opq = _gvn.transform( new (C) Opaque3Node(C, rtm_state, Opaque3Node::RTM_OPT) ); 1.43 + Node* chk = _gvn.transform( new (C) CmpINode(opq, profile_state) ); 1.44 + Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) ); 1.45 + // Branch to failure if state was changed 1.46 + { BuildCutout unless(this, tst, PROB_ALWAYS); 1.47 + uncommon_trap(Deoptimization::Reason_rtm_state_change, 1.48 + Deoptimization::Action_make_not_entrant); 1.49 + } 1.50 + } 1.51 +#endif 1.52 +} 1.53 + 1.54 //------------------------------return_current--------------------------------- 1.55 // Append current _map to _exit_return 1.56 void Parse::return_current(Node* value) {