changeset 3:4e36cfdacf99

Fix the bug of null_check_for_branch. After fixing the bug, the compiler can trigger and handle an implicit exception when the null pointer of branch is checked, so the bug of guarantee("unhandled implicit exception in compiled code") is fixed when SPECjvm2008 runs.
author Cai Songsong <caisongsong@loongson.cn>
date Sat, 09 Oct 2010 17:16:21 +0800
parents d9ead3bdbf5b
children ccd64fcdde80
files hotspot/src/share/vm/c1/c1_LIR.cpp hotspot/src/share/vm/c1/c1_LIR.hpp hotspot/src/share/vm/c1/c1_LIRAssembler.cpp hotspot/src/share/vm/c1/c1_LIRGenerator.cpp hotspot/src/share/vm/c1/c1_LinearScan.cpp
diffstat 5 files changed, 106 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp	Sat Oct 09 16:29:56 2010 +0800
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp	Sat Oct 09 17:16:21 2010 +0800
@@ -315,40 +315,38 @@
 }
 
 #else
-LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type,BlockBegin* block):
-	LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL),
+LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type,
+  BlockBegin* block):
+	LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo *)(NULL)),
 	_cond(cond),
 	_type(type),
 	_label(block->label()),
 	_block(block),
 	_ublock(NULL),
-	_stub(NULL)
- {
+	_stub(NULL) {
+}
 
- }
- LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, CodeStub* stub):
-	LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL),
+LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, 
+  CodeStub* stub):
+	LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo *)(NULL)),
 	_cond(cond),
 	_type(type),
 	_label(stub->entry()),
 	_block(NULL),
 	_ublock(NULL),
-	_stub(stub)
- {
+	_stub(stub) {
+}
 
- }
-
-LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type,BlockBegin *block, BlockBegin *ublock): 
-	LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo*)NULL),
+LIR_OpBranch::LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type,
+  BlockBegin *block, BlockBegin *ublock): 
+	LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo *)(NULL)),
 	_cond(cond),
 	_type(type),
 	_label(block->label()),
 	_block(block),
 	_ublock(ublock),
-	_stub(NULL)
- {
- 
- }
+	_stub(NULL) {
+}
 
 #endif
 
@@ -625,7 +623,11 @@
 
 
 // LIR_Op2
+#ifdef MIPS32
+    case lir_null_check_for_branch:
+#else
     case lir_cmp:
+#endif
     case lir_cmp_l2i:
     case lir_ucmp_fd2i:
     case lir_cmp_fd2i:
@@ -1740,7 +1742,11 @@
      case lir_alloc_object:          s = "alloc_obj";     break;
      case lir_monaddr:               s = "mon_addr";      break;
      // LIR_Op2
+#ifdef MIPS32
+     case lir_null_check_for_branch: s = "null_check_for_branch"; break;
+#else
      case lir_cmp:                   s = "cmp";           break;
+#endif
      case lir_cmp_l2i:               s = "cmp_l2i";       break;
      case lir_ucmp_fd2i:             s = "ucomp_fd2i";    break;
      case lir_cmp_fd2i:              s = "comp_fd2i";     break;
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp	Sat Oct 09 16:29:56 2010 +0800
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp	Sat Oct 09 17:16:21 2010 +0800
@@ -837,7 +837,11 @@
       , lir_branch
       , lir_cond_float_branch
 #endif
+#ifdef MIPS32
+      , lir_null_check_for_branch
+#else
       , lir_cmp
+#endif
       , lir_cmp_l2i
       , lir_ucmp_fd2i
       , lir_cmp_fd2i
@@ -1587,13 +1591,21 @@
 
   virtual void verify() const;
  public:
+  LIR_Op2(LIR_Code code, LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, 
+    CodeEmitInfo* info = NULL, BasicType type = T_ILLEGAL)
+    : LIR_Op(code, LIR_OprFact::illegalOpr, info), 
+			_opr1(opr1), _opr2(opr2), 
+			_type(type), 
+			_tmp(LIR_OprFact::illegalOpr) {
+  }
+
   LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result = LIR_OprFact::illegalOpr,
           CodeEmitInfo* info = NULL, BasicType type = T_ILLEGAL)
     : LIR_Op(code, result, info), 
 			_opr1(opr1), _opr2(opr2), 
 			_type(type), 
-			_tmp(LIR_OprFact::illegalOpr)              {
-    assert(code!=lir_cmp && is_in_range(code, begin_op2, end_op2), "code check");
+			_tmp(LIR_OprFact::illegalOpr) {
+    assert(is_in_range(code, begin_op2, end_op2), "code check");
   }
 
   
@@ -1602,7 +1614,7 @@
 			_opr1(opr1), _opr2(opr2), 
 			_type(T_ILLEGAL),
 			_tmp(tmp) {
-    assert(code != lir_cmp && is_in_range(code, begin_op2, end_op2), "code check");
+    assert(is_in_range(code, begin_op2, end_op2), "code check");
   }
 
   LIR_Opr in_opr1() const                        { return _opr1; }
@@ -1638,14 +1650,17 @@
  public:
   // these are temporary constructors until we start using the conditional register  
   LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, Label* lbl)
