src/share/vm/opto/parse1.cpp

changeset 6518
62c54fcc0a35
parent 6507
752ba2e5f6d0
parent 6429
606acabe7b5c
child 6680
78bbf4d43a14
     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) {

mercurial