src/share/vm/opto/graphKit.cpp

changeset 5981
3213ba4d3dff
parent 5925
f91a9a696e5e
child 5991
b2ee5dc63353
     1.1 --- a/src/share/vm/opto/graphKit.cpp	Fri Oct 18 12:15:32 2013 -0700
     1.2 +++ b/src/share/vm/opto/graphKit.cpp	Sat Oct 19 12:16:43 2013 +0200
     1.3 @@ -639,6 +639,7 @@
     1.4    _map    = kit->map();   // preserve the map
     1.5    _sp     = kit->sp();
     1.6    kit->set_map(clone_map ? kit->clone_map() : NULL);
     1.7 +  Compile::current()->inc_preserve_jvm_state();
     1.8  #ifdef ASSERT
     1.9    _bci    = kit->bci();
    1.10    Parse* parser = kit->is_Parse();
    1.11 @@ -656,6 +657,7 @@
    1.12  #endif
    1.13    kit->set_map(_map);
    1.14    kit->set_sp(_sp);
    1.15 +  Compile::current()->dec_preserve_jvm_state();
    1.16  }
    1.17  
    1.18  
    1.19 @@ -1373,17 +1375,70 @@
    1.20  
    1.21  //--------------------------replace_in_map-------------------------------------
    1.22  void GraphKit::replace_in_map(Node* old, Node* neww) {
    1.23 -  this->map()->replace_edge(old, neww);
    1.24 +  if (old == neww) {
    1.25 +    return;
    1.26 +  }
    1.27 +
    1.28 +  map()->replace_edge(old, neww);
    1.29  
    1.30    // Note: This operation potentially replaces any edge
    1.31    // on the map.  This includes locals, stack, and monitors
    1.32    // of the current (innermost) JVM state.
    1.33  
    1.34 -  // We can consider replacing in caller maps.
    1.35 -  // The idea would be that an inlined function's null checks
    1.36 -  // can be shared with the entire inlining tree.
    1.37 -  // The expense of doing this is that the PreserveJVMState class
    1.38 -  // would have to preserve caller states too, with a deep copy.
    1.39 +  if (!ReplaceInParentMaps) {
    1.40 +    return;
    1.41 +  }
    1.42 +
    1.43 +  // PreserveJVMState doesn't do a deep copy so we can't modify
    1.44 +  // parents
    1.45 +  if (Compile::current()->has_preserve_jvm_state()) {
    1.46 +    return;
    1.47 +  }
    1.48 +
    1.49 +  Parse* parser = is_Parse();
    1.50 +  bool progress = true;
    1.51 +  Node* ctrl = map()->in(0);
    1.52 +  // Follow the chain of parsers and see whether the update can be
    1.53 +  // done in the map of callers. We can do the replace for a caller if
    1.54 +  // the current control post dominates the control of a caller.
    1.55 +  while (parser != NULL && parser->caller() != NULL && progress) {
    1.56 +    progress = false;
    1.57 +    Node* parent_map = parser->caller()->map();
    1.58 +    assert(parser->exits().map()->jvms()->depth() == parser->caller()->depth(), "map mismatch");
    1.59 +
    1.60 +    Node* parent_ctrl = parent_map->in(0);
    1.61 +
    1.62 +    while (parent_ctrl->is_Region()) {
    1.63 +      Node* n = parent_ctrl->as_Region()->is_copy();
    1.64 +      if (n == NULL) {
    1.65 +        break;
    1.66 +      }
    1.67 +      parent_ctrl = n;
    1.68 +    }
    1.69 +
    1.70 +    for (;;) {
    1.71 +      if (ctrl == parent_ctrl) {
    1.72 +        // update the map of the exits which is the one that will be
    1.73 +        // used when compilation resume after inlining
    1.74 +        parser->exits().map()->replace_edge(old, neww);
    1.75 +        progress = true;
    1.76 +        break;
    1.77 +      }
    1.78 +      if (ctrl->is_Proj() && ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
    1.79 +        ctrl = ctrl->in(0)->in(0);
    1.80 +      } else if (ctrl->is_Region()) {
    1.81 +        Node* n = ctrl->as_Region()->is_copy();
    1.82 +        if (n == NULL) {
    1.83 +          break;
    1.84 +        }
    1.85 +        ctrl = n;
    1.86 +      } else {
    1.87 +        break;
    1.88 +      }
    1.89 +    }
    1.90 +
    1.91 +    parser = parser->parent_parser();
    1.92 +  }
    1.93  }
    1.94  
    1.95  

mercurial