United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6828024 verification of fixed interval usage is too weak
JDK-6828024 : verification of fixed interval usage is too weak

Details
Type:
Bug
Submit Date:
2009-04-08
Status:
Resolved
Updated Date:
2010-04-02
Project Name:
JDK
Resolved Date:
2009-05-08
Component:
hotspot
OS:
solaris_9
Sub-Component:
compiler
CPU:
sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs16
Fixed Versions:
hs16 (b02)

Related Reports
Backport:
Backport:

Sub Tasks

Description
Generation of LIR has the subtle invariant that fixed intervals containing oops should never be alive across a safepoint.  The current logic that checks this is too weak.

                                    

Comments
EVALUATION

The purpose of the assert is to check that there are no live intervals using fixed registers spanning a safepoint that aren't used by the op itself.  So we walk to current op id and find all the fixed intervals that are live across the current op.  Then we scan the op itself to see if it is using that interval.  If it is then the interval is safe.  If it's not then there's a bug because that fixed interval won't show up in an oop map.  Basically we're checking that the set of live fixed intervals is subset of the intervals used by the op.
                                     
2009-04-08
SUGGESTED FIX

diff --git a/src/share/vm/c1/c1_LinearScan.cpp b/src/share/vm/c1/c1_LinearScan.cpp
--- a/src/share/vm/c1/c1_LinearScan.cpp
+++ b/src/share/vm/c1/c1_LinearScan.cpp
@@ -2956,9 +2956,11 @@ void LinearScan::do_linear_scan() {
 
   NOT_PRODUCT(print_intervals("After Register Allocation"));
   NOT_PRODUCT(print_lir(2, "LIR after register allocation:"));
+
+  sort_intervals_after_allocation();
+
   DEBUG_ONLY(verify());
 
-  sort_intervals_after_allocation();
   eliminate_spill_moves();
   assign_reg_num();
   CHECK_BAILOUT();
@@ -3147,6 +3149,16 @@ void LinearScan::verify_intervals() {
 
 
 void LinearScan::verify_no_oops_in_fixed_intervals() {
+  Interval* fixed_intervals;
+  Interval* other_intervals;
+  create_unhandled_lists(&fixed_intervals, &other_intervals, is_precolored_cpu_interval, NULL);
+
+  // to ensure a walking until the last instruction id, add a dummy interval
+  // with a high operation id
+  other_intervals = new Interval(any_reg);
+  other_intervals->add_range(max_jint - 2, max_jint - 1);
+  IntervalWalker* iw = new IntervalWalker(this, fixed_intervals, other_intervals);
+
   LIR_OpVisitState visitor;
   for (int i = 0; i < block_count(); i++) {
     BlockBegin* block = block_at(i);
@@ -3158,6 +3170,46 @@ void LinearScan::verify_no_oops_in_fixed
       int op_id = op->id();
 
       visitor.visit(op);
+
+      if (visitor.info_count() > 0) {
+        iw->walk_before(op->id());
+        bool check_live = true;
+        if (op->code() == lir_move) {
+          LIR_Op1* move = (LIR_Op1*)op;
+          check_live = move->patch_code() == lir_patch_none;
+        }
+        LIR_OpBranch* branch = op->as_OpBranch();
+        if (branch != NULL && branch->stub() != NULL && branch->stub()->is_exception_throw_stub()) {
+          check_live = false;
+        }
+
+        // Make sure none of the fixed registers is live across an oopmap since we can't handle that correctly
+        if (check_live) {
+          for (Interval* interval = iw->active_first(fixedKind); interval != Interval::end(); interval = interval->next()) {
+            if (interval->current_to() > op->id() + 1) {
+              bool ok = false;
+              for_each_visitor_mode(mode) {
+                int n = visitor.opr_count(mode);
+                for (int k = 0; k < n; k++) {
+                  LIR_Opr opr = visitor.opr_at(mode, k);
+                  if (opr->is_fixed_cpu()) {
+                    if (interval_at(reg_num(opr)) == interval) {
+                      ok = true;
+                      break;
+                    }
+                    int hi = reg_numHi(opr);
+                    if (hi != -1 && interval_at(hi) == interval) {
+                      ok = true;
+                      break;
+                    }
+                  }
+                }
+              }
+              assert(ok, "fixed intervals should never be live across an oopmap point");
+            }
+          }
+        }
+      }
 
       // oop-maps at calls do not contain registers, so check is not needed
       if (!visitor.has_call()) {
                                     
2009-04-08
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/a134d9824964
                                     
2009-04-17



Hardware and Software, Engineered to Work Together