-    : LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo *)NULL), _cond(cond), _label(lbl), _block(NULL), _ublock(NULL),_stub(NULL){}
+    : LIR_Op2(lir_branch, left, right, LIR_OprFact::illegalOpr, (CodeEmitInfo*)(NULL)), 
+      _cond(cond), _label(lbl), _block(NULL), _ublock(NULL),_stub(NULL)
+  {
+  }
  
-
   LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, BlockBegin* block);
 	 
   LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, CodeStub* stub);
 
-  LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, BlockBegin *block,BlockBegin *ublock);
+  LIR_OpBranch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, 
+                BlockBegin *block,BlockBegin *ublock);
 
   LIR_Condition cond()        const              { return _cond;        }
   BasicType     type()        const              { return _type;        }
@@ -2061,6 +2076,33 @@
   void cmove(LIR_Condition condition, LIR_Opr src1, LIR_Opr src2, LIR_Opr dst) {
     append(new LIR_Op2(lir_cmove, condition, src1, src2, dst));
   }
+#else
+  void null_check_for_branch(LIR_Condition condition, LIR_Opr left, LIR_Opr right, 
+    CodeEmitInfo* info = NULL) {
+    append(new LIR_Op2(lir_null_check_for_branch, condition, left, right, info));
+  }
+
+  void null_check_for_branch(LIR_Condition condition, LIR_Opr left, int right, 
+    CodeEmitInfo* info = NULL) {
+    append(new LIR_Op2(lir_null_check_for_branch, condition, left, LIR_OprFact::intConst(right), info));
+  }
+
+  void null_check_for_branch(LIR_Condition condition, LIR_Opr base, int disp, int c, 
+    CodeEmitInfo* info) {
+    append(new LIR_Op2(lir_null_check_for_branch, condition,
+                        LIR_OprFact::address(new LIR_Address(base, disp, T_INT)), 
+                        LIR_OprFact::intConst(c), 
+                        info, T_INT)); 
+  }
+
+  void null_check_branch(LIR_Condition condition, LIR_Opr reg, LIR_Address* addr, 
+    CodeEmitInfo* info) {
+    append(new LIR_Op2(lir_null_check_for_branch, condition,
+                        reg,
+                        LIR_OprFact::address(addr),
+                        info));
+  }
+
 #endif
 
   void cas_long(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value, LIR_Opr t1, LIR_Opr t2);
@@ -2139,20 +2181,20 @@
   }
 #else
   void branch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, Label* lbl) {
-	  	append(new LIR_OpBranch(cond, left, right, lbl));
+	  append(new LIR_OpBranch(cond, left, right, lbl));
   }
 
   void branch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, BlockBegin* block) {  
- 		append(new LIR_OpBranch(cond, left, right, type,block));
+ 		append(new LIR_OpBranch(cond, left, right, type, block));
   }
 
   void branch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, CodeStub* stub) {
-	  	append(new LIR_OpBranch(cond, left, right, type,stub));
+	  append(new LIR_OpBranch(cond, left, right, type, stub));
   }
 
   void branch(LIR_Condition cond, LIR_Opr left, LIR_Opr right, BasicType type, 
-		BlockBegin* block, BlockBegin* unordered) {
-	  	append(new LIR_OpBranch(cond, left, right, type,block,unordered));
+    BlockBegin* block, BlockBegin* unordered) {
+	  append(new LIR_OpBranch(cond, left, right, type, block, unordered));
   }
 
 #endif
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Sat Oct 09 16:29:56 2010 +0800
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Sat Oct 09 17:16:21 2010 +0800
@@ -633,18 +633,24 @@
 
 void LIR_Assembler::emit_op2(LIR_Op2* op) {
 	switch (op->code()) {
+#ifndef MIPS32
 		case lir_cmp:
-#ifndef MIPS32
 			if (op->info() != NULL) {
 				assert(op->in_opr1()->is_address() || op->in_opr2()->is_address(),
 						"shouldn't be codeemitinfo for non-address operands");
 				add_debug_info_for_null_check_here(op->info()); // exception possible
 			}
 			comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op);
+			break;
 #else
-
+    case lir_null_check_for_branch:
+      	if (op->info() != NULL) {
+				assert(op->in_opr1()->is_address() || op->in_opr2()->is_address(),
+						"shouldn't be codeemitinfo for non-address operands");
+				add_debug_info_for_null_check_here(op->info()); // exception possible
+			}
+      break;
 #endif
-			break;
 
 		case lir_cmp_l2i:
 		case lir_cmp_fd2i:
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Sat Oct 09 16:29:56 2010 +0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Sat Oct 09 17:16:21 2010 +0800
@@ -462,7 +462,8 @@
 #else
 	LIR_Opr left = LIR_OprFact::address(new LIR_Address(array, arrayOopDesc::length_offset_in_bytes(), T_INT));
 	LIR_Opr right = LIR_OprFact::intConst(index->as_jint());
-	__ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch
+  __ null_check_for_branch(lir_cond_belowEqual, left, right, null_check_info);
+	__ branch(lir_cond_belowEqual, left, right ,T_INT, stub); // forward branch
 
 #endif
   } else {
@@ -473,7 +474,8 @@
 #else
 	LIR_Opr left = index;
 	LIR_Opr right = LIR_OprFact::address(new LIR_Address( array, arrayOopDesc::length_offset_in_bytes(), T_INT));
-	__ branch(lir_cond_aboveEqual,left, right ,T_INT, stub); // forward branch
+	__ null_check_for_branch(lir_cond_aboveEqual, left, right, null_check_info);
+  __ branch(lir_cond_aboveEqual,left, right ,T_INT, stub); // forward branch
 #endif
   }
 }
