Print this page
rev 7150 : 8006960: hotspot, "impossible" assertion failure
Summary: Escape state of allocated object should be always adjusted after it was passed to a method.
Reviewed-by: kvn

Split Split Close
Expand all
Collapse all
          --- old/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp
          +++ new/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp
↓ open down ↓ 34 lines elided ↑ open up ↑
  35   35  
  36   36  #ifndef PRODUCT
  37   37    #define TRACE_BCEA(level, code)                                            \
  38   38      if (EstimateArgEscape && BCEATraceLevel >= level) {                        \
  39   39        code;                                                                  \
  40   40      }
  41   41  #else
  42   42    #define TRACE_BCEA(level, code)
  43   43  #endif
  44   44  
  45      -// Maintain a map of which aguments a local variable or
       45 +// Maintain a map of which arguments a local variable or
  46   46  // stack slot may contain.  In addition to tracking
  47   47  // arguments, it tracks two special values, "allocated"
  48   48  // which represents any object allocated in the current
  49   49  // method, and "unknown" which is any other object.
  50   50  // Up to 30 arguments are handled, with the last one
  51   51  // representing summary information for any extra arguments
  52   52  class BCEscapeAnalyzer::ArgumentMap {
  53   53    uint  _bits;
  54   54    enum {MAXBIT = 29,
  55   55          ALLOCATED = 1,
↓ open down ↓ 255 lines elided ↑ open up ↑
 311  311    }
 312  312  
 313  313    if (inline_target != NULL && !is_recursive_call(inline_target)) {
 314  314      // analyze callee
 315  315      BCEscapeAnalyzer analyzer(inline_target, this);
 316  316  
 317  317      // adjust escape state of actual parameters
 318  318      bool must_record_dependencies = false;
 319  319      for (i = arg_size - 1; i >= 0; i--) {
 320  320        ArgumentMap arg = state.raw_pop();
 321      -      if (!is_argument(arg))
      321 +      // Check if callee arg is a caller arg or an allocated object
      322 +      bool allocated = arg.contains_allocated();
      323 +      if (!(is_argument(arg) || allocated))
 322  324          continue;
 323  325        for (int j = 0; j < _arg_size; j++) {
 324  326          if (arg.contains(j)) {
 325  327            _arg_modified[j] |= analyzer._arg_modified[i];
 326  328          }
 327  329        }
 328      -      if (!is_arg_stack(arg)) {
      330 +      if (!(is_arg_stack(arg) || allocated)) {
 329  331          // arguments have already been recognized as escaping
 330  332        } else if (analyzer.is_arg_stack(i) && !analyzer.is_arg_returned(i)) {
 331  333          set_method_escape(arg);
 332  334          must_record_dependencies = true;
 333  335        } else {
 334  336          set_global_escape(arg);
 335  337        }
 336  338      }
 337  339      _unknown_modified = _unknown_modified || analyzer.has_non_arg_side_affects();
 338  340  
↓ open down ↓ 1148 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX