1.1 --- a/src/share/vm/opto/matcher.cpp Wed Sep 17 12:59:52 2008 -0700 1.2 +++ b/src/share/vm/opto/matcher.cpp Tue Sep 23 12:29:06 2008 -0700 1.3 @@ -840,7 +840,7 @@ 1.4 _new2old_map.map(m->_idx, n); 1.5 #endif 1.6 if (m->in(0) != NULL) // m might be top 1.7 - collect_null_checks(m); 1.8 + collect_null_checks(m, n); 1.9 } else { // Else just a regular 'ol guy 1.10 m = n->clone(); // So just clone into new-space 1.11 #ifdef ASSERT 1.12 @@ -1478,12 +1478,19 @@ 1.13 m = _mem_node; 1.14 assert(m != NULL && m->is_Mem(), "expecting memory node"); 1.15 } 1.16 - if (m->adr_type() != mach->adr_type()) { 1.17 + const Type* mach_at = mach->adr_type(); 1.18 + // DecodeN node consumed by an address may have different type 1.19 + // then its input. Don't compare types for such case. 1.20 + if (m->adr_type() != mach_at && m->in(MemNode::Address)->is_AddP() && 1.21 + m->in(MemNode::Address)->in(AddPNode::Address)->is_DecodeN()) { 1.22 + mach_at = m->adr_type(); 1.23 + } 1.24 + if (m->adr_type() != mach_at) { 1.25 m->dump(); 1.26 tty->print_cr("mach:"); 1.27 mach->dump(1); 1.28 } 1.29 - assert(m->adr_type() == mach->adr_type(), "matcher should not change adr type"); 1.30 + assert(m->adr_type() == mach_at, "matcher should not change adr type"); 1.31 } 1.32 #endif 1.33 } 1.34 @@ -1995,7 +2002,7 @@ 1.35 // it. Used by later implicit-null-check handling. Actually collects 1.36 // either an IfTrue or IfFalse for the common NOT-null path, AND the ideal 1.37 // value being tested. 1.38 -void Matcher::collect_null_checks( Node *proj ) { 1.39 +void Matcher::collect_null_checks( Node *proj, Node *orig_proj ) { 1.40 Node *iff = proj->in(0); 1.41 if( iff->Opcode() == Op_If ) { 1.42 // During matching If's have Bool & Cmp side-by-side 1.43 @@ -2008,20 +2015,47 @@ 1.44 if (ct == TypePtr::NULL_PTR || 1.45 (opc == Op_CmpN && ct == TypeNarrowOop::NULL_PTR)) { 1.46 1.47 + bool push_it = false; 1.48 if( proj->Opcode() == Op_IfTrue ) { 1.49 extern int all_null_checks_found; 1.50 all_null_checks_found++; 1.51 if( b->_test._test == BoolTest::ne ) { 1.52 - _null_check_tests.push(proj); 1.53 - _null_check_tests.push(cmp->in(1)); 1.54 + push_it = true; 1.55 } 1.56 } else { 1.57 assert( proj->Opcode() == Op_IfFalse, "" ); 1.58 if( b->_test._test == BoolTest::eq ) { 1.59 - _null_check_tests.push(proj); 1.60 - _null_check_tests.push(cmp->in(1)); 1.61 + push_it = true; 1.62 } 1.63 } 1.64 + if( push_it ) { 1.65 + _null_check_tests.push(proj); 1.66 + Node* val = cmp->in(1); 1.67 +#ifdef _LP64 1.68 + if (UseCompressedOops && !Matcher::clone_shift_expressions && 1.69 + val->bottom_type()->isa_narrowoop()) { 1.70 + // 1.71 + // Look for DecodeN node which should be pinned to orig_proj. 1.72 + // On platforms (Sparc) which can not handle 2 adds 1.73 + // in addressing mode we have to keep a DecodeN node and 1.74 + // use it to do implicit NULL check in address. 1.75 + // 1.76 + // DecodeN node was pinned to non-null path (orig_proj) during 1.77 + // CastPP transformation in final_graph_reshaping_impl(). 1.78 + // 1.79 + uint cnt = orig_proj->outcnt(); 1.80 + for (uint i = 0; i < orig_proj->outcnt(); i++) { 1.81 + Node* d = orig_proj->raw_out(i); 1.82 + if (d->is_DecodeN() && d->in(1) == val) { 1.83 + val = d; 1.84 + val->set_req(0, NULL); // Unpin now. 1.85 + break; 1.86 + } 1.87 + } 1.88 + } 1.89 +#endif 1.90 + _null_check_tests.push(val); 1.91 + } 1.92 } 1.93 } 1.94 }