@@ -488,6 +490,7 @@
 #else
 	LIR_Opr left = LIR_OprFact::address(new LIR_Address(buffer, java_nio_Buffer::limit_offset(),T_INT));
 	LIR_Opr right = LIR_OprFact::intConst(index->as_jint());
+  __ null_check_for_branch(lir_cond_belowEqual, left, right, info);
 	__ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch
 
 #endif
@@ -499,6 +502,7 @@
 #else
 	LIR_Opr left = index;
 	LIR_Opr right = LIR_OprFact::address(new LIR_Address( buffer, java_nio_Buffer::limit_offset(), T_INT));
+  __ null_check_for_branch(lir_cond_aboveEqual, left, right, info);
 	__ branch(lir_cond_aboveEqual,left, right ,T_INT, stub); // forward branch
 
 #endif
@@ -1761,12 +1765,15 @@
     CodeStub* stub = new RangeCheckStub(info, index.result(), true);
     if (index.result()->is_constant()) {
 #ifndef MIPS32
-      cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info);
+      cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), 
+        index.result()->as_jint(), info);
       __ branch(lir_cond_belowEqual, T_INT, stub);
 #else
-	LIR_Opr left = LIR_OprFact::address(new LIR_Address( buf.result(), java_nio_Buffer::limit_offset(),T_INT));
-	LIR_Opr right = LIR_OprFact::intConst(index.result()->as_jint());
-	__ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch
+	    LIR_Opr left = LIR_OprFact::address(new LIR_Address( buf.result(), 
+                                                java_nio_Buffer::limit_offset(),T_INT));
+    	LIR_Opr right = LIR_OprFact::intConst(index.result()->as_jint());
+      __ null_check_for_branch(lir_cond_belowEqual, left, right, info);
+	    __ branch(lir_cond_belowEqual,left, right ,T_INT, stub); // forward branch
 #endif
     } else {
 #ifndef MIPS32
@@ -1774,9 +1781,10 @@
                   java_nio_Buffer::limit_offset(), T_INT, info);
       __ branch(lir_cond_aboveEqual, T_INT, stub);
 #else
-	LIR_Opr right = LIR_OprFact::address(new LIR_Address( buf.result(), java_nio_Buffer::limit_offset(),T_INT));
-	LIR_Opr left =  index.result();
-	__ branch(lir_cond_aboveEqual,left, right ,T_INT, stub); // forward branch
+	    LIR_Opr right = LIR_OprFact::address(new LIR_Address( buf.result(), java_nio_Buffer::limit_offset(),T_INT));
+	    LIR_Opr left =  index.result();
+      __ null_check_for_branch(lir_cond_aboveEqual, left, right, info);
+	    __ branch(lir_cond_aboveEqual, left, right , T_INT, stub); // forward branch
 #endif
     }
     __ move(index.result(), result);
@@ -1853,7 +1861,7 @@
       __ cmp(lir_cond_belowEqual, length.result(), index.result());
       __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
 #else
-	__ branch(lir_cond_belowEqual, length.result(), index.result(),T_INT, new RangeCheckStub(range_check_info, index.result()));
+	    __ branch(lir_cond_belowEqual, length.result(), index.result(),T_INT, new RangeCheckStub(range_check_info, index.result()));
 #endif
     } else {
       array_range_check(array.result(), index.result(), null_check_info, range_check_info);
@@ -2331,7 +2339,6 @@
 
 void LIRGenerator::do_Goto(Goto* x) {
   set_no_result(x);
-
   if (block()->next()->as_OsrEntry()) {
     // need to free up storage used for OSR entry point
     LIR_Opr osrBuffer = block()->next()->operand();
@@ -2344,6 +2351,7 @@
   }
 
   if (x->is_safepoint()) {
+    // need to free up storage used for OSR entry point
     ValueStack* state = x->state_before() ? x->state_before() : x->state();
 
     // increment backedge counter if needed
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Sat Oct 09 16:29:56 2010 +0800
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Sat Oct 09 17:16:21 2010 +0800
@@ -6376,8 +6376,9 @@
 						       }
 						       break;
 					       }
-
+#ifndef MIPS32
 				case lir_cmp:             inc_counter(counter_cmp); break;
+#endif
 
 				case lir_branch:
 				case lir_cond_float_branch: {