Tue, 17 Feb 2009 14:30:24 -0800
Merge
1.1 --- a/src/cpu/sparc/vm/sparc.ad Tue Feb 10 18:39:09 2009 +0300 1.2 +++ b/src/cpu/sparc/vm/sparc.ad Tue Feb 17 14:30:24 2009 -0800 1.3 @@ -762,7 +762,7 @@ 1.4 case Assembler::stdf_op3: st_op = Op_StoreD; break; 1.5 1.6 case Assembler::ldsb_op3: ld_op = Op_LoadB; break; 1.7 - case Assembler::lduh_op3: ld_op = Op_LoadC; break; 1.8 + case Assembler::lduh_op3: ld_op = Op_LoadUS; break; 1.9 case Assembler::ldsh_op3: ld_op = Op_LoadS; break; 1.10 case Assembler::ldx_op3: // may become LoadP or stay LoadI 1.11 case Assembler::ldsw_op3: // may become LoadP or stay LoadI 1.12 @@ -3869,6 +3869,8 @@ 1.13 constraint(ALLOC_IN_RC(dflt_reg)); 1.14 match(RegD); 1.15 1.16 + match(regD_low); 1.17 + 1.18 format %{ %} 1.19 interface(REG_INTER); 1.20 %} 1.21 @@ -3883,7 +3885,7 @@ 1.22 1.23 operand regD_low() %{ 1.24 constraint(ALLOC_IN_RC(dflt_low_reg)); 1.25 - match(RegD); 1.26 + match(regD); 1.27 1.28 format %{ %} 1.29 interface(REG_INTER); 1.30 @@ -5314,9 +5316,9 @@ 1.31 ins_pipe(iload_mask_mem); 1.32 %} 1.33 1.34 -// Load Char (16bit UNsigned) into a Long Register 1.35 -instruct loadUCL(iRegL dst, memory mem, immL_FFFF bytemask) %{ 1.36 - match(Set dst (AndL (ConvI2L (LoadC mem)) bytemask)); 1.37 +// Load Unsigned Short/Char (16bit UNsigned) into a Long Register 1.38 +instruct loadUS2L(iRegL dst, memory mem, immL_FFFF bytemask) %{ 1.39 + match(Set dst (AndL (ConvI2L (LoadUS mem)) bytemask)); 1.40 ins_cost(MEMORY_REF_COST); 1.41 1.42 size(4); 1.43 @@ -5326,9 +5328,9 @@ 1.44 ins_pipe(iload_mask_mem); 1.45 %} 1.46 1.47 -// Load Char (16bit unsigned) 1.48 -instruct loadC(iRegI dst, memory mem) %{ 1.49 - match(Set dst (LoadC mem)); 1.50 +// Load Unsigned Short/Char (16bit unsigned) 1.51 +instruct loadUS(iRegI dst, memory mem) %{ 1.52 + match(Set dst (LoadUS mem)); 1.53 ins_cost(MEMORY_REF_COST); 1.54 1.55 size(4);
2.1 --- a/src/cpu/x86/vm/x86_32.ad Tue Feb 10 18:39:09 2009 +0300 2.2 +++ b/src/cpu/x86/vm/x86_32.ad Tue Feb 17 14:30:24 2009 -0800 2.3 @@ -6413,9 +6413,9 @@ 2.4 ins_pipe( ialu_reg_mem ); 2.5 %} 2.6 2.7 -// Load Char (16bit unsigned) 2.8 -instruct loadC(eRegI dst, memory mem) %{ 2.9 - match(Set dst (LoadC mem)); 2.10 +// Load Unsigned Short/Char (16bit unsigned) 2.11 +instruct loadUS(eRegI dst, memory mem) %{ 2.12 + match(Set dst (LoadUS mem)); 2.13 2.14 ins_cost(125); 2.15 format %{ "MOVZX $dst,$mem" %}
3.1 --- a/src/cpu/x86/vm/x86_64.ad Tue Feb 10 18:39:09 2009 +0300 3.2 +++ b/src/cpu/x86/vm/x86_64.ad Tue Feb 17 14:30:24 2009 -0800 3.3 @@ -6096,25 +6096,25 @@ 3.4 // ins_pipe(ialu_reg_mem); 3.5 // %} 3.6 3.7 -// Load Char (16 bit UNsigned) 3.8 -instruct loadC(rRegI dst, memory mem) 3.9 -%{ 3.10 - match(Set dst (LoadC mem)); 3.11 +// Load Unsigned Short/Char (16 bit UNsigned) 3.12 +instruct loadUS(rRegI dst, memory mem) 3.13 +%{ 3.14 + match(Set dst (LoadUS mem)); 3.15 3.16 ins_cost(125); 3.17 - format %{ "movzwl $dst, $mem\t# char" %} 3.18 + format %{ "movzwl $dst, $mem\t# ushort/char" %} 3.19 opcode(0x0F, 0xB7); 3.20 ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 3.21 ins_pipe(ialu_reg_mem); 3.22 %} 3.23 3.24 -// Load Char (16 bit UNsigned) into long 3.25 -// instruct loadC2L(rRegL dst, memory mem) 3.26 +// Load Unsigned Short/Char (16 bit UNsigned) into long 3.27 +// instruct loadUS2L(rRegL dst, memory mem) 3.28 // %{ 3.29 -// match(Set dst (ConvI2L (LoadC mem))); 3.30 +// match(Set dst (ConvI2L (LoadUS mem))); 3.31 3.32 // ins_cost(125); 3.33 -// format %{ "movzwl $dst, $mem\t# char -> long" %} 3.34 +// format %{ "movzwl $dst, $mem\t# ushort/char -> long" %} 3.35 // opcode(0x0F, 0xB7); 3.36 // ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 3.37 // ins_pipe(ialu_reg_mem); 3.38 @@ -9490,14 +9490,14 @@ 3.39 %{ 3.40 match(Set dst (AndL dst src)); 3.41 3.42 - format %{ "movzbq $dst, $src\t# long & 0xFF" %} 3.43 + format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 3.44 opcode(0x0F, 0xB6); 3.45 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 3.46 ins_pipe(ialu_reg); 3.47 %} 3.48 3.49 // And Register with Immediate 65535 3.50 -instruct andL_rReg_imm65535(rRegI dst, immL_65535 src) 3.51 +instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 3.52 %{ 3.53 match(Set dst (AndL dst src)); 3.54
4.1 --- a/src/share/vm/adlc/dict2.cpp Tue Feb 10 18:39:09 2009 +0300 4.2 +++ b/src/share/vm/adlc/dict2.cpp Tue Feb 17 14:30:24 2009 -0800 4.3 @@ -316,9 +316,12 @@ 4.4 return strcmp((const char *)k1,(const char *)k2); 4.5 } 4.6 4.7 -// Slimey cheap key comparator. 4.8 +// Cheap key comparator. 4.9 int cmpkey(const void *key1, const void *key2) { 4.10 - return (int)((intptr_t)key1 - (intptr_t)key2); 4.11 + if (key1 == key2) return 0; 4.12 + intptr_t delta = (intptr_t)key1 - (intptr_t)key2; 4.13 + if (delta > 0) return 1; 4.14 + return -1; 4.15 } 4.16 4.17 //=============================================================================
5.1 --- a/src/share/vm/adlc/forms.cpp Tue Feb 10 18:39:09 2009 +0300 5.2 +++ b/src/share/vm/adlc/forms.cpp Tue Feb 17 14:30:24 2009 -0800 5.3 @@ -248,7 +248,7 @@ 5.4 // True if 'opType', an ideal name, loads or stores. 5.5 Form::DataType Form::is_load_from_memory(const char *opType) const { 5.6 if( strcmp(opType,"LoadB")==0 ) return Form::idealB; 5.7 - if( strcmp(opType,"LoadC")==0 ) return Form::idealC; 5.8 + if( strcmp(opType,"LoadUS")==0 ) return Form::idealC; 5.9 if( strcmp(opType,"LoadD")==0 ) return Form::idealD; 5.10 if( strcmp(opType,"LoadD_unaligned")==0 ) return Form::idealD; 5.11 if( strcmp(opType,"LoadF")==0 ) return Form::idealF;
6.1 --- a/src/share/vm/adlc/formssel.cpp Tue Feb 10 18:39:09 2009 +0300 6.2 +++ b/src/share/vm/adlc/formssel.cpp Tue Feb 17 14:30:24 2009 -0800 6.3 @@ -3314,7 +3314,7 @@ 6.4 "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" , 6.5 "StoreB","StoreC","Store" ,"StoreFP", 6.6 "LoadI" ,"LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF" , 6.7 - "LoadB" ,"LoadC" ,"LoadS" ,"Load" , 6.8 + "LoadB" ,"LoadUS" ,"LoadS" ,"Load" , 6.9 "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B", 6.10 "Store8B","Store4B","Store8C","Store4C","Store2C", 6.11 "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
7.1 --- a/src/share/vm/asm/codeBuffer.cpp Tue Feb 10 18:39:09 2009 +0300 7.2 +++ b/src/share/vm/asm/codeBuffer.cpp Tue Feb 17 14:30:24 2009 -0800 7.3 @@ -123,6 +123,10 @@ 7.4 // addresses constructed before expansions will not be confused. 7.5 cb->free_blob(); 7.6 } 7.7 + 7.8 + // free any overflow storage 7.9 + delete _overflow_arena; 7.10 + 7.11 #ifdef ASSERT 7.12 Copy::fill_to_bytes(this, sizeof(*this), badResourceValue); 7.13 #endif
8.1 --- a/src/share/vm/classfile/systemDictionary.cpp Tue Feb 10 18:39:09 2009 +0300 8.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Tue Feb 17 14:30:24 2009 -0800 8.3 @@ -846,6 +846,12 @@ 8.4 Handle protection_domain, 8.5 TRAPS) { 8.6 8.7 + // UseNewReflection 8.8 + // The result of this call should be consistent with the result 8.9 + // of the call to resolve_instance_class_or_null(). 8.10 + // See evaluation 6790209 and 4474172 for more details. 8.11 + class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); 8.12 + 8.13 unsigned int d_hash = dictionary()->compute_hash(class_name, class_loader); 8.14 int d_index = dictionary()->hash_to_index(d_hash); 8.15
9.1 --- a/src/share/vm/libadt/dict.cpp Tue Feb 10 18:39:09 2009 +0300 9.2 +++ b/src/share/vm/libadt/dict.cpp Tue Feb 17 14:30:24 2009 -0800 9.3 @@ -346,9 +346,12 @@ 9.4 return strcmp((const char *)k1,(const char *)k2); 9.5 } 9.6 9.7 -// Slimey cheap key comparator. 9.8 +// Cheap key comparator. 9.9 int32 cmpkey(const void *key1, const void *key2) { 9.10 - return (int32)((intptr_t)key1 - (intptr_t)key2); 9.11 + if (key1 == key2) return 0; 9.12 + intptr_t delta = (intptr_t)key1 - (intptr_t)key2; 9.13 + if (delta > 0) return 1; 9.14 + return -1; 9.15 } 9.16 9.17 //=============================================================================
10.1 --- a/src/share/vm/opto/block.cpp Tue Feb 10 18:39:09 2009 +0300 10.2 +++ b/src/share/vm/opto/block.cpp Tue Feb 17 14:30:24 2009 -0800 10.3 @@ -880,6 +880,7 @@ 10.4 } 10.5 10.6 void PhaseCFG::verify( ) const { 10.7 +#ifdef ASSERT 10.8 // Verify sane CFG 10.9 for( uint i = 0; i < _num_blocks; i++ ) { 10.10 Block *b = _blocks[i]; 10.11 @@ -894,10 +895,20 @@ 10.12 "CreateEx must be first instruction in block" ); 10.13 } 10.14 for( uint k = 0; k < n->req(); k++ ) { 10.15 - Node *use = n->in(k); 10.16 - if( use && use != n ) { 10.17 - assert( _bbs[use->_idx] || use->is_Con(), 10.18 + Node *def = n->in(k); 10.19 + if( def && def != n ) { 10.20 + assert( _bbs[def->_idx] || def->is_Con(), 10.21 "must have block; constants for debug info ok" ); 10.22 + // Verify that instructions in the block is in correct order. 10.23 + // Uses must follow their definition if they are at the same block. 10.24 + // Mostly done to check that MachSpillCopy nodes are placed correctly 10.25 + // when CreateEx node is moved in build_ifg_physical(). 10.26 + if( _bbs[def->_idx] == b && 10.27 + !(b->head()->is_Loop() && n->is_Phi()) && 10.28 + // See (+++) comment in reg_split.cpp 10.29 + !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) { 10.30 + assert( b->find_node(def) < j, "uses must follow definitions" ); 10.31 + } 10.32 } 10.33 } 10.34 } 10.35 @@ -914,6 +925,7 @@ 10.36 assert( b->_num_succs == 2, "Conditional branch must have two targets"); 10.37 } 10.38 } 10.39 +#endif 10.40 } 10.41 #endif 10.42
11.1 --- a/src/share/vm/opto/c2_globals.hpp Tue Feb 10 18:39:09 2009 +0300 11.2 +++ b/src/share/vm/opto/c2_globals.hpp Tue Feb 17 14:30:24 2009 -0800 11.3 @@ -191,6 +191,9 @@ 11.4 notproduct(bool, VerifyHashTableKeys, true, \ 11.5 "Verify the immutability of keys in the VN hash tables") \ 11.6 \ 11.7 + notproduct(bool, VerifyRegisterAllocator , false, \ 11.8 + "Verify Register Allocator") \ 11.9 + \ 11.10 develop_pd(intx, FLOATPRESSURE, \ 11.11 "Number of float LRG's that constitute high register pressure") \ 11.12 \
12.1 --- a/src/share/vm/opto/cfgnode.cpp Tue Feb 10 18:39:09 2009 +0300 12.2 +++ b/src/share/vm/opto/cfgnode.cpp Tue Feb 17 14:30:24 2009 -0800 12.3 @@ -858,12 +858,18 @@ 12.4 // convert the one to the other. 12.5 const TypePtr* ttp = _type->make_ptr(); 12.6 const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL; 12.7 + const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL; 12.8 bool is_intf = false; 12.9 if (ttip != NULL) { 12.10 ciKlass* k = ttip->klass(); 12.11 if (k->is_loaded() && k->is_interface()) 12.12 is_intf = true; 12.13 } 12.14 + if (ttkp != NULL) { 12.15 + ciKlass* k = ttkp->klass(); 12.16 + if (k->is_loaded() && k->is_interface()) 12.17 + is_intf = true; 12.18 + } 12.19 12.20 // Default case: merge all inputs 12.21 const Type *t = Type::TOP; // Merged type starting value 12.22 @@ -921,6 +927,8 @@ 12.23 // uplift the type. 12.24 if( !t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface() ) 12.25 { assert(ft == _type, ""); } // Uplift to interface 12.26 + else if( !t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface() ) 12.27 + { assert(ft == _type, ""); } // Uplift to interface 12.28 // Otherwise it's something stupid like non-overlapping int ranges 12.29 // found on dying counted loops. 12.30 else 12.31 @@ -936,6 +944,7 @@ 12.32 // because the type system doesn't interact well with interfaces. 12.33 const TypePtr *jtp = jt->make_ptr(); 12.34 const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL; 12.35 + const TypeKlassPtr *jtkp = (jtp != NULL) ? jtp->isa_klassptr() : NULL; 12.36 if( jtip && ttip ) { 12.37 if( jtip->is_loaded() && jtip->klass()->is_interface() && 12.38 ttip->is_loaded() && !ttip->klass()->is_interface() ) { 12.39 @@ -945,6 +954,14 @@ 12.40 jt = ft; 12.41 } 12.42 } 12.43 + if( jtkp && ttkp ) { 12.44 + if( jtkp->is_loaded() && jtkp->klass()->is_interface() && 12.45 + ttkp->is_loaded() && !ttkp->klass()->is_interface() ) { 12.46 + assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) || 12.47 + ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), ""); 12.48 + jt = ft; 12.49 + } 12.50 + } 12.51 if (jt != ft && jt->base() == ft->base()) { 12.52 if (jt->isa_int() && 12.53 jt->is_int()->_lo == ft->is_int()->_lo &&
13.1 --- a/src/share/vm/opto/chaitin.cpp Tue Feb 10 18:39:09 2009 +0300 13.2 +++ b/src/share/vm/opto/chaitin.cpp Tue Feb 17 14:30:24 2009 -0800 13.3 @@ -228,6 +228,11 @@ 13.4 // them for real. 13.5 de_ssa(); 13.6 13.7 +#ifdef ASSERT 13.8 + // Veify the graph before RA. 13.9 + verify(&live_arena); 13.10 +#endif 13.11 + 13.12 { 13.13 NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); ) 13.14 _live = NULL; // Mark live as being not available 13.15 @@ -306,12 +311,6 @@ 13.16 C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split"); 13.17 if (C->failing()) return; 13.18 13.19 -#ifdef ASSERT 13.20 - if( VerifyOpto ) { 13.21 - _cfg.verify(); 13.22 - verify_base_ptrs(&live_arena); 13.23 - } 13.24 -#endif 13.25 NOT_PRODUCT( C->verify_graph_edges(); ) 13.26 13.27 compact(); // Compact LRGs; return new lower max lrg 13.28 @@ -340,7 +339,7 @@ 13.29 compress_uf_map_for_nodes(); 13.30 13.31 #ifdef ASSERT 13.32 - if( VerifyOpto ) _ifg->verify(this); 13.33 + verify(&live_arena, true); 13.34 #endif 13.35 } else { 13.36 ifg.SquareUp(); 13.37 @@ -376,12 +375,6 @@ 13.38 // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor) 13.39 C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split"); 13.40 if (C->failing()) return; 13.41 -#ifdef ASSERT 13.42 - if( VerifyOpto ) { 13.43 - _cfg.verify(); 13.44 - verify_base_ptrs(&live_arena); 13.45 - } 13.46 -#endif 13.47 13.48 compact(); // Compact LRGs; return new lower max lrg 13.49 13.50 @@ -412,7 +405,7 @@ 13.51 } 13.52 compress_uf_map_for_nodes(); 13.53 #ifdef ASSERT 13.54 - if( VerifyOpto ) _ifg->verify(this); 13.55 + verify(&live_arena, true); 13.56 #endif 13.57 cache_lrg_info(); // Count degree of LRGs 13.58 13.59 @@ -432,6 +425,11 @@ 13.60 // Peephole remove copies 13.61 post_allocate_copy_removal(); 13.62 13.63 +#ifdef ASSERT 13.64 + // Veify the graph after RA. 13.65 + verify(&live_arena); 13.66 +#endif 13.67 + 13.68 // max_reg is past the largest *register* used. 13.69 // Convert that to a frame_slot number. 13.70 if( _max_reg <= _matcher._new_SP ) 13.71 @@ -956,7 +954,7 @@ 13.72 while ((neighbor = elements.next()) != 0) { 13.73 LRG *n = &lrgs(neighbor); 13.74 #ifdef ASSERT 13.75 - if( VerifyOpto ) { 13.76 + if( VerifyOpto || VerifyRegisterAllocator ) { 13.77 assert( _ifg->effective_degree(neighbor) == n->degree(), "" ); 13.78 } 13.79 #endif
14.1 --- a/src/share/vm/opto/chaitin.hpp Tue Feb 10 18:39:09 2009 +0300 14.2 +++ b/src/share/vm/opto/chaitin.hpp Tue Feb 17 14:30:24 2009 -0800 14.3 @@ -491,6 +491,8 @@ 14.4 // Verify that base pointers and derived pointers are still sane 14.5 void verify_base_ptrs( ResourceArea *a ) const; 14.6 14.7 + void verify( ResourceArea *a, bool verify_ifg = false ) const; 14.8 + 14.9 void dump_for_spill_split_recycle() const; 14.10 14.11 public:
15.1 --- a/src/share/vm/opto/classes.hpp Tue Feb 10 18:39:09 2009 +0300 15.2 +++ b/src/share/vm/opto/classes.hpp Tue Feb 17 14:30:24 2009 -0800 15.3 @@ -129,7 +129,7 @@ 15.4 macro(LShiftI) 15.5 macro(LShiftL) 15.6 macro(LoadB) 15.7 -macro(LoadC) 15.8 +macro(LoadUS) 15.9 macro(LoadD) 15.10 macro(LoadD_unaligned) 15.11 macro(LoadF)
16.1 --- a/src/share/vm/opto/compile.cpp Tue Feb 10 18:39:09 2009 +0300 16.2 +++ b/src/share/vm/opto/compile.cpp Tue Feb 17 14:30:24 2009 -0800 16.3 @@ -2005,7 +2005,7 @@ 16.4 case Op_StoreP: 16.5 case Op_StoreN: 16.6 case Op_LoadB: 16.7 - case Op_LoadC: 16.8 + case Op_LoadUS: 16.9 case Op_LoadI: 16.10 case Op_LoadKlass: 16.11 case Op_LoadNKlass:
17.1 --- a/src/share/vm/opto/divnode.cpp Tue Feb 10 18:39:09 2009 +0300 17.2 +++ b/src/share/vm/opto/divnode.cpp Tue Feb 17 14:30:24 2009 -0800 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 17.6 + * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -244,42 +244,73 @@ 17.11 17.12 //---------------------long_by_long_mulhi-------------------------------------- 17.13 // Generate ideal node graph for upper half of a 64 bit x 64 bit multiplication 17.14 -static Node *long_by_long_mulhi( PhaseGVN *phase, Node *dividend, jlong magic_const) { 17.15 +static Node* long_by_long_mulhi(PhaseGVN* phase, Node* dividend, jlong magic_const) { 17.16 // If the architecture supports a 64x64 mulhi, there is 17.17 // no need to synthesize it in ideal nodes. 17.18 if (Matcher::has_match_rule(Op_MulHiL)) { 17.19 - Node *v = phase->longcon(magic_const); 17.20 + Node* v = phase->longcon(magic_const); 17.21 return new (phase->C, 3) MulHiLNode(dividend, v); 17.22 } 17.23 17.24 + // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed. 17.25 + // (http://www.hackersdelight.org/HDcode/mulhs.c) 17.26 + // 17.27 + // int mulhs(int u, int v) { 17.28 + // unsigned u0, v0, w0; 17.29 + // int u1, v1, w1, w2, t; 17.30 + // 17.31 + // u0 = u & 0xFFFF; u1 = u >> 16; 17.32 + // v0 = v & 0xFFFF; v1 = v >> 16; 17.33 + // w0 = u0*v0; 17.34 + // t = u1*v0 + (w0 >> 16); 17.35 + // w1 = t & 0xFFFF; 17.36 + // w2 = t >> 16; 17.37 + // w1 = u0*v1 + w1; 17.38 + // return u1*v1 + w2 + (w1 >> 16); 17.39 + // } 17.40 + // 17.41 + // Note: The version above is for 32x32 multiplications, while the 17.42 + // following inline comments are adapted to 64x64. 17.43 + 17.44 const int N = 64; 17.45 17.46 - Node *u_hi = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2))); 17.47 - Node *u_lo = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); 17.48 + // u0 = u & 0xFFFFFFFF; u1 = u >> 32; 17.49 + Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF))); 17.50 + Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2))); 17.51 17.52 - Node *v_hi = phase->longcon(magic_const >> N/2); 17.53 - Node *v_lo = phase->longcon(magic_const & 0XFFFFFFFF); 17.54 + // v0 = v & 0xFFFFFFFF; v1 = v >> 32; 17.55 + Node* v0 = phase->longcon(magic_const & 0xFFFFFFFF); 17.56 + Node* v1 = phase->longcon(magic_const >> (N / 2)); 17.57 17.58 - Node *hihi_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_hi)); 17.59 - Node *hilo_product = phase->transform(new (phase->C, 3) MulLNode(u_hi, v_lo)); 17.60 - Node *lohi_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_hi)); 17.61 - Node *lolo_product = phase->transform(new (phase->C, 3) MulLNode(u_lo, v_lo)); 17.62 + // w0 = u0*v0; 17.63 + Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0)); 17.64 17.65 - Node *t1 = phase->transform(new (phase->C, 3) URShiftLNode(lolo_product, phase->intcon(N / 2))); 17.66 - Node *t2 = phase->transform(new (phase->C, 3) AddLNode(hilo_product, t1)); 17.67 + // t = u1*v0 + (w0 >> 32); 17.68 + Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0)); 17.69 + Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2))); 17.70 + Node* t = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp)); 17.71 17.72 - // Construct both t3 and t4 before transforming so t2 doesn't go dead 17.73 - // prematurely. 17.74 - Node *t3 = new (phase->C, 3) RShiftLNode(t2, phase->intcon(N / 2)); 17.75 - Node *t4 = new (phase->C, 3) AndLNode(t2, phase->longcon(0xFFFFFFFF)); 17.76 - t3 = phase->transform(t3); 17.77 - t4 = phase->transform(t4); 17.78 + // w1 = t & 0xFFFFFFFF; 17.79 + Node* w1 = new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF)); 17.80 17.81 - Node *t5 = phase->transform(new (phase->C, 3) AddLNode(t4, lohi_product)); 17.82 - Node *t6 = phase->transform(new (phase->C, 3) RShiftLNode(t5, phase->intcon(N / 2))); 17.83 - Node *t7 = phase->transform(new (phase->C, 3) AddLNode(t3, hihi_product)); 17.84 + // w2 = t >> 32; 17.85 + Node* w2 = new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2)); 17.86 17.87 - return new (phase->C, 3) AddLNode(t7, t6); 17.88 + // 6732154: Construct both w1 and w2 before transforming, so t 17.89 + // doesn't go dead prematurely. 17.90 + w1 = phase->transform(w1); 17.91 + w2 = phase->transform(w2); 17.92 + 17.93 + // w1 = u0*v1 + w1; 17.94 + Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1)); 17.95 + w1 = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1)); 17.96 + 17.97 + // return u1*v1 + w2 + (w1 >> 32); 17.98 + Node* u1v1 = phase->transform(new (phase->C, 3) MulLNode(u1, v1)); 17.99 + Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2)); 17.100 + Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2))); 17.101 + 17.102 + return new (phase->C, 3) AddLNode(temp1, temp2); 17.103 } 17.104 17.105 17.106 @@ -976,7 +1007,7 @@ 17.107 17.108 // Expand mod 17.109 if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) { 17.110 - uint k = log2_long(con); // Extract k 17.111 + uint k = exact_log2_long(con+1); // Extract k 17.112 17.113 // Basic algorithm by David Detlefs. See fastmod_long.java for gory details. 17.114 // Used to help a popular random number generator which does a long-mod
18.1 --- a/src/share/vm/opto/gcm.cpp Tue Feb 10 18:39:09 2009 +0300 18.2 +++ b/src/share/vm/opto/gcm.cpp Tue Feb 17 14:30:24 2009 -0800 18.3 @@ -29,6 +29,9 @@ 18.4 #include "incls/_precompiled.incl" 18.5 #include "incls/_gcm.cpp.incl" 18.6 18.7 +// To avoid float value underflow 18.8 +#define MIN_BLOCK_FREQUENCY 1.e-35f 18.9 + 18.10 //----------------------------schedule_node_into_block------------------------- 18.11 // Insert node n into block b. Look for projections of n and make sure they 18.12 // are in b also. 18.13 @@ -1380,6 +1383,13 @@ 18.14 } 18.15 } 18.16 18.17 +#ifdef ASSERT 18.18 + for (uint i = 0; i < _num_blocks; i++ ) { 18.19 + Block *b = _blocks[i]; 18.20 + assert(b->_freq >= MIN_BLOCK_FREQUENCY, "Register Allocator requiers meaningful block frequency"); 18.21 + } 18.22 +#endif 18.23 + 18.24 #ifndef PRODUCT 18.25 if (PrintCFGBlockFreq) { 18.26 tty->print_cr("CFG Block Frequencies"); 18.27 @@ -1877,7 +1887,9 @@ 18.28 float loop_freq = _freq * trip_count(); 18.29 for (int i = 0; i < _members.length(); i++) { 18.30 CFGElement* s = _members.at(i); 18.31 - s->_freq *= loop_freq; 18.32 + float block_freq = s->_freq * loop_freq; 18.33 + if (block_freq < MIN_BLOCK_FREQUENCY) block_freq = MIN_BLOCK_FREQUENCY; 18.34 + s->_freq = block_freq; 18.35 } 18.36 CFGLoop* ch = _child; 18.37 while (ch != NULL) {
19.1 --- a/src/share/vm/opto/graphKit.cpp Tue Feb 10 18:39:09 2009 +0300 19.2 +++ b/src/share/vm/opto/graphKit.cpp Tue Feb 17 14:30:24 2009 -0800 19.3 @@ -1836,10 +1836,7 @@ 19.4 (CardTableModRefBS*)(Universe::heap()->barrier_set()); 19.5 Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) )); 19.6 // We store into a byte array, so do not bother to left-shift by zero 19.7 - // Get base of card map 19.8 - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), 19.9 - "adjust this code"); 19.10 - Node *c = makecon(TypeRawPtr::make((address)ct->byte_map_base)); 19.11 + Node *c = byte_map_base_node(); 19.12 // Combine 19.13 Node *sb_ctl = control(); 19.14 Node *sb_adr = _gvn.transform(new (C, 4) AddPNode( top()/*no base ptr*/, c, b )); 19.15 @@ -2945,16 +2942,10 @@ 19.16 19.17 // Now generate allocation code 19.18 19.19 - // With escape analysis, the entire memory state is needed to be able to 19.20 - // eliminate the allocation. If the allocations cannot be eliminated, this 19.21 - // will be optimized to the raw slice when the allocation is expanded. 19.22 - Node *mem; 19.23 - if (C->do_escape_analysis()) { 19.24 - mem = reset_memory(); 19.25 - set_all_memory(mem); 19.26 - } else { 19.27 - mem = memory(Compile::AliasIdxRaw); 19.28 - } 19.29 + // The entire memory state is needed for slow path of the allocation 19.30 + // since GC and deoptimization can happened. 19.31 + Node *mem = reset_memory(); 19.32 + set_all_memory(mem); // Create new memory state 19.33 19.34 AllocateNode* alloc 19.35 = new (C, AllocateNode::ParmLimit) 19.36 @@ -3091,16 +3082,10 @@ 19.37 19.38 // Now generate allocation code 19.39 19.40 - // With escape analysis, the entire memory state is needed to be able to 19.41 - // eliminate the allocation. If the allocations cannot be eliminated, this 19.42 - // will be optimized to the raw slice when the allocation is expanded. 19.43 - Node *mem; 19.44 - if (C->do_escape_analysis()) { 19.45 - mem = reset_memory(); 19.46 - set_all_memory(mem); 19.47 - } else { 19.48 - mem = memory(Compile::AliasIdxRaw); 19.49 - } 19.50 + // The entire memory state is needed for slow path of the allocation 19.51 + // since GC and deoptimization can happened. 19.52 + Node *mem = reset_memory(); 19.53 + set_all_memory(mem); // Create new memory state 19.54 19.55 // Create the AllocateArrayNode and its result projections 19.56 AllocateArrayNode* alloc 19.57 @@ -3365,14 +3350,6 @@ 19.58 19.59 const TypeFunc *tf = OptoRuntime::g1_wb_post_Type(); 19.60 19.61 - // Get the address of the card table 19.62 - CardTableModRefBS* ct = 19.63 - (CardTableModRefBS*)(Universe::heap()->barrier_set()); 19.64 - Node *card_table = __ makecon(TypeRawPtr::make((address)ct->byte_map_base)); 19.65 - // Get base of card map 19.66 - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); 19.67 - 19.68 - 19.69 // Offsets into the thread 19.70 const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() + 19.71 PtrQueue::byte_offset_of_index()); 19.72 @@ -3402,7 +3379,7 @@ 19.73 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) ); 19.74 19.75 // Combine card table base and card offset 19.76 - Node *card_adr = __ AddP(no_base, card_table, card_offset ); 19.77 + Node *card_adr = __ AddP(no_base, byte_map_base_node(), card_offset ); 19.78 19.79 // If we know the value being stored does it cross regions? 19.80
20.1 --- a/src/share/vm/opto/graphKit.hpp Tue Feb 10 18:39:09 2009 +0300 20.2 +++ b/src/share/vm/opto/graphKit.hpp Tue Feb 17 14:30:24 2009 -0800 20.3 @@ -83,6 +83,18 @@ 20.4 Node* zerocon(BasicType bt) const { return _gvn.zerocon(bt); } 20.5 // (See also macro MakeConX in type.hpp, which uses intcon or longcon.) 20.6 20.7 + // Helper for byte_map_base 20.8 + Node* byte_map_base_node() { 20.9 + // Get base of card map 20.10 + CardTableModRefBS* ct = (CardTableModRefBS*)(Universe::heap()->barrier_set()); 20.11 + assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust users of this code"); 20.12 + if (ct->byte_map_base != NULL) { 20.13 + return makecon(TypeRawPtr::make((address)ct->byte_map_base)); 20.14 + } else { 20.15 + return null(); 20.16 + } 20.17 + } 20.18 + 20.19 jint find_int_con(Node* n, jint value_if_unknown) { 20.20 return _gvn.find_int_con(n, value_if_unknown); 20.21 }
21.1 --- a/src/share/vm/opto/ifg.cpp Tue Feb 10 18:39:09 2009 +0300 21.2 +++ b/src/share/vm/opto/ifg.cpp Tue Feb 17 14:30:24 2009 -0800 21.3 @@ -471,12 +471,28 @@ 21.4 // for the "collect_gc_info" phase later. 21.5 IndexSet liveout(_live->live(b)); 21.6 uint last_inst = b->end_idx(); 21.7 - // Compute last phi index 21.8 - uint last_phi; 21.9 - for( last_phi = 1; last_phi < last_inst; last_phi++ ) 21.10 - if( !b->_nodes[last_phi]->is_Phi() ) 21.11 + // Compute first nonphi node index 21.12 + uint first_inst; 21.13 + for( first_inst = 1; first_inst < last_inst; first_inst++ ) 21.14 + if( !b->_nodes[first_inst]->is_Phi() ) 21.15 break; 21.16 21.17 + // Spills could be inserted before CreateEx node which should be 21.18 + // first instruction in block after Phis. Move CreateEx up. 21.19 + for( uint insidx = first_inst; insidx < last_inst; insidx++ ) { 21.20 + Node *ex = b->_nodes[insidx]; 21.21 + if( ex->is_SpillCopy() ) continue; 21.22 + if( insidx > first_inst && ex->is_Mach() && 21.23 + ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) { 21.24 + // If the CreateEx isn't above all the MachSpillCopies 21.25 + // then move it to the top. 21.26 + b->_nodes.remove(insidx); 21.27 + b->_nodes.insert(first_inst, ex); 21.28 + } 21.29 + // Stop once a CreateEx or any other node is found 21.30 + break; 21.31 + } 21.32 + 21.33 // Reset block's register pressure values for each ifg construction 21.34 uint pressure[2], hrp_index[2]; 21.35 pressure[0] = pressure[1] = 0; 21.36 @@ -485,7 +501,7 @@ 21.37 // Liveout things are presumed live for the whole block. We accumulate 21.38 // 'area' accordingly. If they get killed in the block, we'll subtract 21.39 // the unused part of the block from the area. 21.40 - int inst_count = last_inst - last_phi; 21.41 + int inst_count = last_inst - first_inst; 21.42 double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count); 21.43 assert(!(cost < 0.0), "negative spill cost" ); 21.44 IndexSetIterator elements(&liveout);
22.1 --- a/src/share/vm/opto/lcm.cpp Tue Feb 10 18:39:09 2009 +0300 22.2 +++ b/src/share/vm/opto/lcm.cpp Tue Feb 17 14:30:24 2009 -0800 22.3 @@ -107,7 +107,7 @@ 22.4 was_store = false; 22.5 switch( mach->ideal_Opcode() ) { 22.6 case Op_LoadB: 22.7 - case Op_LoadC: 22.8 + case Op_LoadUS: 22.9 case Op_LoadD: 22.10 case Op_LoadF: 22.11 case Op_LoadI:
23.1 --- a/src/share/vm/opto/live.cpp Tue Feb 10 18:39:09 2009 +0300 23.2 +++ b/src/share/vm/opto/live.cpp Tue Feb 17 14:30:24 2009 -0800 23.3 @@ -271,9 +271,9 @@ 23.4 23.5 //------------------------------verify_base_ptrs------------------------------- 23.6 // Verify that base pointers and derived pointers are still sane. 23.7 -// Basically, if a derived pointer is live at a safepoint, then its 23.8 -// base pointer must be live also. 23.9 void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const { 23.10 +#ifdef ASSERT 23.11 + Unique_Node_List worklist(a); 23.12 for( uint i = 0; i < _cfg._num_blocks; i++ ) { 23.13 Block *b = _cfg._blocks[i]; 23.14 for( uint j = b->end_idx() + 1; j > 1; j-- ) { 23.15 @@ -287,28 +287,81 @@ 23.16 // Now scan for a live derived pointer 23.17 if (jvms->oopoff() < sfpt->req()) { 23.18 // Check each derived/base pair 23.19 - for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx += 2) { 23.20 + for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) { 23.21 Node *check = sfpt->in(idx); 23.22 - uint j = 0; 23.23 + bool is_derived = ((idx - jvms->oopoff()) & 1) == 0; 23.24 // search upwards through spills and spill phis for AddP 23.25 - while(true) { 23.26 - if( !check ) break; 23.27 - int idx = check->is_Copy(); 23.28 - if( idx ) { 23.29 - check = check->in(idx); 23.30 - } else if( check->is_Phi() && check->_idx >= _oldphi ) { 23.31 - check = check->in(1); 23.32 - } else 23.33 - break; 23.34 - j++; 23.35 - assert(j < 100000,"Derived pointer checking in infinite loop"); 23.36 + worklist.clear(); 23.37 + worklist.push(check); 23.38 + uint k = 0; 23.39 + while( k < worklist.size() ) { 23.40 + check = worklist.at(k); 23.41 + assert(check,"Bad base or derived pointer"); 23.42 + // See PhaseChaitin::find_base_for_derived() for all cases. 23.43 + int isc = check->is_Copy(); 23.44 + if( isc ) { 23.45 + worklist.push(check->in(isc)); 23.46 + } else if( check->is_Phi() ) { 23.47 + for (uint m = 1; m < check->req(); m++) 23.48 + worklist.push(check->in(m)); 23.49 + } else if( check->is_Con() ) { 23.50 + if (is_derived) { 23.51 + // Derived is NULL+offset 23.52 + assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer"); 23.53 + } else { 23.54 + assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer"); 23.55 + // Base either ConP(NULL) or loadConP 23.56 + if (check->is_Mach()) { 23.57 + assert(check->as_Mach()->ideal_Opcode() == Op_ConP,"Bad base pointer"); 23.58 + } else { 23.59 + assert(check->Opcode() == Op_ConP && 23.60 + check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer"); 23.61 + } 23.62 + } 23.63 + } else if( check->bottom_type()->is_ptr()->_offset == 0 ) { 23.64 + if(check->is_Proj() || check->is_Mach() && 23.65 + (check->as_Mach()->ideal_Opcode() == Op_CreateEx || 23.66 + check->as_Mach()->ideal_Opcode() == Op_ThreadLocal || 23.67 + check->as_Mach()->ideal_Opcode() == Op_CMoveP || 23.68 + check->as_Mach()->ideal_Opcode() == Op_CheckCastPP || 23.69 +#ifdef _LP64 23.70 + UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP || 23.71 + UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN || 23.72 +#endif 23.73 + check->as_Mach()->ideal_Opcode() == Op_LoadP || 23.74 + check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) { 23.75 + // Valid nodes 23.76 + } else { 23.77 + check->dump(); 23.78 + assert(false,"Bad base or derived pointer"); 23.79 + } 23.80 + } else { 23.81 + assert(is_derived,"Bad base pointer"); 23.82 + assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer"); 23.83 + } 23.84 + k++; 23.85 + assert(k < 100000,"Derived pointer checking in infinite loop"); 23.86 } // End while 23.87 - assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer") 23.88 } 23.89 } // End of check for derived pointers 23.90 } // End of Kcheck for debug info 23.91 } // End of if found a safepoint 23.92 } // End of forall instructions in block 23.93 } // End of forall blocks 23.94 +#endif 23.95 } 23.96 + 23.97 +//------------------------------verify------------------------------------- 23.98 +// Verify that graphs and base pointers are still sane. 23.99 +void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const { 23.100 +#ifdef ASSERT 23.101 + if( VerifyOpto || VerifyRegisterAllocator ) { 23.102 + _cfg.verify(); 23.103 + verify_base_ptrs(a); 23.104 + if(verify_ifg) 23.105 + _ifg->verify(this); 23.106 + } 23.107 #endif 23.108 +} 23.109 + 23.110 +#endif
24.1 --- a/src/share/vm/opto/loopnode.cpp Tue Feb 10 18:39:09 2009 +0300 24.2 +++ b/src/share/vm/opto/loopnode.cpp Tue Feb 17 14:30:24 2009 -0800 24.3 @@ -2654,7 +2654,7 @@ 24.4 case Op_ModF: 24.5 case Op_ModD: 24.6 case Op_LoadB: // Same with Loads; they can sink 24.7 - case Op_LoadC: // during loop optimizations. 24.8 + case Op_LoadUS: // during loop optimizations. 24.9 case Op_LoadD: 24.10 case Op_LoadF: 24.11 case Op_LoadI:
25.1 --- a/src/share/vm/opto/macro.cpp Tue Feb 10 18:39:09 2009 +0300 25.2 +++ b/src/share/vm/opto/macro.cpp Tue Feb 17 14:30:24 2009 -0800 25.3 @@ -952,13 +952,6 @@ 25.4 Node* klass_node = alloc->in(AllocateNode::KlassNode); 25.5 Node* initial_slow_test = alloc->in(AllocateNode::InitialTest); 25.6 25.7 - // With escape analysis, the entire memory state was needed to be able to 25.8 - // eliminate the allocation. Since the allocations cannot be eliminated, 25.9 - // optimize it to the raw slice. 25.10 - if (mem->is_MergeMem()) { 25.11 - mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw); 25.12 - } 25.13 - 25.14 assert(ctrl != NULL, "must have control"); 25.15 // We need a Region and corresponding Phi's to merge the slow-path and fast-path results. 25.16 // they will not be used if "always_slow" is set 25.17 @@ -1016,6 +1009,11 @@ 25.18 Node *slow_mem = mem; // save the current memory state for slow path 25.19 // generate the fast allocation code unless we know that the initial test will always go slow 25.20 if (!always_slow) { 25.21 + // Fast path modifies only raw memory. 25.22 + if (mem->is_MergeMem()) { 25.23 + mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw); 25.24 + } 25.25 + 25.26 Node* eden_top_adr; 25.27 Node* eden_end_adr; 25.28 25.29 @@ -1239,8 +1237,6 @@ 25.30 } 25.31 } 25.32 25.33 - mem = result_phi_rawmem; 25.34 - 25.35 // An allocate node has separate i_o projections for the uses on the control and i_o paths 25.36 // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call) 25.37 if (_ioproj_fallthrough == NULL) {
26.1 --- a/src/share/vm/opto/matcher.cpp Tue Feb 10 18:39:09 2009 +0300 26.2 +++ b/src/share/vm/opto/matcher.cpp Tue Feb 17 14:30:24 2009 -0800 26.3 @@ -1824,7 +1824,7 @@ 26.4 mem_op = true; 26.5 break; 26.6 case Op_LoadB: 26.7 - case Op_LoadC: 26.8 + case Op_LoadUS: 26.9 case Op_LoadD: 26.10 case Op_LoadF: 26.11 case Op_LoadI:
27.1 --- a/src/share/vm/opto/memnode.cpp Tue Feb 10 18:39:09 2009 +0300 27.2 +++ b/src/share/vm/opto/memnode.cpp Tue Feb 17 14:30:24 2009 -0800 27.3 @@ -779,14 +779,14 @@ 27.4 "use LoadRangeNode instead"); 27.5 switch (bt) { 27.6 case T_BOOLEAN: 27.7 - case T_BYTE: return new (C, 3) LoadBNode(ctl, mem, adr, adr_type, rt->is_int() ); 27.8 - case T_INT: return new (C, 3) LoadINode(ctl, mem, adr, adr_type, rt->is_int() ); 27.9 - case T_CHAR: return new (C, 3) LoadCNode(ctl, mem, adr, adr_type, rt->is_int() ); 27.10 - case T_SHORT: return new (C, 3) LoadSNode(ctl, mem, adr, adr_type, rt->is_int() ); 27.11 - case T_LONG: return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long() ); 27.12 - case T_FLOAT: return new (C, 3) LoadFNode(ctl, mem, adr, adr_type, rt ); 27.13 - case T_DOUBLE: return new (C, 3) LoadDNode(ctl, mem, adr, adr_type, rt ); 27.14 - case T_ADDRESS: return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_ptr() ); 27.15 + case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); 27.16 + case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() ); 27.17 + case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() ); 27.18 + case T_SHORT: return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() ); 27.19 + case T_LONG: return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() ); 27.20 + case T_FLOAT: return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt ); 27.21 + case T_DOUBLE: return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt ); 27.22 + case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr() ); 27.23 case T_OBJECT: 27.24 #ifdef _LP64 27.25 if (adr->bottom_type()->is_ptr_to_narrowoop()) { 27.26 @@ -1076,13 +1076,14 @@ 27.27 // of the original value. 27.28 Node* mem_phi = in(Memory); 27.29 Node* offset = in(Address)->in(AddPNode::Offset); 27.30 + Node* region = base->in(0); 27.31 27.32 Node* in1 = clone(); 27.33 Node* in1_addr = in1->in(Address)->clone(); 27.34 in1_addr->set_req(AddPNode::Base, base->in(allocation_index)); 27.35 in1_addr->set_req(AddPNode::Address, base->in(allocation_index)); 27.36 in1_addr->set_req(AddPNode::Offset, offset); 27.37 - in1->set_req(0, base->in(allocation_index)); 27.38 + in1->set_req(0, region->in(allocation_index)); 27.39 in1->set_req(Address, in1_addr); 27.40 in1->set_req(Memory, mem_phi->in(allocation_index)); 27.41 27.42 @@ -1091,7 +1092,7 @@ 27.43 in2_addr->set_req(AddPNode::Base, base->in(load_index)); 27.44 in2_addr->set_req(AddPNode::Address, base->in(load_index)); 27.45 in2_addr->set_req(AddPNode::Offset, offset); 27.46 - in2->set_req(0, base->in(load_index)); 27.47 + in2->set_req(0, region->in(load_index)); 27.48 in2->set_req(Address, in2_addr); 27.49 in2->set_req(Memory, mem_phi->in(load_index)); 27.50 27.51 @@ -1100,7 +1101,7 @@ 27.52 in2_addr = phase->transform(in2_addr); 27.53 in2 = phase->transform(in2); 27.54 27.55 - PhiNode* result = PhiNode::make_blank(base->in(0), this); 27.56 + PhiNode* result = PhiNode::make_blank(region, this); 27.57 result->set_req(allocation_index, in1); 27.58 result->set_req(load_index, in2); 27.59 return result; 27.60 @@ -1357,7 +1358,7 @@ 27.61 // Steps (a), (b): Walk past independent stores to find an exact match. 27.62 if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) { 27.63 // (c) See if we can fold up on the spot, but don't fold up here. 27.64 - // Fold-up might require truncation (for LoadB/LoadS/LoadC) or 27.65 + // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or 27.66 // just return a prior value, which is done by Identity calls. 27.67 if (can_see_stored_value(prev_mem, phase)) { 27.68 // Make ready for step (d): 27.69 @@ -1606,14 +1607,14 @@ 27.70 return LoadNode::Ideal(phase, can_reshape); 27.71 } 27.72 27.73 -//--------------------------LoadCNode::Ideal-------------------------------------- 27.74 +//--------------------------LoadUSNode::Ideal------------------------------------- 27.75 // 27.76 // If the previous store is to the same address as this load, 27.77 // and the value stored was larger than a char, replace this load 27.78 // with the value stored truncated to a char. If no truncation is 27.79 // needed, the replacement is done in LoadNode::Identity(). 27.80 // 27.81 -Node *LoadCNode::Ideal(PhaseGVN *phase, bool can_reshape) { 27.82 +Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) { 27.83 Node* mem = in(MemNode::Memory); 27.84 Node* value = can_see_stored_value(mem,phase); 27.85 if( value && !phase->type(value)->higher_equal( _type ) )
28.1 --- a/src/share/vm/opto/memnode.hpp Tue Feb 10 18:39:09 2009 +0300 28.2 +++ b/src/share/vm/opto/memnode.hpp Tue Feb 17 14:30:24 2009 -0800 28.3 @@ -207,11 +207,11 @@ 28.4 virtual BasicType memory_type() const { return T_BYTE; } 28.5 }; 28.6 28.7 -//------------------------------LoadCNode-------------------------------------- 28.8 -// Load a char (16bits unsigned) from memory 28.9 -class LoadCNode : public LoadNode { 28.10 +//------------------------------LoadUSNode------------------------------------- 28.11 +// Load an unsigned short/char (16bits unsigned) from memory 28.12 +class LoadUSNode : public LoadNode { 28.13 public: 28.14 - LoadCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR ) 28.15 + LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR ) 28.16 : LoadNode(c,mem,adr,at,ti) {} 28.17 virtual int Opcode() const; 28.18 virtual uint ideal_reg() const { return Op_RegI; }
29.1 --- a/src/share/vm/opto/mulnode.cpp Tue Feb 10 18:39:09 2009 +0300 29.2 +++ b/src/share/vm/opto/mulnode.cpp Tue Feb 17 14:30:24 2009 -0800 29.3 @@ -1,5 +1,5 @@ 29.4 /* 29.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 29.6 + * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 29.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.8 * 29.9 * This code is free software; you can redistribute it and/or modify it 29.10 @@ -442,16 +442,17 @@ 29.11 return load; 29.12 } 29.13 uint lop = load->Opcode(); 29.14 - if( lop == Op_LoadC && 29.15 + if( lop == Op_LoadUS && 29.16 con == 0x0000FFFF ) // Already zero-extended 29.17 return load; 29.18 // Masking off the high bits of a unsigned-shift-right is not 29.19 // needed either. 29.20 if( lop == Op_URShiftI ) { 29.21 const TypeInt *t12 = phase->type( load->in(2) )->isa_int(); 29.22 - if( t12 && t12->is_con() ) { 29.23 - int shift_con = t12->get_con(); 29.24 - int mask = max_juint >> shift_con; 29.25 + if( t12 && t12->is_con() ) { // Shift is by a constant 29.26 + int shift = t12->get_con(); 29.27 + shift &= BitsPerJavaInteger - 1; // semantics of Java shifts 29.28 + int mask = max_juint >> shift; 29.29 if( (mask&con) == mask ) // If AND is useless, skip it 29.30 return load; 29.31 } 29.32 @@ -470,19 +471,19 @@ 29.33 uint lop = load->Opcode(); 29.34 29.35 // Masking bits off of a Character? Hi bits are already zero. 29.36 - if( lop == Op_LoadC && 29.37 + if( lop == Op_LoadUS && 29.38 (mask & 0xFFFF0000) ) // Can we make a smaller mask? 29.39 return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF)); 29.40 29.41 // Masking bits off of a Short? Loading a Character does some masking 29.42 if( lop == Op_LoadS && 29.43 (mask & 0xFFFF0000) == 0 ) { 29.44 - Node *ldc = new (phase->C, 3) LoadCNode(load->in(MemNode::Control), 29.45 + Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control), 29.46 load->in(MemNode::Memory), 29.47 load->in(MemNode::Address), 29.48 load->adr_type()); 29.49 - ldc = phase->transform(ldc); 29.50 - return new (phase->C, 3) AndINode(ldc,phase->intcon(mask&0xFFFF)); 29.51 + ldus = phase->transform(ldus); 29.52 + return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF)); 29.53 } 29.54 29.55 // Masking sign bits off of a Byte? Let the matcher use an unsigned load 29.56 @@ -579,9 +580,10 @@ 29.57 // needed either. 29.58 if( lop == Op_URShiftL ) { 29.59 const TypeInt *t12 = phase->type( usr->in(2) )->isa_int(); 29.60 - if( t12 && t12->is_con() ) { 29.61 - int shift_con = t12->get_con(); 29.62 - jlong mask = max_julong >> shift_con; 29.63 + if( t12 && t12->is_con() ) { // Shift is by a constant 29.64 + int shift = t12->get_con(); 29.65 + shift &= BitsPerJavaLong - 1; // semantics of Java shifts 29.66 + jlong mask = max_julong >> shift; 29.67 if( (mask&con) == mask ) // If AND is useless, skip it 29.68 return usr; 29.69 } 29.70 @@ -605,8 +607,8 @@ 29.71 const TypeInt *t12 = phase->type(rsh->in(2))->isa_int(); 29.72 if( t12 && t12->is_con() ) { // Shift is by a constant 29.73 int shift = t12->get_con(); 29.74 - shift &= (BitsPerJavaInteger*2)-1; // semantics of Java shifts 29.75 - const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - shift)) -1); 29.76 + shift &= BitsPerJavaLong - 1; // semantics of Java shifts 29.77 + const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1); 29.78 // If the AND'ing of the 2 masks has no bits, then only original shifted 29.79 // bits survive. NO sign-extension bits survive the maskings. 29.80 if( (sign_bits_mask & mask) == 0 ) { 29.81 @@ -786,7 +788,7 @@ 29.82 29.83 // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits 29.84 // before shifting them away. 29.85 - const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) - CONST64(1); 29.86 + const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1); 29.87 if( add1_op == Op_AndL && 29.88 phase->type(add1->in(2)) == TypeLong::make( bits_mask ) ) 29.89 return new (phase->C, 3) LShiftLNode( add1->in(1), in(2) ); 29.90 @@ -820,7 +822,7 @@ 29.91 return TypeLong::LONG; 29.92 29.93 uint shift = r2->get_con(); 29.94 - shift &= (BitsPerJavaInteger*2)-1; // semantics of Java shifts 29.95 + shift &= BitsPerJavaLong - 1; // semantics of Java shifts 29.96 // Shift by a multiple of 64 does nothing: 29.97 if (shift == 0) return t1; 29.98 29.99 @@ -913,7 +915,7 @@ 29.100 set_req(2, phase->intcon(0)); 29.101 return this; 29.102 } 29.103 - else if( ld->Opcode() == Op_LoadC ) 29.104 + else if( ld->Opcode() == Op_LoadUS ) 29.105 // Replace zero-extension-load with sign-extension-load 29.106 return new (phase->C, 3) LoadSNode( ld->in(MemNode::Control), 29.107 ld->in(MemNode::Memory), 29.108 @@ -1235,7 +1237,7 @@ 29.109 if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count 29.110 // note: mask computation below does not work for 0 shift count 29.111 // We'll be wanting the right-shift amount as a mask of that many bits 29.112 - const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaInteger*2 - con)) -1); 29.113 + const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) -1); 29.114 29.115 // Check for ((x << z) + Y) >>> z. Replace with x + con>>>z 29.116 // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z". 29.117 @@ -1302,7 +1304,7 @@ 29.118 29.119 if (r2->is_con()) { 29.120 uint shift = r2->get_con(); 29.121 - shift &= (2*BitsPerJavaInteger)-1; // semantics of Java shifts 29.122 + shift &= BitsPerJavaLong - 1; // semantics of Java shifts 29.123 // Shift by a multiple of 64 does nothing: 29.124 if (shift == 0) return t1; 29.125 // Calculate reasonably aggressive bounds for the result. 29.126 @@ -1325,7 +1327,7 @@ 29.127 const TypeLong* tl = TypeLong::make(lo, hi, MAX2(r1->_widen,r2->_widen)); 29.128 #ifdef ASSERT 29.129 // Make sure we get the sign-capture idiom correct. 29.130 - if (shift == (2*BitsPerJavaInteger)-1) { 29.131 + if (shift == BitsPerJavaLong - 1) { 29.132 if (r1->_lo >= 0) assert(tl == TypeLong::ZERO, ">>>63 of + is 0"); 29.133 if (r1->_hi < 0) assert(tl == TypeLong::ONE, ">>>63 of - is +1"); 29.134 }
30.1 --- a/src/share/vm/opto/superword.cpp Tue Feb 10 18:39:09 2009 +0300 30.2 +++ b/src/share/vm/opto/superword.cpp Tue Feb 17 14:30:24 2009 -0800 30.3 @@ -1444,7 +1444,7 @@ 30.4 // (Start, end] half-open range defining which operands are vector 30.5 void SuperWord::vector_opd_range(Node* n, uint* start, uint* end) { 30.6 switch (n->Opcode()) { 30.7 - case Op_LoadB: case Op_LoadC: 30.8 + case Op_LoadB: case Op_LoadUS: 30.9 case Op_LoadI: case Op_LoadL: 30.10 case Op_LoadF: case Op_LoadD: 30.11 case Op_LoadP:
31.1 --- a/src/share/vm/opto/type.cpp Tue Feb 10 18:39:09 2009 +0300 31.2 +++ b/src/share/vm/opto/type.cpp Tue Feb 17 14:30:24 2009 -0800 31.3 @@ -2471,6 +2471,8 @@ 31.4 const Type* ft = join(kills); 31.5 const TypeInstPtr* ftip = ft->isa_instptr(); 31.6 const TypeInstPtr* ktip = kills->isa_instptr(); 31.7 + const TypeKlassPtr* ftkp = ft->isa_klassptr(); 31.8 + const TypeKlassPtr* ktkp = kills->isa_klassptr(); 31.9 31.10 if (ft->empty()) { 31.11 // Check for evil case of 'this' being a class and 'kills' expecting an 31.12 @@ -2484,6 +2486,8 @@ 31.13 // uplift the type. 31.14 if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) 31.15 return kills; // Uplift to interface 31.16 + if (!empty() && ktkp != NULL && ktkp->klass()->is_loaded() && ktkp->klass()->is_interface()) 31.17 + return kills; // Uplift to interface 31.18 31.19 return Type::TOP; // Canonical empty value 31.20 } 31.21 @@ -2499,6 +2503,12 @@ 31.22 // Happens in a CTW of rt.jar, 320-341, no extra flags 31.23 return ktip->cast_to_ptr_type(ftip->ptr()); 31.24 } 31.25 + if (ftkp != NULL && ktkp != NULL && 31.26 + ftkp->is_loaded() && ftkp->klass()->is_interface() && 31.27 + ktkp->is_loaded() && !ktkp->klass()->is_interface()) { 31.28 + // Happens in a CTW of rt.jar, 320-341, no extra flags 31.29 + return ktkp->cast_to_ptr_type(ftkp->ptr()); 31.30 + } 31.31 31.32 return ft; 31.33 } 31.34 @@ -3657,7 +3667,7 @@ 31.35 31.36 //------------------------------cast_to_ptr_type------------------------------- 31.37 const Type *TypeKlassPtr::cast_to_ptr_type(PTR ptr) const { 31.38 - assert(_base == OopPtr, "subclass must override cast_to_ptr_type"); 31.39 + assert(_base == KlassPtr, "subclass must override cast_to_ptr_type"); 31.40 if( ptr == _ptr ) return this; 31.41 return make(ptr, _klass, _offset); 31.42 }
32.1 --- a/src/share/vm/opto/type.hpp Tue Feb 10 18:39:09 2009 +0300 32.2 +++ b/src/share/vm/opto/type.hpp Tue Feb 17 14:30:24 2009 -0800 32.3 @@ -882,6 +882,8 @@ 32.4 public: 32.5 ciSymbol* name() const { return _klass->name(); } 32.6 32.7 + bool is_loaded() const { return _klass->is_loaded(); } 32.8 + 32.9 // ptr to klass 'k' 32.10 static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); } 32.11 // ptr to klass 'k' with offset
33.1 --- a/src/share/vm/opto/vectornode.cpp Tue Feb 10 18:39:09 2009 +0300 33.2 +++ b/src/share/vm/opto/vectornode.cpp Tue Feb 17 14:30:24 2009 -0800 33.3 @@ -239,7 +239,7 @@ 33.4 return Op_XorV; 33.5 33.6 case Op_LoadB: 33.7 - case Op_LoadC: 33.8 + case Op_LoadUS: 33.9 case Op_LoadS: 33.10 case Op_LoadI: 33.11 case Op_LoadL: 33.12 @@ -269,7 +269,7 @@ 33.13 case 16: return Op_Load16B; 33.14 } 33.15 break; 33.16 - case Op_LoadC: 33.17 + case Op_LoadUS: 33.18 switch (vlen) { 33.19 case 2: return Op_Load2C; 33.20 case 4: return Op_Load4C;
34.1 --- a/src/share/vm/runtime/arguments.cpp Tue Feb 10 18:39:09 2009 +0300 34.2 +++ b/src/share/vm/runtime/arguments.cpp Tue Feb 17 14:30:24 2009 -0800 34.3 @@ -2489,7 +2489,7 @@ 34.4 vm_args.version = JNI_VERSION_1_2; 34.5 vm_args.options = options; 34.6 vm_args.nOptions = i; 34.7 - vm_args.ignoreUnrecognized = false; 34.8 + vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions; 34.9 34.10 if (PrintVMOptions) { 34.11 const char* tail; 34.12 @@ -2536,13 +2536,12 @@ 34.13 34.14 // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed. 34.15 bool settings_file_specified = false; 34.16 + const char* flags_file; 34.17 int index; 34.18 for (index = 0; index < args->nOptions; index++) { 34.19 const JavaVMOption *option = args->options + index; 34.20 if (match_option(option, "-XX:Flags=", &tail)) { 34.21 - if (!process_settings_file(tail, true, args->ignoreUnrecognized)) { 34.22 - return JNI_EINVAL; 34.23 - } 34.24 + flags_file = tail; 34.25 settings_file_specified = true; 34.26 } 34.27 if (match_option(option, "-XX:+PrintVMOptions", &tail)) { 34.28 @@ -2551,6 +2550,24 @@ 34.29 if (match_option(option, "-XX:-PrintVMOptions", &tail)) { 34.30 PrintVMOptions = false; 34.31 } 34.32 + if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions", &tail)) { 34.33 + IgnoreUnrecognizedVMOptions = true; 34.34 + } 34.35 + if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) { 34.36 + IgnoreUnrecognizedVMOptions = false; 34.37 + } 34.38 + } 34.39 + 34.40 + if (IgnoreUnrecognizedVMOptions) { 34.41 + // uncast const to modify the flag args->ignoreUnrecognized 34.42 + *(jboolean*)(&args->ignoreUnrecognized) = true; 34.43 + } 34.44 + 34.45 + // Parse specified settings file 34.46 + if (settings_file_specified) { 34.47 + if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) { 34.48 + return JNI_EINVAL; 34.49 + } 34.50 } 34.51 34.52 // Parse default .hotspotrc settings file
35.1 --- a/src/share/vm/runtime/globals.hpp Tue Feb 10 18:39:09 2009 +0300 35.2 +++ b/src/share/vm/runtime/globals.hpp Tue Feb 17 14:30:24 2009 -0800 35.3 @@ -2194,6 +2194,9 @@ 35.4 product(bool, PrintVMOptions, trueInDebug, \ 35.5 "print VM flag settings") \ 35.6 \ 35.7 + product(bool, IgnoreUnrecognizedVMOptions, false, \ 35.8 + "Ignore unrecognized VM options") \ 35.9 + \ 35.10 diagnostic(bool, SerializeVMOutput, true, \ 35.11 "Use a mutex to serialize output to tty and hotspot.log") \ 35.12 \
36.1 --- a/src/share/vm/utilities/globalDefinitions.hpp Tue Feb 10 18:39:09 2009 +0300 36.2 +++ b/src/share/vm/utilities/globalDefinitions.hpp Tue Feb 17 14:30:24 2009 -0800 36.3 @@ -1,5 +1,5 @@ 36.4 /* 36.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 36.6 + * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. 36.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.8 * 36.9 * This code is free software; you can redistribute it and/or modify it 36.10 @@ -74,6 +74,7 @@ 36.11 extern int BitsPerHeapOop; 36.12 36.13 const int BitsPerJavaInteger = 32; 36.14 +const int BitsPerJavaLong = 64; 36.15 const int BitsPerSize_t = size_tSize * BitsPerByte; 36.16 36.17 // Size of a char[] needed to represent a jint as a string in decimal. 36.18 @@ -906,6 +907,14 @@ 36.19 return log2_intptr(x); 36.20 } 36.21 36.22 +//* the argument must be exactly a power of 2 36.23 +inline int exact_log2_long(jlong x) { 36.24 + #ifdef ASSERT 36.25 + if (!is_power_of_2_long(x)) basic_fatal("x must be a power of 2"); 36.26 + #endif 36.27 + return log2_long(x); 36.28 +} 36.29 + 36.30 36.31 // returns integer round-up to the nearest multiple of s (s must be a power of two) 36.32 inline intptr_t round_to(intptr_t x, uintx s) {
37.1 --- a/test/Makefile Tue Feb 10 18:39:09 2009 +0300 37.2 +++ b/test/Makefile Tue Feb 17 14:30:24 2009 -0800 37.3 @@ -28,9 +28,9 @@ 37.4 37.5 # Get OS/ARCH specifics 37.6 OSNAME = $(shell uname -s) 37.7 -SLASH_JAVA = /java 37.8 ifeq ($(OSNAME), SunOS) 37.9 PLATFORM = solaris 37.10 + SLASH_JAVA = /java 37.11 ARCH = $(shell uname -p) 37.12 ifeq ($(ARCH), i386) 37.13 ARCH=i586 37.14 @@ -38,6 +38,7 @@ 37.15 endif 37.16 ifeq ($(OSNAME), Linux) 37.17 PLATFORM = linux 37.18 + SLASH_JAVA = /java 37.19 ARCH = $(shell uname -m) 37.20 ifeq ($(ARCH), i386) 37.21 ARCH = i586 37.22 @@ -62,6 +63,10 @@ 37.23 EXESUFFIX = .exe 37.24 endif 37.25 37.26 +ifdef ALT_SLASH_JAVA 37.27 + SLASH_JAVA = $(ALT_SLASH_JAVA) 37.28 +endif 37.29 + 37.30 # Utilities used 37.31 CD = cd 37.32 CP = cp
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/test/compiler/6603011/Test.java Tue Feb 17 14:30:24 2009 -0800 38.3 @@ -0,0 +1,220 @@ 38.4 +/* 38.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 38.7 + * 38.8 + * This code is free software; you can redistribute it and/or modify it 38.9 + * under the terms of the GNU General Public License version 2 only, as 38.10 + * published by the Free Software Foundation. 38.11 + * 38.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 38.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 38.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 38.15 + * version 2 for more details (a copy is included in the LICENSE file that 38.16 + * accompanied this code). 38.17 + * 38.18 + * You should have received a copy of the GNU General Public License version 38.19 + * 2 along with this work; if not, write to the Free Software Foundation, 38.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 38.21 + * 38.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 38.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 38.24 + * have any questions. 38.25 + */ 38.26 + 38.27 +/** 38.28 + * @test 38.29 + * @bug 6603011 38.30 + * @summary long/int division by constant 38.31 + * 38.32 + * @run main/othervm -Xcomp -Xbatch -XX:-Inline Test 38.33 + */ 38.34 + 38.35 +// 38.36 +// -XX:-Inline is essential to this test so that verification functions 38.37 +// divi, modi, divl and modl generate "plain" divides. 38.38 +// -Xcomp -Xbatch are also useful to ensure the full range of 38.39 +// dividend and divisor combinations are tested 38.40 +// 38.41 + 38.42 +import java.net.*; 38.43 + 38.44 +class s { 38.45 + static int divi(int dividend, int divisor) { return dividend / divisor; } 38.46 + static int modi(int dividend, int divisor) { return dividend % divisor; } 38.47 + static long divl(long dividend, long divisor) { return dividend / divisor; } 38.48 + static long modl(long dividend, long divisor) { return dividend % divisor; } 38.49 +} 38.50 + 38.51 +public class Test implements Runnable { 38.52 + // Report verbose messages on failure; turn off to suppress 38.53 + // too much output with gross numbers of failures. 38.54 + static final boolean VERBOSE = true; 38.55 + 38.56 + // Initailize DIVISOR so that it is final in this class. 38.57 + static final int DIVISOR; 38.58 + static { 38.59 + int value = 0; 38.60 + try { 38.61 + value = Integer.decode(System.getProperty("divisor")); 38.62 + } catch (Throwable e) { 38.63 + } 38.64 + DIVISOR = value; 38.65 + } 38.66 + 38.67 + // The methods of interest. We want the JIT to compile these 38.68 + // and convert the divide into a multiply. 38.69 + public int divbyI (int dividend) { return dividend / DIVISOR; } 38.70 + public int modbyI (int dividend) { return dividend % DIVISOR; } 38.71 + public long divbyL (long dividend) { return dividend / DIVISOR; } 38.72 + public long modbyL (long dividend) { return dividend % DIVISOR; } 38.73 + 38.74 + public int divisor() { return DIVISOR; } 38.75 + 38.76 + public boolean checkI (int dividend) { 38.77 + int quo = divbyI(dividend); 38.78 + int rem = modbyI(dividend); 38.79 + int quo0 = s.divi(dividend, divisor()); 38.80 + int rem0 = s.modi(dividend, divisor()); 38.81 + 38.82 + if (quo != quo0 || rem != rem0) { 38.83 + if (VERBOSE) { 38.84 + System.out.println("Computed: " + dividend + " / " + divisor() + " = " + 38.85 + quo + ", " + dividend + " % " + divisor() + " = " + rem ); 38.86 + System.out.println("expected: " + dividend + " / " + divisor() + " = " + 38.87 + quo0 + ", " + dividend + " % " + divisor() + " = " + rem0); 38.88 + // Report sign of rem failure 38.89 + if (rem != 0 && (rem ^ dividend) < 0) { 38.90 + System.out.println(" rem & dividend have different signs"); 38.91 + } 38.92 + // Report range of rem failure 38.93 + if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) { 38.94 + System.out.println(" remainder out of range"); 38.95 + } 38.96 + // Report quo/rem identity relationship failure 38.97 + if ((quo * divisor()) + rem != dividend) { 38.98 + System.out.println(" quotien/remainder invariant broken"); 38.99 + } 38.100 + } 38.101 + return false; 38.102 + } 38.103 + return true; 38.104 + } 38.105 + 38.106 + public boolean checkL (long dividend) { 38.107 + long quo = divbyL(dividend); 38.108 + long rem = modbyL(dividend); 38.109 + long quo0 = s.divl(dividend, divisor()); 38.110 + long rem0 = s.modl(dividend, divisor()); 38.111 + 38.112 + if (quo != quo0 || rem != rem0) { 38.113 + if (VERBOSE) { 38.114 + System.out.println(" " + dividend + " / " + divisor() + " = " + 38.115 + quo + ", " + dividend + " % " + divisor() + " = " + rem); 38.116 + // Report sign of rem failure 38.117 + if (rem != 0 && (rem ^ dividend) < 0) { 38.118 + System.out.println(" rem & dividend have different signs"); 38.119 + } 38.120 + // Report range of rem failure 38.121 + if (java.lang.Math.abs(rem) >= java.lang.Math.abs(divisor())) { 38.122 + System.out.println(" remainder out of range"); 38.123 + } 38.124 + // Report quo/rem identity relationship failure 38.125 + if ((quo * divisor()) + rem != dividend) { 38.126 + System.out.println(" (" + quo + " * " + divisor() + ") + " + rem + " != " 38.127 + + dividend); 38.128 + } 38.129 + } 38.130 + return false; 38.131 + } 38.132 + return true; 38.133 + } 38.134 + 38.135 + public void run() { 38.136 + // Don't try to divide by zero 38.137 + if (divisor() == 0) return; 38.138 + 38.139 + // Range of dividends to check. Try dividends from start to end 38.140 + // inclusive, as well as variations on those values as shifted 38.141 + // left. 38.142 + int start = -1024; 38.143 + int end = 1024; 38.144 + 38.145 + // Test int division using a variety of dividends. 38.146 + int wrong = 0; 38.147 + int total = 0; 38.148 + 38.149 + outerloop: 38.150 + for (int i = start; i <= end; i++) { 38.151 + for (int s = 0; s < 32; s += 4) { 38.152 + total++; 38.153 + int dividend = i << s; 38.154 + if (!checkI(dividend)) { 38.155 + wrong++; 38.156 + // Stop on the first failure 38.157 + // break outerloop; 38.158 + } 38.159 + } 38.160 + } 38.161 + if (wrong > 0) { 38.162 + System.out.println("divisor " + divisor() + ": " + 38.163 + wrong + "/" + total + " wrong int divisions"); 38.164 + } 38.165 + 38.166 + // Test long division using a variety of dividends. 38.167 + wrong = 0; 38.168 + total = 0; 38.169 + 38.170 + outerloop: 38.171 + for (int i = start; i <= end; i++) { 38.172 + for (int s = 0; s < 64; s += 4) { 38.173 + total++; 38.174 + long dividend = i << s; 38.175 + if (!checkL(dividend)) { 38.176 + wrong++; 38.177 + // Stop on the first failure 38.178 + // break outerloop; 38.179 + } 38.180 + } 38.181 + } 38.182 + if (wrong > 0) { 38.183 + System.out.println("divisor " + divisor() + ": " + 38.184 + wrong + "/" + total + " wrong long divisions"); 38.185 + } 38.186 + 38.187 + } 38.188 + 38.189 + // Reload this class with the "divisor" property set to the input parameter. 38.190 + // This allows the JIT to see q.DIVISOR as a final constant, and change 38.191 + // any divisions or mod operations into multiplies. 38.192 + public static void test_divisor(int divisor, 38.193 + URLClassLoader apploader) throws Exception { 38.194 + System.setProperty("divisor", "" + divisor); 38.195 + ClassLoader loader = new URLClassLoader(apploader.getURLs(), 38.196 + apploader.getParent()); 38.197 + Class c = loader.loadClass("Test"); 38.198 + Runnable r = (Runnable)c.newInstance(); 38.199 + r.run(); 38.200 + } 38.201 + 38.202 + public static void main(String[] args) throws Exception { 38.203 + Class cl = Class.forName("Test"); 38.204 + URLClassLoader apploader = (URLClassLoader)cl.getClassLoader(); 38.205 + 38.206 + 38.207 + // Test every divisor between -100 and 100. 38.208 + for (int i = -100; i <= 100; i++) { 38.209 + test_divisor(i, apploader); 38.210 + } 38.211 + 38.212 + // Try a few divisors outside the typical range. 38.213 + // The values below have been observed in rt.jar. 38.214 + test_divisor(101, apploader); 38.215 + test_divisor(400, apploader); 38.216 + test_divisor(1000, apploader); 38.217 + test_divisor(3600, apploader); 38.218 + test_divisor(9973, apploader); 38.219 + test_divisor(86400, apploader); 38.220 + test_divisor(1000000, apploader); 38.221 + } 38.222 + 38.223 +}
39.1 --- a/test/compiler/6775880/Test.java Tue Feb 10 18:39:09 2009 +0300 39.2 +++ b/test/compiler/6775880/Test.java Tue Feb 17 14:30:24 2009 -0800 39.3 @@ -27,7 +27,7 @@ 39.4 * @bug 6775880 39.5 * @summary EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now") 39.6 * @compile -source 1.4 -target 1.4 Test.java 39.7 - * @run main/othervm -server -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test 39.8 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test 39.9 */ 39.10 39.11 public class Test {
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/test/compiler/6795161/Test.java Tue Feb 17 14:30:24 2009 -0800 40.3 @@ -0,0 +1,60 @@ 40.4 +/* 40.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 40.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 40.7 + * 40.8 + * This code is free software; you can redistribute it and/or modify it 40.9 + * under the terms of the GNU General Public License version 2 only, as 40.10 + * published by the Free Software Foundation. 40.11 + * 40.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 40.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 40.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 40.15 + * version 2 for more details (a copy is included in the LICENSE file that 40.16 + * accompanied this code). 40.17 + * 40.18 + * You should have received a copy of the GNU General Public License version 40.19 + * 2 along with this work; if not, write to the Free Software Foundation, 40.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 40.21 + * 40.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 40.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 40.24 + * have any questions. 40.25 + * 40.26 + */ 40.27 + 40.28 +/* 40.29 + * @test 40.30 + * @bug 6795161 40.31 + * @summary Escape analysis leads to data corruption 40.32 + * @run main/othervm -server -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test 40.33 + */ 40.34 + 40.35 +class Test_Class_1 { 40.36 + static String var_1; 40.37 + 40.38 + static void badFunc(int size) 40.39 + { 40.40 + try { 40.41 + for (int i = 0; i < 1; (new byte[size-i])[0] = 0, i++) {} 40.42 + } catch (Exception e) { 40.43 + // don't comment it out, it will lead to correct results ;) 40.44 + //System.out.println("Got exception: " + e); 40.45 + } 40.46 + } 40.47 +} 40.48 + 40.49 +public class Test { 40.50 + static String var_1_copy = Test_Class_1.var_1; 40.51 + 40.52 + static byte var_check; 40.53 + 40.54 + public static void main(String[] args) 40.55 + { 40.56 + var_check = 1; 40.57 + 40.58 + Test_Class_1.badFunc(-1); 40.59 + 40.60 + System.out.println("EATester.var_check = " + Test.var_check + " (expected 1)\n"); 40.61 + } 40.62 +} 40.63 +
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/test/compiler/6795362/Test6795362.java Tue Feb 17 14:30:24 2009 -0800 41.3 @@ -0,0 +1,48 @@ 41.4 +/* 41.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.7 + * 41.8 + * This code is free software; you can redistribute it and/or modify it 41.9 + * under the terms of the GNU General Public License version 2 only, as 41.10 + * published by the Free Software Foundation. 41.11 + * 41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 41.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 41.15 + * version 2 for more details (a copy is included in the LICENSE file that 41.16 + * accompanied this code). 41.17 + * 41.18 + * You should have received a copy of the GNU General Public License version 41.19 + * 2 along with this work; if not, write to the Free Software Foundation, 41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 41.21 + * 41.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 41.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 41.24 + * have any questions. 41.25 + */ 41.26 + 41.27 +/** 41.28 + * @test 41.29 + * @bug 6795362 41.30 + * @summary 32bit server compiler leads to wrong results on solaris-x86 41.31 + * 41.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6795362.sub Test6795362 41.33 + */ 41.34 + 41.35 +public class Test6795362 { 41.36 + public static void main(String[] args) 41.37 + { 41.38 + sub(); 41.39 + 41.40 + if (var_bad != 0) 41.41 + throw new InternalError(var_bad + " != 0"); 41.42 + } 41.43 + 41.44 + static long var_bad = -1L; 41.45 + 41.46 + static void sub() 41.47 + { 41.48 + var_bad >>= 65; 41.49 + var_bad /= 65; 41.50 + } 41.51 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/test/compiler/6799693/Test.java Tue Feb 17 14:30:24 2009 -0800 42.3 @@ -0,0 +1,47 @@ 42.4 +/* 42.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 42.7 + * 42.8 + * This code is free software; you can redistribute it and/or modify it 42.9 + * under the terms of the GNU General Public License version 2 only, as 42.10 + * published by the Free Software Foundation. 42.11 + * 42.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 42.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 42.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 42.15 + * version 2 for more details (a copy is included in the LICENSE file that 42.16 + * accompanied this code). 42.17 + * 42.18 + * You should have received a copy of the GNU General Public License version 42.19 + * 2 along with this work; if not, write to the Free Software Foundation, 42.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 42.21 + * 42.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 42.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 42.24 + * have any questions. 42.25 + * 42.26 + */ 42.27 + 42.28 +/* 42.29 + * @test 42.30 + * @bug 6799693 42.31 + * @summary Server compiler leads to data corruption when expression throws an Exception 42.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test Test 42.33 + */ 42.34 + 42.35 +public class Test { 42.36 + static int var_bad = 1; 42.37 + 42.38 + public static void main(String[] args) 42.39 + { 42.40 + var_bad++; 42.41 + 42.42 + try { 42.43 + for (int i = 0; i < 10; i++) (new byte[((byte)-1 << i)])[0] = 0; 42.44 + } 42.45 + catch (Exception e) { System.out.println("Got " + e); } 42.46 + 42.47 + System.out.println("Test.var_bad = " + var_bad + " (expected 2)\n"); 42.48 + } 42.49 +} 42.50 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/test/compiler/6800154/Test6800154.java Tue Feb 17 14:30:24 2009 -0800 43.3 @@ -0,0 +1,109 @@ 43.4 +/* 43.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43.7 + * 43.8 + * This code is free software; you can redistribute it and/or modify it 43.9 + * under the terms of the GNU General Public License version 2 only, as 43.10 + * published by the Free Software Foundation. 43.11 + * 43.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 43.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 43.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 43.15 + * version 2 for more details (a copy is included in the LICENSE file that 43.16 + * accompanied this code). 43.17 + * 43.18 + * You should have received a copy of the GNU General Public License version 43.19 + * 2 along with this work; if not, write to the Free Software Foundation, 43.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 43.21 + * 43.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 43.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 43.24 + * have any questions. 43.25 + */ 43.26 + 43.27 +/** 43.28 + * @test 43.29 + * @bug 6800154 43.30 + * @summary Add comments to long_by_long_mulhi() for better understandability 43.31 + * 43.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6800154.divcomp Test6800154 43.33 + */ 43.34 + 43.35 +import java.net.URLClassLoader; 43.36 + 43.37 +public class Test6800154 implements Runnable { 43.38 + static final long[] DIVIDENDS = { 43.39 + 0, 43.40 + 1, 43.41 + 2, 43.42 + 1423487, 43.43 + 4444441, 43.44 + 4918923241323L, 43.45 + -1, 43.46 + -24351, 43.47 + 0x3333, 43.48 + 0x0000000080000000L, 43.49 + 0x7fffffffffffffffL, 43.50 + 0x8000000000000000L 43.51 + }; 43.52 + 43.53 + static final long[] DIVISORS = { 43.54 + 1, 43.55 + 2, 43.56 + 17, 43.57 + 12342, 43.58 + 24123, 43.59 + 143444, 43.60 + 123444442344L, 43.61 + -1, 43.62 + -2, 43.63 + -4423423234231423L, 43.64 + 0x0000000080000000L, 43.65 + 0x7fffffffffffffffL, 43.66 + 0x8000000000000000L 43.67 + }; 43.68 + 43.69 + // Initialize DIVISOR so that it is final in this class. 43.70 + static final long DIVISOR; 43.71 + 43.72 + static { 43.73 + long value = 0; 43.74 + try { 43.75 + value = Long.decode(System.getProperty("divisor")); 43.76 + } catch (Throwable e) { 43.77 + } 43.78 + DIVISOR = value; 43.79 + } 43.80 + 43.81 + public static void main(String[] args) throws Exception 43.82 + { 43.83 + Class cl = Class.forName("Test6800154"); 43.84 + URLClassLoader apploader = (URLClassLoader) cl.getClassLoader(); 43.85 + 43.86 + // Iterate over all divisors. 43.87 + for (int i = 0; i < DIVISORS.length; i++) { 43.88 + System.setProperty("divisor", "" + DIVISORS[i]); 43.89 + ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent()); 43.90 + Class c = loader.loadClass("Test6800154"); 43.91 + Runnable r = (Runnable) c.newInstance(); 43.92 + r.run(); 43.93 + } 43.94 + } 43.95 + 43.96 + public void run() 43.97 + { 43.98 + // Iterate over all dividends. 43.99 + for (int i = 0; i < DIVIDENDS.length; i++) { 43.100 + long dividend = DIVIDENDS[i]; 43.101 + 43.102 + long expected = divint(dividend); 43.103 + long result = divcomp(dividend); 43.104 + 43.105 + if (result != expected) 43.106 + throw new InternalError(dividend + " / " + DIVISOR + " failed: " + result + " != " + expected); 43.107 + } 43.108 + } 43.109 + 43.110 + static long divint(long a) { return a / DIVISOR; } 43.111 + static long divcomp(long a) { return a / DIVISOR; } 43.112 +}
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/test/compiler/6805724/Test6805724.java Tue Feb 17 14:30:24 2009 -0800 44.3 @@ -0,0 +1,80 @@ 44.4 +/* 44.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 44.7 + * 44.8 + * This code is free software; you can redistribute it and/or modify it 44.9 + * under the terms of the GNU General Public License version 2 only, as 44.10 + * published by the Free Software Foundation. 44.11 + * 44.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 44.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 44.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 44.15 + * version 2 for more details (a copy is included in the LICENSE file that 44.16 + * accompanied this code). 44.17 + * 44.18 + * You should have received a copy of the GNU General Public License version 44.19 + * 2 along with this work; if not, write to the Free Software Foundation, 44.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 44.21 + * 44.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 44.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 44.24 + * have any questions. 44.25 + */ 44.26 + 44.27 +/** 44.28 + * @test 44.29 + * @bug 6805724 44.30 + * @summary ModLNode::Ideal() generates functionally incorrect graph when divisor is any (2^k-1) constant. 44.31 + * 44.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test6805724.fcomp Test6805724 44.33 + */ 44.34 + 44.35 +import java.net.URLClassLoader; 44.36 + 44.37 +public class Test6805724 implements Runnable { 44.38 + // Initialize DIVISOR so that it is final in this class. 44.39 + static final long DIVISOR; // 2^k-1 constant 44.40 + 44.41 + static { 44.42 + long value = 0; 44.43 + try { 44.44 + value = Long.decode(System.getProperty("divisor")); 44.45 + } catch (Throwable t) { 44.46 + // This one is required for the Class.forName() in main. 44.47 + } 44.48 + DIVISOR = value; 44.49 + } 44.50 + 44.51 + static long fint(long x) { 44.52 + return x % DIVISOR; 44.53 + } 44.54 + 44.55 + static long fcomp(long x) { 44.56 + return x % DIVISOR; 44.57 + } 44.58 + 44.59 + public void run() { 44.60 + long a = 0x617981E1L; 44.61 + 44.62 + long expected = fint(a); 44.63 + long result = fcomp(a); 44.64 + 44.65 + if (result != expected) 44.66 + throw new InternalError(result + " != " + expected); 44.67 + } 44.68 + 44.69 + public static void main(String args[]) throws Exception { 44.70 + Class cl = Class.forName("Test6805724"); 44.71 + URLClassLoader apploader = (URLClassLoader) cl.getClassLoader(); 44.72 + 44.73 + // Iterate over all 2^k-1 divisors. 44.74 + for (int k = 1; k < Long.SIZE; k++) { 44.75 + long divisor = (1L << k) - 1; 44.76 + System.setProperty("divisor", "" + divisor); 44.77 + ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent()); 44.78 + Class c = loader.loadClass("Test6805724"); 44.79 + Runnable r = (Runnable) c.newInstance(); 44.80 + r.run(); 44.81 + } 44.82 + } 44.83 +}