Fri, 25 Mar 2011 18:04:45 -0700
Merge
test/compiler/6987555/Test6987555.java | file | annotate | diff | comparison | revisions | |
test/compiler/6991596/Test6991596.java | file | annotate | diff | comparison | revisions |
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java Fri Mar 25 17:26:33 2011 -0700 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java Fri Mar 25 18:04:45 2011 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -62,7 +62,7 @@ 1.11 1.12 // get the value of static field 1.13 ValueImpl getValue() { 1.14 - return getValue(saField.getFieldHolder()); 1.15 + return getValue(saField.getFieldHolder().getJavaMirror()); 1.16 } 1.17 1.18 // get the value of this Field from a specific Oop
2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java Fri Mar 25 17:26:33 2011 -0700 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java Fri Mar 25 18:04:45 2011 -0700 2.3 @@ -44,12 +44,10 @@ 2.4 private static synchronized void initialize(TypeDataBase db) { 2.5 Type type = db.lookupType("StringTable"); 2.6 theTableField = type.getAddressField("_the_table"); 2.7 - stringTableSize = db.lookupIntConstant("StringTable::string_table_size").intValue(); 2.8 } 2.9 2.10 // Fields 2.11 private static AddressField theTableField; 2.12 - private static int stringTableSize; 2.13 2.14 // Accessors 2.15 public static StringTable getTheTable() { 2.16 @@ -57,10 +55,6 @@ 2.17 return (StringTable) VMObjectFactory.newObject(StringTable.class, tmp); 2.18 } 2.19 2.20 - public static int getStringTableSize() { 2.21 - return stringTableSize; 2.22 - } 2.23 - 2.24 public StringTable(Address addr) { 2.25 super(addr); 2.26 }
3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Mar 25 17:26:33 2011 -0700 3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Mar 25 18:04:45 2011 -0700 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -87,7 +87,7 @@ 3.11 innerClasses = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize()); 3.12 nonstaticFieldSize = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize()); 3.13 staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize()); 3.14 - staticOopFieldSize = new CIntField(type.getCIntegerField("_static_oop_field_size"), Oop.getHeaderSize()); 3.15 + staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize()); 3.16 nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize()); 3.17 isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize()); 3.18 initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize()); 3.19 @@ -140,7 +140,7 @@ 3.20 private static OopField innerClasses; 3.21 private static CIntField nonstaticFieldSize; 3.22 private static CIntField staticFieldSize; 3.23 - private static CIntField staticOopFieldSize; 3.24 + private static CIntField staticOopFieldCount; 3.25 private static CIntField nonstaticOopMapSize; 3.26 private static CIntField isMarkedDependent; 3.27 private static CIntField initState; 3.28 @@ -261,8 +261,7 @@ 3.29 public Symbol getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); } 3.30 public TypeArray getInnerClasses() { return (TypeArray) innerClasses.getValue(this); } 3.31 public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); } 3.32 - public long getStaticFieldSize() { return staticFieldSize.getValue(this); } 3.33 - public long getStaticOopFieldSize() { return staticOopFieldSize.getValue(this); } 3.34 + public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); } 3.35 public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); } 3.36 public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; } 3.37 public long getVtableLen() { return vtableLen.getValue(this); } 3.38 @@ -453,7 +452,7 @@ 3.39 visitor.doOop(innerClasses, true); 3.40 visitor.doCInt(nonstaticFieldSize, true); 3.41 visitor.doCInt(staticFieldSize, true); 3.42 - visitor.doCInt(staticOopFieldSize, true); 3.43 + visitor.doCInt(staticOopFieldCount, true); 3.44 visitor.doCInt(nonstaticOopMapSize, true); 3.45 visitor.doCInt(isMarkedDependent, true); 3.46 visitor.doCInt(initState, true); 3.47 @@ -692,7 +691,7 @@ 3.48 public long getObjectSize() { 3.49 long bodySize = alignObjectOffset(getVtableLen() * getHeap().getOopSize()) 3.50 + alignObjectOffset(getItableLen() * getHeap().getOopSize()) 3.51 - + (getStaticFieldSize() + getNonstaticOopMapSize()) * getHeap().getOopSize(); 3.52 + + (getNonstaticOopMapSize()) * getHeap().getOopSize(); 3.53 return alignObjectSize(headerSize + bodySize); 3.54 } 3.55
4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/IntField.java Fri Mar 25 17:26:33 2011 -0700 4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/IntField.java Fri Mar 25 18:04:45 2011 -0700 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -40,7 +40,12 @@ 4.11 super(holder, fieldArrayIndex); 4.12 } 4.13 4.14 - public int getValue(Oop obj) { return obj.getHandle().getJIntAt(getOffset()); } 4.15 + public int getValue(Oop obj) { 4.16 + if (!isVMField() && !obj.isInstance() && !obj.isArray()) { 4.17 + throw new InternalError(obj.toString()); 4.18 + } 4.19 + return obj.getHandle().getJIntAt(getOffset()); 4.20 + } 4.21 public void setValue(Oop obj, int value) throws MutationException { 4.22 // Fix this: setJIntAt is missing in Address 4.23 }
5.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopField.java Fri Mar 25 17:26:33 2011 -0700 5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopField.java Fri Mar 25 18:04:45 2011 -0700 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -41,11 +41,17 @@ 5.11 } 5.12 5.13 public Oop getValue(Oop obj) { 5.14 + if (!isVMField() && !obj.isInstance() && !obj.isArray()) { 5.15 + throw new InternalError(); 5.16 + } 5.17 return obj.getHeap().newOop(getValueAsOopHandle(obj)); 5.18 } 5.19 5.20 /** Debugging support */ 5.21 public OopHandle getValueAsOopHandle(Oop obj) { 5.22 + if (!isVMField() && !obj.isInstance() && !obj.isArray()) { 5.23 + throw new InternalError(obj.toString()); 5.24 + } 5.25 return obj.getHandle().getOopHandleAt(getOffset()); 5.26 } 5.27
6.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Fri Mar 25 17:26:33 2011 -0700 6.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Fri Mar 25 18:04:45 2011 -0700 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -274,13 +274,7 @@ 6.11 // hc_klass is a HotSpot magic field and hence we can't 6.12 // find it from InstanceKlass for java.lang.Class. 6.13 TypeDataBase db = VM.getVM().getTypeDataBase(); 6.14 - int hcKlassOffset = (int) Instance.getHeaderSize(); 6.15 - try { 6.16 - hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() * 6.17 - VM.getVM().getHeapOopSize()); 6.18 - } catch (RuntimeException re) { 6.19 - // ignore, currently java_lang_Class::hc_klass_offset is zero 6.20 - } 6.21 + int hcKlassOffset = (int) db.lookupType("java_lang_Class").getCIntegerField("klass_offset").getValue(); 6.22 if (VM.getVM().isCompressedOopsEnabled()) { 6.23 hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true); 6.24 } else {
7.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Mar 25 17:26:33 2011 -0700 7.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Mar 25 18:04:45 2011 -0700 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -839,13 +839,13 @@ 7.11 } 7.12 7.13 private void readSystemProperties() { 7.14 - InstanceKlass systemKls = getSystemDictionary().getSystemKlass(); 7.15 + final InstanceKlass systemKls = getSystemDictionary().getSystemKlass(); 7.16 systemKls.iterate(new DefaultOopVisitor() { 7.17 ObjectReader objReader = new ObjectReader(); 7.18 public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) { 7.19 if (field.getID().getName().equals("props")) { 7.20 try { 7.21 - sysProps = (Properties) objReader.readObject(field.getValue(getObj())); 7.22 + sysProps = (Properties) objReader.readObject(field.getValue(systemKls.getJavaMirror())); 7.23 } catch (Exception e) { 7.24 if (Assert.ASSERTS_ENABLED) { 7.25 e.printStackTrace();
8.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Fri Mar 25 17:26:33 2011 -0700 8.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Fri Mar 25 18:04:45 2011 -0700 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -746,7 +746,7 @@ 8.11 out.writeByte((byte)kind); 8.12 if (ik != null) { 8.13 // static field 8.14 - writeField(field, ik); 8.15 + writeField(field, ik.getJavaMirror()); 8.16 } 8.17 } 8.18 }
9.1 --- a/agent/test/jdi/sasanity.sh Fri Mar 25 17:26:33 2011 -0700 9.2 +++ b/agent/test/jdi/sasanity.sh Fri Mar 25 18:04:45 2011 -0700 9.3 @@ -43,6 +43,7 @@ 9.4 fi 9.5 9.6 jdk=$1 9.7 +shift 9.8 OS=`uname` 9.9 9.10 if [ "$OS" != "Linux" ]; then 9.11 @@ -68,7 +69,7 @@ 9.12 9.13 tmp=/tmp/sagsetup 9.14 rm -f $tmp 9.15 -$jdk/bin/java sagtarg > $tmp & 9.16 +$jdk/bin/java $* sagtarg > $tmp & 9.17 pid=$! 9.18 while [ ! -s $tmp ] ; do 9.19 # Kludge alert!
10.1 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Mar 25 17:26:33 2011 -0700 10.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp Fri Mar 25 18:04:45 2011 -0700 10.3 @@ -301,7 +301,8 @@ 10.4 // thread. 10.5 assert(_obj != noreg, "must be a valid register"); 10.6 assert(_oop_index >= 0, "must have oop index"); 10.7 - __ ld_ptr(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3); 10.8 + __ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3); 10.9 + __ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3); 10.10 __ cmp(G2_thread, G3); 10.11 __ br(Assembler::notEqual, false, Assembler::pn, call_patch); 10.12 __ delayed()->nop();
11.1 --- a/src/cpu/sparc/vm/dump_sparc.cpp Fri Mar 25 17:26:33 2011 -0700 11.2 +++ b/src/cpu/sparc/vm/dump_sparc.cpp Fri Mar 25 18:04:45 2011 -0700 11.3 @@ -80,13 +80,19 @@ 11.4 for (int j = 0; j < num_virtuals; ++j) { 11.5 dummy_vtable[num_virtuals * i + j] = (void*)masm->pc(); 11.6 __ save(SP, -256, SP); 11.7 + int offset = (i << 8) + j; 11.8 + Register src = G0; 11.9 + if (!Assembler::is_simm13(offset)) { 11.10 + __ sethi(offset, L0); 11.11 + src = L0; 11.12 + offset = offset & ((1 << 10) - 1); 11.13 + } 11.14 __ brx(Assembler::always, false, Assembler::pt, common_code); 11.15 11.16 // Load L0 with a value indicating vtable/offset pair. 11.17 // -- bits[ 7..0] (8 bits) which virtual method in table? 11.18 - // -- bits[12..8] (5 bits) which virtual method table? 11.19 - // -- must fit in 13-bit instruction immediate field. 11.20 - __ delayed()->set((i << 8) + j, L0); 11.21 + // -- bits[13..8] (6 bits) which virtual method table? 11.22 + __ delayed()->or3(src, offset, L0); 11.23 } 11.24 } 11.25
12.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Mar 25 17:26:33 2011 -0700 12.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Mar 25 18:04:45 2011 -0700 12.3 @@ -775,9 +775,13 @@ 12.4 switch (ek) { 12.5 case _adapter_opt_i2l: 12.6 { 12.7 - __ ldsw(arg_lsw, O2_scratch); // Load LSW 12.8 - NOT_LP64(__ srlx(O2_scratch, BitsPerInt, O3_scratch)); // Move high bits to lower bits for std 12.9 - __ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64 12.10 +#ifdef _LP64 12.11 + __ ldsw(arg_lsw, O2_scratch); // Load LSW sign-extended 12.12 +#else 12.13 + __ ldsw(arg_lsw, O3_scratch); // Load LSW sign-extended 12.14 + __ srlx(O3_scratch, BitsPerInt, O2_scratch); // Move MSW value to lower 32-bits for std 12.15 +#endif 12.16 + __ st_long(O2_scratch, arg_msw); // Uses O2/O3 on !_LP64 12.17 } 12.18 break; 12.19 case _adapter_opt_unboxl:
13.1 --- a/src/cpu/sparc/vm/nativeInst_sparc.cpp Fri Mar 25 17:26:33 2011 -0700 13.2 +++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp Fri Mar 25 18:04:45 2011 -0700 13.3 @@ -52,6 +52,22 @@ 13.4 ICache::invalidate_range(instaddr, 7 * BytesPerInstWord); 13.5 } 13.6 13.7 +void NativeInstruction::verify_data64_sethi(address instaddr, intptr_t x) { 13.8 + ResourceMark rm; 13.9 + unsigned char buffer[10 * BytesPerInstWord]; 13.10 + CodeBuffer buf(buffer, 10 * BytesPerInstWord); 13.11 + MacroAssembler masm(&buf); 13.12 + 13.13 + Register destreg = inv_rd(*(unsigned int *)instaddr); 13.14 + // Generate the proper sequence into a temporary buffer and compare 13.15 + // it with the original sequence. 13.16 + masm.patchable_sethi(x, destreg); 13.17 + int len = buffer - masm.pc(); 13.18 + for (int i = 0; i < len; i++) { 13.19 + assert(instaddr[i] == buffer[i], "instructions must match"); 13.20 + } 13.21 +} 13.22 + 13.23 void NativeInstruction::verify() { 13.24 // make sure code pattern is actually an instruction address 13.25 address addr = addr_at(0);
14.1 --- a/src/cpu/sparc/vm/nativeInst_sparc.hpp Fri Mar 25 17:26:33 2011 -0700 14.2 +++ b/src/cpu/sparc/vm/nativeInst_sparc.hpp Fri Mar 25 18:04:45 2011 -0700 14.3 @@ -254,6 +254,7 @@ 14.4 // sethi. This only does the sethi. The disp field (bottom 10 bits) 14.5 // must be handled separately. 14.6 static void set_data64_sethi(address instaddr, intptr_t x); 14.7 + static void verify_data64_sethi(address instaddr, intptr_t x); 14.8 14.9 // combine the fields of a sethi/simm13 pair (simm13 = or, add, jmpl, ld/st) 14.10 static int data32(int sethi_insn, int arith_insn) {
15.1 --- a/src/cpu/sparc/vm/relocInfo_sparc.cpp Fri Mar 25 17:26:33 2011 -0700 15.2 +++ b/src/cpu/sparc/vm/relocInfo_sparc.cpp Fri Mar 25 18:04:45 2011 -0700 15.3 @@ -30,7 +30,7 @@ 15.4 #include "oops/oop.inline.hpp" 15.5 #include "runtime/safepoint.hpp" 15.6 15.7 -void Relocation::pd_set_data_value(address x, intptr_t o) { 15.8 +void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) { 15.9 NativeInstruction* ip = nativeInstruction_at(addr()); 15.10 jint inst = ip->long_at(0); 15.11 assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint"); 15.12 @@ -83,7 +83,11 @@ 15.13 guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13"); 15.14 inst &= ~Assembler::simm( -1, 13); 15.15 inst |= Assembler::simm(simm13, 13); 15.16 - ip->set_long_at(0, inst); 15.17 + if (verify_only) { 15.18 + assert(ip->long_at(0) == inst, "instructions must match"); 15.19 + } else { 15.20 + ip->set_long_at(0, inst); 15.21 + } 15.22 } 15.23 break; 15.24 15.25 @@ -97,19 +101,36 @@ 15.26 jint np = oopDesc::encode_heap_oop((oop)x); 15.27 inst &= ~Assembler::hi22(-1); 15.28 inst |= Assembler::hi22((intptr_t)np); 15.29 - ip->set_long_at(0, inst); 15.30 + if (verify_only) { 15.31 + assert(ip->long_at(0) == inst, "instructions must match"); 15.32 + } else { 15.33 + ip->set_long_at(0, inst); 15.34 + } 15.35 inst2 = ip->long_at( NativeInstruction::nop_instruction_size ); 15.36 guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op"); 15.37 - ip->set_long_at(NativeInstruction::nop_instruction_size, ip->set_data32_simm13( inst2, (intptr_t)np)); 15.38 + if (verify_only) { 15.39 + assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np), 15.40 + "instructions must match"); 15.41 + } else { 15.42 + ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np)); 15.43 + } 15.44 break; 15.45 } 15.46 - ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x ); 15.47 + if (verify_only) { 15.48 + ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x ); 15.49 + } else { 15.50 + ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x ); 15.51 + } 15.52 #else 15.53 guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi"); 15.54 inst &= ~Assembler::hi22( -1); 15.55 inst |= Assembler::hi22((intptr_t)x); 15.56 // (ignore offset; it doesn't play into the sethi) 15.57 - ip->set_long_at(0, inst); 15.58 + if (verify_only) { 15.59 + assert(ip->long_at(0) == inst, "instructions must match"); 15.60 + } else { 15.61 + ip->set_long_at(0, inst); 15.62 + } 15.63 #endif 15.64 } 15.65 break;
16.1 --- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Mar 25 17:26:33 2011 -0700 16.2 +++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp Fri Mar 25 18:04:45 2011 -0700 16.3 @@ -313,10 +313,13 @@ 16.4 } 16.5 assert(_obj != noreg, "must be a valid register"); 16.6 Register tmp = rax; 16.7 - if (_obj == tmp) tmp = rbx; 16.8 + Register tmp2 = rbx; 16.9 __ push(tmp); 16.10 + __ push(tmp2); 16.11 + __ load_heap_oop(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes())); 16.12 __ get_thread(tmp); 16.13 - __ cmpptr(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc))); 16.14 + __ cmpptr(tmp, Address(tmp2, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc))); 16.15 + __ pop(tmp2); 16.16 __ pop(tmp); 16.17 __ jcc(Assembler::notEqual, call_patch); 16.18
17.1 --- a/src/cpu/x86/vm/relocInfo_x86.cpp Fri Mar 25 17:26:33 2011 -0700 17.2 +++ b/src/cpu/x86/vm/relocInfo_x86.cpp Fri Mar 25 18:04:45 2011 -0700 17.3 @@ -31,7 +31,7 @@ 17.4 #include "runtime/safepoint.hpp" 17.5 17.6 17.7 -void Relocation::pd_set_data_value(address x, intptr_t o) { 17.8 +void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) { 17.9 #ifdef AMD64 17.10 x += o; 17.11 typedef Assembler::WhichOperand WhichOperand; 17.12 @@ -40,19 +40,35 @@ 17.13 which == Assembler::narrow_oop_operand || 17.14 which == Assembler::imm_operand, "format unpacks ok"); 17.15 if (which == Assembler::imm_operand) { 17.16 - *pd_address_in_code() = x; 17.17 + if (verify_only) { 17.18 + assert(*pd_address_in_code() == x, "instructions must match"); 17.19 + } else { 17.20 + *pd_address_in_code() = x; 17.21 + } 17.22 } else if (which == Assembler::narrow_oop_operand) { 17.23 address disp = Assembler::locate_operand(addr(), which); 17.24 - *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x); 17.25 + if (verify_only) { 17.26 + assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match"); 17.27 + } else { 17.28 + *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x); 17.29 + } 17.30 } else { 17.31 // Note: Use runtime_call_type relocations for call32_operand. 17.32 address ip = addr(); 17.33 address disp = Assembler::locate_operand(ip, which); 17.34 address next_ip = Assembler::locate_next_instruction(ip); 17.35 - *(int32_t*) disp = x - next_ip; 17.36 + if (verify_only) { 17.37 + assert(*(int32_t*) disp == (x - next_ip), "instructions must match"); 17.38 + } else { 17.39 + *(int32_t*) disp = x - next_ip; 17.40 + } 17.41 } 17.42 #else 17.43 - *pd_address_in_code() = x + o; 17.44 + if (verify_only) { 17.45 + assert(*pd_address_in_code() == (x + o), "instructions must match"); 17.46 + } else { 17.47 + *pd_address_in_code() = x + o; 17.48 + } 17.49 #endif // AMD64 17.50 } 17.51
18.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Mar 25 17:26:33 2011 -0700 18.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Fri Mar 25 18:04:45 2011 -0700 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 18.7 * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. 18.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.9 * 18.10 @@ -281,7 +281,7 @@ 18.11 18.12 if (method->is_static()) { 18.13 istate->set_oop_temp( 18.14 - method->constants()->pool_holder()->klass_part()->java_mirror()); 18.15 + method->constants()->pool_holder()->java_mirror()); 18.16 mirror = istate->oop_temp_addr(); 18.17 *(dst++) = &mirror; 18.18 } 18.19 @@ -667,7 +667,7 @@ 18.20 (BasicObjectLock *) stack->alloc(monitor_words * wordSize); 18.21 oop object; 18.22 if (method->is_static()) 18.23 - object = method->constants()->pool_holder()->klass_part()->java_mirror(); 18.24 + object = method->constants()->pool_holder()->java_mirror(); 18.25 else 18.26 object = (oop) locals[0]; 18.27 monitor->set_obj(object);
19.1 --- a/src/os/windows/vm/os_windows.cpp Fri Mar 25 17:26:33 2011 -0700 19.2 +++ b/src/os/windows/vm/os_windows.cpp Fri Mar 25 18:04:45 2011 -0700 19.3 @@ -3297,9 +3297,14 @@ 19.4 "possibility of dangling Thread pointer"); 19.5 19.6 OSThread* osthread = thread->osthread(); 19.7 - bool interrupted; 19.8 - interrupted = osthread->interrupted(); 19.9 - if (clear_interrupted == true) { 19.10 + bool interrupted = osthread->interrupted(); 19.11 + // There is no synchronization between the setting of the interrupt 19.12 + // and it being cleared here. It is critical - see 6535709 - that 19.13 + // we only clear the interrupt state, and reset the interrupt event, 19.14 + // if we are going to report that we were indeed interrupted - else 19.15 + // an interrupt can be "lost", leading to spurious wakeups or lost wakeups 19.16 + // depending on the timing 19.17 + if (interrupted && clear_interrupted) { 19.18 osthread->set_interrupted(false); 19.19 ResetEvent(osthread->interrupt_event()); 19.20 } // Otherwise leave the interrupted state alone
20.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp Fri Mar 25 17:26:33 2011 -0700 20.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Fri Mar 25 18:04:45 2011 -0700 20.3 @@ -1471,9 +1471,9 @@ 20.4 if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) { 20.5 if (state_before != NULL) { 20.6 // build a patching constant 20.7 - obj = new Constant(new ClassConstant(holder), state_before); 20.8 + obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before); 20.9 } else { 20.10 - obj = new Constant(new ClassConstant(holder)); 20.11 + obj = new Constant(new InstanceConstant(holder->java_mirror())); 20.12 } 20.13 } 20.14
21.1 --- a/src/share/vm/c1/c1_Runtime1.cpp Fri Mar 25 17:26:33 2011 -0700 21.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp Fri Mar 25 18:04:45 2011 -0700 21.3 @@ -808,7 +808,7 @@ 21.4 { klassOop klass = resolve_field_return_klass(caller_method, bci, CHECK); 21.5 // Save a reference to the class that has to be checked for initialization 21.6 init_klass = KlassHandle(THREAD, klass); 21.7 - k = klass; 21.8 + k = klass->java_mirror(); 21.9 } 21.10 break; 21.11 case Bytecodes::_new:
22.1 --- a/src/share/vm/ci/ciCPCache.cpp Fri Mar 25 17:26:33 2011 -0700 22.2 +++ b/src/share/vm/ci/ciCPCache.cpp Fri Mar 25 18:04:45 2011 -0700 22.3 @@ -1,5 +1,5 @@ 22.4 /* 22.5 - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 22.6 + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. 22.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.8 * 22.9 * This code is free software; you can redistribute it and/or modify it 22.10 @@ -46,8 +46,7 @@ 22.11 // ciCPCache::is_f1_null_at 22.12 bool ciCPCache::is_f1_null_at(int index) { 22.13 VM_ENTRY_MARK; 22.14 - oop f1 = entry_at(index)->f1(); 22.15 - return (f1 == NULL); 22.16 + return entry_at(index)->is_f1_null(); 22.17 } 22.18 22.19
23.1 --- a/src/share/vm/ci/ciField.cpp Fri Mar 25 17:26:33 2011 -0700 23.2 +++ b/src/share/vm/ci/ciField.cpp Fri Mar 25 18:04:45 2011 -0700 23.3 @@ -213,7 +213,7 @@ 23.4 // may change. The three examples are java.lang.System.in, 23.5 // java.lang.System.out, and java.lang.System.err. 23.6 23.7 - Handle k = _holder->get_klassOop(); 23.8 + KlassHandle k = _holder->get_klassOop(); 23.9 assert( SystemDictionary::System_klass() != NULL, "Check once per vm"); 23.10 if( k() == SystemDictionary::System_klass() ) { 23.11 // Check offsets for case 2: System.in, System.out, or System.err 23.12 @@ -225,36 +225,38 @@ 23.13 } 23.14 } 23.15 23.16 + Handle mirror = k->java_mirror(); 23.17 + 23.18 _is_constant = true; 23.19 switch(type()->basic_type()) { 23.20 case T_BYTE: 23.21 - _constant_value = ciConstant(type()->basic_type(), k->byte_field(_offset)); 23.22 + _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset)); 23.23 break; 23.24 case T_CHAR: 23.25 - _constant_value = ciConstant(type()->basic_type(), k->char_field(_offset)); 23.26 + _constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset)); 23.27 break; 23.28 case T_SHORT: 23.29 - _constant_value = ciConstant(type()->basic_type(), k->short_field(_offset)); 23.30 + _constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset)); 23.31 break; 23.32 case T_BOOLEAN: 23.33 - _constant_value = ciConstant(type()->basic_type(), k->bool_field(_offset)); 23.34 + _constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset)); 23.35 break; 23.36 case T_INT: 23.37 - _constant_value = ciConstant(type()->basic_type(), k->int_field(_offset)); 23.38 + _constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset)); 23.39 break; 23.40 case T_FLOAT: 23.41 - _constant_value = ciConstant(k->float_field(_offset)); 23.42 + _constant_value = ciConstant(mirror->float_field(_offset)); 23.43 break; 23.44 case T_DOUBLE: 23.45 - _constant_value = ciConstant(k->double_field(_offset)); 23.46 + _constant_value = ciConstant(mirror->double_field(_offset)); 23.47 break; 23.48 case T_LONG: 23.49 - _constant_value = ciConstant(k->long_field(_offset)); 23.50 + _constant_value = ciConstant(mirror->long_field(_offset)); 23.51 break; 23.52 case T_OBJECT: 23.53 case T_ARRAY: 23.54 { 23.55 - oop o = k->obj_field(_offset); 23.56 + oop o = mirror->obj_field(_offset); 23.57 23.58 // A field will be "constant" if it is known always to be 23.59 // a non-null reference to an instance of a particular class,
24.1 --- a/src/share/vm/ci/ciInstance.cpp Fri Mar 25 17:26:33 2011 -0700 24.2 +++ b/src/share/vm/ci/ciInstance.cpp Fri Mar 25 18:04:45 2011 -0700 24.3 @@ -1,5 +1,5 @@ 24.4 /* 24.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 24.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 24.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.8 * 24.9 * This code is free software; you can redistribute it and/or modify it 24.10 @@ -138,3 +138,9 @@ 24.11 st->print(" type="); 24.12 klass()->print(st); 24.13 } 24.14 + 24.15 + 24.16 +ciKlass* ciInstance::java_lang_Class_klass() { 24.17 + VM_ENTRY_MARK; 24.18 + return CURRENT_ENV->get_object(java_lang_Class::as_klassOop(get_oop()))->as_klass(); 24.19 +}
25.1 --- a/src/share/vm/ci/ciInstance.hpp Fri Mar 25 17:26:33 2011 -0700 25.2 +++ b/src/share/vm/ci/ciInstance.hpp Fri Mar 25 18:04:45 2011 -0700 25.3 @@ -1,5 +1,5 @@ 25.4 /* 25.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 25.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 25.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.8 * 25.9 * This code is free software; you can redistribute it and/or modify it 25.10 @@ -64,6 +64,8 @@ 25.11 25.12 // Constant value of a field at the specified offset. 25.13 ciConstant field_value_by_offset(int field_offset); 25.14 + 25.15 + ciKlass* java_lang_Class_klass(); 25.16 }; 25.17 25.18 #endif // SHARE_VM_CI_CIINSTANCE_HPP
26.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp Fri Mar 25 17:26:33 2011 -0700 26.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp Fri Mar 25 18:04:45 2011 -0700 26.3 @@ -1,5 +1,5 @@ 26.4 /* 26.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 26.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 26.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.8 * 26.9 * This code is free software; you can redistribute it and/or modify it 26.10 @@ -85,7 +85,6 @@ 26.11 if (h_k() != SystemDictionary::Object_klass()) { 26.12 super(); 26.13 } 26.14 - java_mirror(); 26.15 //compute_nonstatic_fields(); // done outside of constructor 26.16 } 26.17 26.18 @@ -320,6 +319,9 @@ 26.19 // Get the instance of java.lang.Class corresponding to this klass. 26.20 // Cache it on this->_java_mirror. 26.21 ciInstance* ciInstanceKlass::java_mirror() { 26.22 + if (is_shared()) { 26.23 + return ciKlass::java_mirror(); 26.24 + } 26.25 if (_java_mirror == NULL) { 26.26 _java_mirror = ciKlass::java_mirror(); 26.27 }
27.1 --- a/src/share/vm/ci/ciObjectFactory.cpp Fri Mar 25 17:26:33 2011 -0700 27.2 +++ b/src/share/vm/ci/ciObjectFactory.cpp Fri Mar 25 18:04:45 2011 -0700 27.3 @@ -663,7 +663,7 @@ 27.4 if (key->is_perm() && _non_perm_count == 0) { 27.5 return emptyBucket; 27.6 } else if (key->is_instance()) { 27.7 - if (key->klass() == SystemDictionary::Class_klass()) { 27.8 + if (key->klass() == SystemDictionary::Class_klass() && JavaObjectsInPerm) { 27.9 // class mirror instances are always perm 27.10 return emptyBucket; 27.11 }
28.1 --- a/src/share/vm/classfile/classFileParser.cpp Fri Mar 25 17:26:33 2011 -0700 28.2 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Mar 25 18:04:45 2011 -0700 28.3 @@ -37,6 +37,7 @@ 28.4 #include "memory/universe.inline.hpp" 28.5 #include "oops/constantPoolOop.hpp" 28.6 #include "oops/instanceKlass.hpp" 28.7 +#include "oops/instanceMirrorKlass.hpp" 28.8 #include "oops/klass.inline.hpp" 28.9 #include "oops/klassOop.hpp" 28.10 #include "oops/klassVtable.hpp" 28.11 @@ -2606,54 +2607,6 @@ 28.12 } 28.13 28.14 28.15 -static void initialize_static_field(fieldDescriptor* fd, TRAPS) { 28.16 - KlassHandle h_k (THREAD, fd->field_holder()); 28.17 - assert(h_k.not_null() && fd->is_static(), "just checking"); 28.18 - if (fd->has_initial_value()) { 28.19 - BasicType t = fd->field_type(); 28.20 - switch (t) { 28.21 - case T_BYTE: 28.22 - h_k()->byte_field_put(fd->offset(), fd->int_initial_value()); 28.23 - break; 28.24 - case T_BOOLEAN: 28.25 - h_k()->bool_field_put(fd->offset(), fd->int_initial_value()); 28.26 - break; 28.27 - case T_CHAR: 28.28 - h_k()->char_field_put(fd->offset(), fd->int_initial_value()); 28.29 - break; 28.30 - case T_SHORT: 28.31 - h_k()->short_field_put(fd->offset(), fd->int_initial_value()); 28.32 - break; 28.33 - case T_INT: 28.34 - h_k()->int_field_put(fd->offset(), fd->int_initial_value()); 28.35 - break; 28.36 - case T_FLOAT: 28.37 - h_k()->float_field_put(fd->offset(), fd->float_initial_value()); 28.38 - break; 28.39 - case T_DOUBLE: 28.40 - h_k()->double_field_put(fd->offset(), fd->double_initial_value()); 28.41 - break; 28.42 - case T_LONG: 28.43 - h_k()->long_field_put(fd->offset(), fd->long_initial_value()); 28.44 - break; 28.45 - case T_OBJECT: 28.46 - { 28.47 - #ifdef ASSERT 28.48 - TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK); 28.49 - assert(fd->signature() == sym, "just checking"); 28.50 - #endif 28.51 - oop string = fd->string_initial_value(CHECK); 28.52 - h_k()->obj_field_put(fd->offset(), string); 28.53 - } 28.54 - break; 28.55 - default: 28.56 - THROW_MSG(vmSymbols::java_lang_ClassFormatError(), 28.57 - "Illegal ConstantValue attribute in class file"); 28.58 - } 28.59 - } 28.60 -} 28.61 - 28.62 - 28.63 void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr, 28.64 constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) { 28.65 // This code is for compatibility with earlier jdk's that do not 28.66 @@ -2769,8 +2722,8 @@ 28.67 } 28.68 28.69 28.70 -void ClassFileParser::java_lang_Class_fix_pre(objArrayHandle* methods_ptr, 28.71 - FieldAllocationCount *fac_ptr, TRAPS) { 28.72 +void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size, 28.73 + FieldAllocationCount *fac_ptr) { 28.74 // Add fake fields for java.lang.Class instances 28.75 // 28.76 // This is not particularly nice. We should consider adding a 28.77 @@ -2787,10 +2740,13 @@ 28.78 // versions because when the offsets are computed at bootstrap 28.79 // time we don't know yet which version of the JDK we're running in. 28.80 28.81 - // The values below are fake but will force two non-static oop fields and 28.82 + // The values below are fake but will force three non-static oop fields and 28.83 // a corresponding non-static oop map block to be allocated. 28.84 const int extra = java_lang_Class::number_of_fake_oop_fields; 28.85 fac_ptr->nonstatic_oop_count += extra; 28.86 + 28.87 + // Reserve some leading space for fake ints 28.88 + *nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize; 28.89 } 28.90 28.91 28.92 @@ -3205,9 +3161,7 @@ 28.93 int next_nonstatic_field_offset; 28.94 28.95 // Calculate the starting byte offsets 28.96 - next_static_oop_offset = (instanceKlass::header_size() + 28.97 - align_object_offset(vtable_size) + 28.98 - align_object_offset(itable_size)) * wordSize; 28.99 + next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields(); 28.100 next_static_double_offset = next_static_oop_offset + 28.101 (fac.static_oop_count * heapOopSize); 28.102 if ( fac.static_double_count && 28.103 @@ -3226,15 +3180,16 @@ 28.104 fac.static_byte_count ), wordSize ); 28.105 static_field_size = (next_static_type_offset - 28.106 next_static_oop_offset) / wordSize; 28.107 + 28.108 + // Add fake fields for java.lang.Class instances (also see below) 28.109 + if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { 28.110 + java_lang_Class_fix_pre(&nonstatic_field_size, &fac); 28.111 + } 28.112 + 28.113 first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + 28.114 nonstatic_field_size * heapOopSize; 28.115 next_nonstatic_field_offset = first_nonstatic_field_offset; 28.116 28.117 - // Add fake fields for java.lang.Class instances (also see below) 28.118 - if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { 28.119 - java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle)); 28.120 - } 28.121 - 28.122 // adjust the vmentry field declaration in java.lang.invoke.MethodHandle 28.123 if (EnableMethodHandles && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) { 28.124 java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle)); 28.125 @@ -3566,7 +3521,7 @@ 28.126 } 28.127 28.128 // We can now create the basic klassOop for this klass 28.129 - klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size, 28.130 + klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size, 28.131 static_field_size, 28.132 total_oop_map_count, 28.133 rt, CHECK_(nullHandle)); 28.134 @@ -3588,7 +3543,7 @@ 28.135 this_klass->set_class_loader(class_loader()); 28.136 this_klass->set_nonstatic_field_size(nonstatic_field_size); 28.137 this_klass->set_has_nonstatic_fields(has_nonstatic_fields); 28.138 - this_klass->set_static_oop_field_size(fac.static_oop_count); 28.139 + this_klass->set_static_oop_field_count(fac.static_oop_count); 28.140 cp->set_pool_holder(this_klass()); 28.141 error_handler.set_in_error(false); // turn off error handler for cp 28.142 this_klass->set_constants(cp()); 28.143 @@ -3649,9 +3604,6 @@ 28.144 // Make sure this is the end of class file stream 28.145 guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle)); 28.146 28.147 - // Initialize static fields 28.148 - this_klass->do_local_static_fields(&initialize_static_field, CHECK_(nullHandle)); 28.149 - 28.150 // VerifyOops believes that once this has been set, the object is completely loaded. 28.151 // Compute transitive closure of interfaces this class implements 28.152 this_klass->set_transitive_interfaces(transitive_interfaces()); 28.153 @@ -3685,6 +3637,9 @@ 28.154 check_illegal_static_method(this_klass, CHECK_(nullHandle)); 28.155 } 28.156 28.157 + // Allocate mirror and initialize static fields 28.158 + java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle)); 28.159 + 28.160 ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()), 28.161 false /* not shared class */); 28.162
29.1 --- a/src/share/vm/classfile/classFileParser.hpp Fri Mar 25 17:26:33 2011 -0700 29.2 +++ b/src/share/vm/classfile/classFileParser.hpp Fri Mar 25 18:04:45 2011 -0700 29.3 @@ -154,11 +154,12 @@ 29.4 // Add the "discovered" field to java.lang.ref.Reference if 29.5 // it does not exist. 29.6 void java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr, 29.7 - constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS); 29.8 + constantPoolHandle cp, 29.9 + FieldAllocationCount *fac_ptr, TRAPS); 29.10 // Adjust the field allocation counts for java.lang.Class to add 29.11 // fake fields. 29.12 - void java_lang_Class_fix_pre(objArrayHandle* methods_ptr, 29.13 - FieldAllocationCount *fac_ptr, TRAPS); 29.14 + void java_lang_Class_fix_pre(int* nonstatic_field_size, 29.15 + FieldAllocationCount *fac_ptr); 29.16 // Adjust the next_nonstatic_oop_offset to place the fake fields 29.17 // before any Java fields. 29.18 void java_lang_Class_fix_post(int* next_nonstatic_oop_offset);
30.1 --- a/src/share/vm/classfile/javaClasses.cpp Fri Mar 25 17:26:33 2011 -0700 30.2 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Mar 25 18:04:45 2011 -0700 30.3 @@ -33,6 +33,7 @@ 30.4 #include "memory/resourceArea.hpp" 30.5 #include "memory/universe.inline.hpp" 30.6 #include "oops/instanceKlass.hpp" 30.7 +#include "oops/instanceMirrorKlass.hpp" 30.8 #include "oops/klass.hpp" 30.9 #include "oops/klassOop.hpp" 30.10 #include "oops/methodOop.hpp" 30.11 @@ -161,7 +162,7 @@ 30.12 } 30.13 30.14 Handle java_lang_String::create_tenured_from_unicode(jchar* unicode, int length, TRAPS) { 30.15 - return basic_create_from_unicode(unicode, length, true, CHECK_NH); 30.16 + return basic_create_from_unicode(unicode, length, JavaObjectsInPerm, CHECK_NH); 30.17 } 30.18 30.19 oop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) { 30.20 @@ -391,6 +392,75 @@ 30.21 } 30.22 } 30.23 30.24 +static void initialize_static_field(fieldDescriptor* fd, TRAPS) { 30.25 + Handle mirror (THREAD, fd->field_holder()->java_mirror()); 30.26 + assert(mirror.not_null() && fd->is_static(), "just checking"); 30.27 + if (fd->has_initial_value()) { 30.28 + BasicType t = fd->field_type(); 30.29 + switch (t) { 30.30 + case T_BYTE: 30.31 + mirror()->byte_field_put(fd->offset(), fd->int_initial_value()); 30.32 + break; 30.33 + case T_BOOLEAN: 30.34 + mirror()->bool_field_put(fd->offset(), fd->int_initial_value()); 30.35 + break; 30.36 + case T_CHAR: 30.37 + mirror()->char_field_put(fd->offset(), fd->int_initial_value()); 30.38 + break; 30.39 + case T_SHORT: 30.40 + mirror()->short_field_put(fd->offset(), fd->int_initial_value()); 30.41 + break; 30.42 + case T_INT: 30.43 + mirror()->int_field_put(fd->offset(), fd->int_initial_value()); 30.44 + break; 30.45 + case T_FLOAT: 30.46 + mirror()->float_field_put(fd->offset(), fd->float_initial_value()); 30.47 + break; 30.48 + case T_DOUBLE: 30.49 + mirror()->double_field_put(fd->offset(), fd->double_initial_value()); 30.50 + break; 30.51 + case T_LONG: 30.52 + mirror()->long_field_put(fd->offset(), fd->long_initial_value()); 30.53 + break; 30.54 + case T_OBJECT: 30.55 + { 30.56 + #ifdef ASSERT 30.57 + TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK); 30.58 + assert(fd->signature() == sym, "just checking"); 30.59 + #endif 30.60 + oop string = fd->string_initial_value(CHECK); 30.61 + mirror()->obj_field_put(fd->offset(), string); 30.62 + } 30.63 + break; 30.64 + default: 30.65 + THROW_MSG(vmSymbols::java_lang_ClassFormatError(), 30.66 + "Illegal ConstantValue attribute in class file"); 30.67 + } 30.68 + } 30.69 +} 30.70 + 30.71 + 30.72 +// During bootstrap, java.lang.Class wasn't loaded so static field 30.73 +// offsets were computed without the size added it. Go back and 30.74 +// update all the static field offsets to included the size. 30.75 +static void fixup_static_field(fieldDescriptor* fd, TRAPS) { 30.76 + if (fd->is_static()) { 30.77 + int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields(); 30.78 + typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields(); 30.79 + fields->short_at_put(fd->index() + instanceKlass::low_offset, extract_low_short_from_int(real_offset)); 30.80 + fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset)); 30.81 + } 30.82 +} 30.83 + 30.84 +void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) { 30.85 + assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already"); 30.86 + 30.87 + if (k->oop_is_instance()) { 30.88 + // Fixup the offsets 30.89 + instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK); 30.90 + } 30.91 + create_mirror(k, CHECK); 30.92 +} 30.93 30.94 oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) { 30.95 assert(k->java_mirror() == NULL, "should only assign mirror once"); 30.96 @@ -400,12 +470,17 @@ 30.97 // class is put into the system dictionary. 30.98 int computed_modifiers = k->compute_modifier_flags(CHECK_0); 30.99 k->set_modifier_flags(computed_modifiers); 30.100 - if (SystemDictionary::Class_klass_loaded()) { 30.101 + if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) { 30.102 // Allocate mirror (java.lang.Class instance) 30.103 - Handle mirror = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0); 30.104 + Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); 30.105 // Setup indirections 30.106 mirror->obj_field_put(klass_offset, k()); 30.107 k->set_java_mirror(mirror()); 30.108 + 30.109 + instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass()); 30.110 + java_lang_Class::set_oop_size(mirror(), mk->instance_size(k)); 30.111 + java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); 30.112 + 30.113 // It might also have a component mirror. This mirror must already exist. 30.114 if (k->oop_is_javaArray()) { 30.115 Handle comp_mirror; 30.116 @@ -428,6 +503,9 @@ 30.117 arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror()); 30.118 set_array_klass(comp_mirror(), k->as_klassOop()); 30.119 } 30.120 + } else if (k->oop_is_instance()) { 30.121 + // Initialize static fields 30.122 + instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL); 30.123 } 30.124 return mirror(); 30.125 } else { 30.126 @@ -436,21 +514,46 @@ 30.127 } 30.128 30.129 30.130 + 30.131 +int java_lang_Class::oop_size(oop java_class) { 30.132 + assert(oop_size_offset != 0, "must be set"); 30.133 + return java_class->int_field(oop_size_offset); 30.134 +} 30.135 +void java_lang_Class::set_oop_size(oop java_class, int size) { 30.136 + assert(oop_size_offset != 0, "must be set"); 30.137 + java_class->int_field_put(oop_size_offset, size); 30.138 +} 30.139 +int java_lang_Class::static_oop_field_count(oop java_class) { 30.140 + assert(static_oop_field_count_offset != 0, "must be set"); 30.141 + return java_class->int_field(static_oop_field_count_offset); 30.142 +} 30.143 +void java_lang_Class::set_static_oop_field_count(oop java_class, int size) { 30.144 + assert(static_oop_field_count_offset != 0, "must be set"); 30.145 + java_class->int_field_put(static_oop_field_count_offset, size); 30.146 +} 30.147 + 30.148 + 30.149 + 30.150 + 30.151 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { 30.152 // This should be improved by adding a field at the Java level or by 30.153 // introducing a new VM klass (see comment in ClassFileParser) 30.154 - oop java_class = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0); 30.155 + oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0); 30.156 if (type != T_VOID) { 30.157 klassOop aklass = Universe::typeArrayKlassObj(type); 30.158 assert(aklass != NULL, "correct bootstrap"); 30.159 set_array_klass(java_class, aklass); 30.160 } 30.161 + instanceMirrorKlass* mk = instanceMirrorKlass::cast(SystemDictionary::Class_klass()); 30.162 + java_lang_Class::set_oop_size(java_class, mk->instance_size(oop(NULL))); 30.163 + java_lang_Class::set_static_oop_field_count(java_class, 0); 30.164 return java_class; 30.165 } 30.166 30.167 30.168 klassOop java_lang_Class::as_klassOop(oop java_class) { 30.169 //%note memory_2 30.170 + assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 30.171 klassOop k = klassOop(java_class->obj_field(klass_offset)); 30.172 assert(k == NULL || k->is_klass(), "type check"); 30.173 return k; 30.174 @@ -2152,7 +2255,7 @@ 30.175 // Support for java_lang_ref_Reference 30.176 oop java_lang_ref_Reference::pending_list_lock() { 30.177 instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass()); 30.178 - char *addr = (((char *)ik->start_of_static_fields()) + static_lock_offset); 30.179 + address addr = ik->static_field_addr(static_lock_offset); 30.180 if (UseCompressedOops) { 30.181 return oopDesc::load_decode_heap_oop((narrowOop *)addr); 30.182 } else { 30.183 @@ -2162,7 +2265,7 @@ 30.184 30.185 HeapWord *java_lang_ref_Reference::pending_list_addr() { 30.186 instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass()); 30.187 - char *addr = (((char *)ik->start_of_static_fields()) + static_pending_offset); 30.188 + address addr = ik->static_field_addr(static_pending_offset); 30.189 // XXX This might not be HeapWord aligned, almost rather be char *. 30.190 return (HeapWord*)addr; 30.191 } 30.192 @@ -2185,16 +2288,14 @@ 30.193 30.194 jlong java_lang_ref_SoftReference::clock() { 30.195 instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass()); 30.196 - int offset = ik->offset_of_static_fields() + static_clock_offset; 30.197 - 30.198 - return SystemDictionary::SoftReference_klass()->long_field(offset); 30.199 + jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset); 30.200 + return *offset; 30.201 } 30.202 30.203 void java_lang_ref_SoftReference::set_clock(jlong value) { 30.204 instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass()); 30.205 - int offset = ik->offset_of_static_fields() + static_clock_offset; 30.206 - 30.207 - SystemDictionary::SoftReference_klass()->long_field_put(offset, value); 30.208 + jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset); 30.209 + *offset = value; 30.210 } 30.211 30.212 30.213 @@ -2625,26 +2726,18 @@ 30.214 30.215 30.216 // Support for java_lang_System 30.217 - 30.218 -void java_lang_System::compute_offsets() { 30.219 - assert(offset_of_static_fields == 0, "offsets should be initialized only once"); 30.220 - 30.221 - instanceKlass* ik = instanceKlass::cast(SystemDictionary::System_klass()); 30.222 - offset_of_static_fields = ik->offset_of_static_fields(); 30.223 +int java_lang_System::in_offset_in_bytes() { 30.224 + return (instanceMirrorKlass::offset_of_static_fields() + static_in_offset); 30.225 } 30.226 30.227 -int java_lang_System::in_offset_in_bytes() { 30.228 - return (offset_of_static_fields + static_in_offset); 30.229 + 30.230 +int java_lang_System::out_offset_in_bytes() { 30.231 + return (instanceMirrorKlass::offset_of_static_fields() + static_out_offset); 30.232 } 30.233 30.234 30.235 -int java_lang_System::out_offset_in_bytes() { 30.236 - return (offset_of_static_fields + static_out_offset); 30.237 -} 30.238 - 30.239 - 30.240 int java_lang_System::err_offset_in_bytes() { 30.241 - return (offset_of_static_fields + static_err_offset); 30.242 + return (instanceMirrorKlass::offset_of_static_fields() + static_err_offset); 30.243 } 30.244 30.245 30.246 @@ -2657,6 +2750,8 @@ 30.247 int java_lang_Class::array_klass_offset; 30.248 int java_lang_Class::resolved_constructor_offset; 30.249 int java_lang_Class::number_of_fake_oop_fields; 30.250 +int java_lang_Class::oop_size_offset; 30.251 +int java_lang_Class::static_oop_field_count_offset; 30.252 int java_lang_Throwable::backtrace_offset; 30.253 int java_lang_Throwable::detailMessage_offset; 30.254 int java_lang_Throwable::cause_offset; 30.255 @@ -2700,7 +2795,6 @@ 30.256 int java_lang_ref_SoftReference::timestamp_offset; 30.257 int java_lang_ref_SoftReference::static_clock_offset; 30.258 int java_lang_ClassLoader::parent_offset; 30.259 -int java_lang_System::offset_of_static_fields; 30.260 int java_lang_System::static_in_offset; 30.261 int java_lang_System::static_out_offset; 30.262 int java_lang_System::static_err_offset; 30.263 @@ -2817,10 +2911,19 @@ 30.264 java_lang_String::count_offset = java_lang_String::offset_offset + sizeof (jint); 30.265 java_lang_String::hash_offset = java_lang_String::count_offset + sizeof (jint); 30.266 30.267 - // Do the Class Class 30.268 - java_lang_Class::klass_offset = java_lang_Class::hc_klass_offset * x + header; 30.269 - java_lang_Class::array_klass_offset = java_lang_Class::hc_array_klass_offset * x + header; 30.270 - java_lang_Class::resolved_constructor_offset = java_lang_Class::hc_resolved_constructor_offset * x + header; 30.271 + { 30.272 + // Do the Class Class 30.273 + int offset = header; 30.274 + java_lang_Class::oop_size_offset = header; 30.275 + offset += BytesPerInt; 30.276 + java_lang_Class::static_oop_field_count_offset = offset; 30.277 + offset = align_size_up(offset + BytesPerInt, x); 30.278 + java_lang_Class::klass_offset = offset; 30.279 + offset += x; 30.280 + java_lang_Class::array_klass_offset = offset; 30.281 + offset += x; 30.282 + java_lang_Class::resolved_constructor_offset = offset; 30.283 + } 30.284 30.285 // This is NOT an offset 30.286 java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields; 30.287 @@ -2877,7 +2980,6 @@ 30.288 void JavaClasses::compute_offsets() { 30.289 30.290 java_lang_Class::compute_offsets(); 30.291 - java_lang_System::compute_offsets(); 30.292 java_lang_Thread::compute_offsets(); 30.293 java_lang_ThreadGroup::compute_offsets(); 30.294 if (EnableMethodHandles) { 30.295 @@ -2961,10 +3063,10 @@ 30.296 tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name); 30.297 return false; 30.298 } 30.299 - if (fd.offset() == hardcoded_offset + h_klass->offset_of_static_fields()) { 30.300 + if (fd.offset() == hardcoded_offset + instanceMirrorKlass::offset_of_static_fields()) { 30.301 return true; 30.302 } else { 30.303 - tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - h_klass->offset_of_static_fields()); 30.304 + tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - instanceMirrorKlass::offset_of_static_fields()); 30.305 return false; 30.306 } 30.307 }
31.1 --- a/src/share/vm/classfile/javaClasses.hpp Fri Mar 25 17:26:33 2011 -0700 31.2 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Mar 25 18:04:45 2011 -0700 31.3 @@ -138,10 +138,8 @@ 31.4 // The fake offsets are added by the class loader when java.lang.Class is loaded 31.5 31.6 enum { 31.7 - hc_klass_offset = 0, 31.8 - hc_array_klass_offset = 1, 31.9 - hc_resolved_constructor_offset = 2, 31.10 - hc_number_of_fake_oop_fields = 3 31.11 + hc_number_of_fake_oop_fields = 3, 31.12 + hc_number_of_fake_int_fields = 2 31.13 }; 31.14 31.15 static int klass_offset; 31.16 @@ -149,6 +147,9 @@ 31.17 static int array_klass_offset; 31.18 static int number_of_fake_oop_fields; 31.19 31.20 + static int oop_size_offset; 31.21 + static int static_oop_field_count_offset; 31.22 + 31.23 static void compute_offsets(); 31.24 static bool offsets_computed; 31.25 static int classRedefinedCount_offset; 31.26 @@ -157,6 +158,7 @@ 31.27 public: 31.28 // Instance creation 31.29 static oop create_mirror(KlassHandle k, TRAPS); 31.30 + static void fixup_mirror(KlassHandle k, TRAPS); 31.31 static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS); 31.32 // Conversion 31.33 static klassOop as_klassOop(oop java_class); 31.34 @@ -191,6 +193,12 @@ 31.35 static void set_classRedefinedCount(oop the_class_mirror, int value); 31.36 // Support for parallelCapable field 31.37 static bool parallelCapable(oop the_class_mirror); 31.38 + 31.39 + static int oop_size(oop java_class); 31.40 + static void set_oop_size(oop java_class, int size); 31.41 + static int static_oop_field_count(oop java_class); 31.42 + static void set_static_oop_field_count(oop java_class, int size); 31.43 + 31.44 // Debugging 31.45 friend class JavaClasses; 31.46 friend class instanceKlass; // verification code accesses offsets 31.47 @@ -1165,13 +1173,10 @@ 31.48 hc_static_err_offset = 2 31.49 }; 31.50 31.51 - static int offset_of_static_fields; 31.52 static int static_in_offset; 31.53 static int static_out_offset; 31.54 static int static_err_offset; 31.55 31.56 - static void compute_offsets(); 31.57 - 31.58 public: 31.59 static int in_offset_in_bytes(); 31.60 static int out_offset_in_bytes();
32.1 --- a/src/share/vm/classfile/symbolTable.cpp Fri Mar 25 17:26:33 2011 -0700 32.2 +++ b/src/share/vm/classfile/symbolTable.cpp Fri Mar 25 18:04:45 2011 -0700 32.3 @@ -530,7 +530,7 @@ 32.4 32.5 Handle string; 32.6 // try to reuse the string if possible 32.7 - if (!string_or_null.is_null() && string_or_null()->is_perm()) { 32.8 + if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) { 32.9 string = string_or_null; 32.10 } else { 32.11 string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); 32.12 @@ -662,7 +662,7 @@ 32.13 for ( ; p != NULL; p = p->next()) { 32.14 oop s = p->literal(); 32.15 guarantee(s != NULL, "interned string is NULL"); 32.16 - guarantee(s->is_perm(), "interned string not in permspace"); 32.17 + guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace"); 32.18 32.19 int length; 32.20 jchar* chars = java_lang_String::as_unicode_string(s, length);
33.1 --- a/src/share/vm/classfile/symbolTable.hpp Fri Mar 25 17:26:33 2011 -0700 33.2 +++ b/src/share/vm/classfile/symbolTable.hpp Fri Mar 25 18:04:45 2011 -0700 33.3 @@ -216,18 +216,14 @@ 33.4 oop basic_add(int index, Handle string_or_null, jchar* name, int len, 33.5 unsigned int hashValue, TRAPS); 33.6 33.7 - // Table size 33.8 - enum { 33.9 - string_table_size = 1009 33.10 - }; 33.11 - 33.12 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); 33.13 33.14 - StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {} 33.15 + StringTable() : Hashtable<oop>((int)StringTableSize, 33.16 + sizeof (HashtableEntry<oop>)) {} 33.17 33.18 StringTable(HashtableBucket* t, int number_of_entries) 33.19 - : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t, 33.20 - number_of_entries) {} 33.21 + : Hashtable<oop>((int)StringTableSize, sizeof (HashtableEntry<oop>), t, 33.22 + number_of_entries) {} 33.23 33.24 public: 33.25 // The string table 33.26 @@ -241,7 +237,7 @@ 33.27 static void create_table(HashtableBucket* t, int length, 33.28 int number_of_entries) { 33.29 assert(_the_table == NULL, "One string table allowed."); 33.30 - assert(length == string_table_size * sizeof(HashtableBucket), 33.31 + assert((size_t)length == StringTableSize * sizeof(HashtableBucket), 33.32 "bad shared string size."); 33.33 _the_table = new StringTable(t, number_of_entries); 33.34 }
34.1 --- a/src/share/vm/code/codeCache.cpp Fri Mar 25 17:26:33 2011 -0700 34.2 +++ b/src/share/vm/code/codeCache.cpp Fri Mar 25 18:04:45 2011 -0700 34.3 @@ -1,5 +1,5 @@ 34.4 /* 34.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 34.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 34.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.8 * 34.9 * This code is free software; you can redistribute it and/or modify it 34.10 @@ -337,7 +337,6 @@ 34.11 if (is_live) { 34.12 // Perform cur->oops_do(f), maybe just once per nmethod. 34.13 f->do_code_blob(cur); 34.14 - cur->fix_oop_relocations(); 34.15 } 34.16 } 34.17 34.18 @@ -552,6 +551,19 @@ 34.19 } 34.20 34.21 34.22 +void CodeCache::verify_oops() { 34.23 + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 34.24 + VerifyOopClosure voc; 34.25 + FOR_ALL_ALIVE_BLOBS(cb) { 34.26 + if (cb->is_nmethod()) { 34.27 + nmethod *nm = (nmethod*)cb; 34.28 + nm->oops_do(&voc); 34.29 + nm->verify_oop_relocations(); 34.30 + } 34.31 + } 34.32 +} 34.33 + 34.34 + 34.35 address CodeCache::first_address() { 34.36 assert_locked_or_safepoint(CodeCache_lock); 34.37 return (address)_heap->begin();
35.1 --- a/src/share/vm/code/codeCache.hpp Fri Mar 25 17:26:33 2011 -0700 35.2 +++ b/src/share/vm/code/codeCache.hpp Fri Mar 25 18:04:45 2011 -0700 35.3 @@ -122,6 +122,7 @@ 35.4 // GC support 35.5 static void gc_epilogue(); 35.6 static void gc_prologue(); 35.7 + static void verify_oops(); 35.8 // If "unloading_occurred" is true, then unloads (i.e., breaks root links 35.9 // to) any unmarked codeBlobs in the cache. Sets "marked_for_unloading" 35.10 // to "true" iff some code got unloaded.
36.1 --- a/src/share/vm/code/nmethod.cpp Fri Mar 25 17:26:33 2011 -0700 36.2 +++ b/src/share/vm/code/nmethod.cpp Fri Mar 25 18:04:45 2011 -0700 36.3 @@ -653,6 +653,9 @@ 36.4 _pc_desc_cache.reset_to(NULL); 36.5 36.6 code_buffer->copy_oops_to(this); 36.7 + if (ScavengeRootsInCode && detect_scavenge_root_oops()) { 36.8 + CodeCache::add_scavenge_root_nmethod(this); 36.9 + } 36.10 debug_only(verify_scavenge_root_oops()); 36.11 CodeCache::commit(this); 36.12 } 36.13 @@ -1105,6 +1108,20 @@ 36.14 } 36.15 36.16 36.17 +void nmethod::verify_oop_relocations() { 36.18 + // Ensure sure that the code matches the current oop values 36.19 + RelocIterator iter(this, NULL, NULL); 36.20 + while (iter.next()) { 36.21 + if (iter.type() == relocInfo::oop_type) { 36.22 + oop_Relocation* reloc = iter.oop_reloc(); 36.23 + if (!reloc->oop_is_immediate()) { 36.24 + reloc->verify_oop_relocation(); 36.25 + } 36.26 + } 36.27 + } 36.28 +} 36.29 + 36.30 + 36.31 ScopeDesc* nmethod::scope_desc_at(address pc) { 36.32 PcDesc* pd = pc_desc_at(pc); 36.33 guarantee(pd != NULL, "scope must be present"); 36.34 @@ -1823,6 +1840,7 @@ 36.35 assert(cur != NULL, "not NULL-terminated"); 36.36 nmethod* next = cur->_oops_do_mark_link; 36.37 cur->_oops_do_mark_link = NULL; 36.38 + cur->fix_oop_relocations(); 36.39 NOT_PRODUCT(if (TraceScavenge) cur->print_on(tty, "oops_do, unmark\n")); 36.40 cur = next; 36.41 }
37.1 --- a/src/share/vm/code/nmethod.hpp Fri Mar 25 17:26:33 2011 -0700 37.2 +++ b/src/share/vm/code/nmethod.hpp Fri Mar 25 18:04:45 2011 -0700 37.3 @@ -459,6 +459,7 @@ 37.4 public: 37.5 void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); } 37.6 void fix_oop_relocations() { fix_oop_relocations(NULL, NULL, false); } 37.7 + void verify_oop_relocations(); 37.8 37.9 bool is_at_poll_return(address pc); 37.10 bool is_at_poll_or_poll_return(address pc);
38.1 --- a/src/share/vm/code/relocInfo.cpp Fri Mar 25 17:26:33 2011 -0700 38.2 +++ b/src/share/vm/code/relocInfo.cpp Fri Mar 25 18:04:45 2011 -0700 38.3 @@ -798,6 +798,14 @@ 38.4 } 38.5 38.6 38.7 +void oop_Relocation::verify_oop_relocation() { 38.8 + if (!oop_is_immediate()) { 38.9 + // get the oop from the pool, and re-insert it into the instruction: 38.10 + verify_value(value()); 38.11 + } 38.12 +} 38.13 + 38.14 + 38.15 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop, 38.16 oop* &oop_addr, bool *is_optimized) { 38.17 assert(ic_call != NULL, "ic_call address must be set");
39.1 --- a/src/share/vm/code/relocInfo.hpp Fri Mar 25 17:26:33 2011 -0700 39.2 +++ b/src/share/vm/code/relocInfo.hpp Fri Mar 25 18:04:45 2011 -0700 39.3 @@ -765,7 +765,8 @@ 39.4 39.5 protected: 39.6 // platform-dependent utilities for decoding and patching instructions 39.7 - void pd_set_data_value (address x, intptr_t off); // a set or mem-ref 39.8 + void pd_set_data_value (address x, intptr_t off, bool verify_only = false); // a set or mem-ref 39.9 + void pd_verify_data_value (address x, intptr_t off) { pd_set_data_value(x, off, true); } 39.10 address pd_call_destination (address orig_addr = NULL); 39.11 void pd_set_call_destination (address x); 39.12 void pd_swap_in_breakpoint (address x, short* instrs, int instrlen); 39.13 @@ -880,6 +881,12 @@ 39.14 else 39.15 pd_set_data_value(x, o); 39.16 } 39.17 + void verify_value(address x) { 39.18 + if (addr_in_const()) 39.19 + assert(*(address*)addr() == x, "must agree"); 39.20 + else 39.21 + pd_verify_data_value(x, offset()); 39.22 + } 39.23 39.24 // The "o" (displacement) argument is relevant only to split relocations 39.25 // on RISC machines. In some CPUs (SPARC), the set-hi and set-lo ins'ns 39.26 @@ -950,6 +957,8 @@ 39.27 39.28 void fix_oop_relocation(); // reasserts oop value 39.29 39.30 + void verify_oop_relocation(); 39.31 + 39.32 address value() { return (address) *oop_addr(); } 39.33 39.34 bool oop_is_immediate() { return oop_index() == 0; }
40.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Mar 25 17:26:33 2011 -0700 40.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Mar 25 18:04:45 2011 -0700 40.3 @@ -5930,14 +5930,18 @@ 40.4 } 40.5 40.6 { 40.7 - TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty); 40.8 - // Now clean up stale oops in StringTable 40.9 - StringTable::unlink(&_is_alive_closure); 40.10 + TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty); 40.11 // Clean up unreferenced symbols in symbol table. 40.12 SymbolTable::unlink(); 40.13 } 40.14 } 40.15 40.16 + if (should_unload_classes() || !JavaObjectsInPerm) { 40.17 + TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty); 40.18 + // Now clean up stale oops in StringTable 40.19 + StringTable::unlink(&_is_alive_closure); 40.20 + } 40.21 + 40.22 verify_work_stacks_empty(); 40.23 // Restore any preserved marks as a result of mark stack or 40.24 // work queue overflow
41.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Fri Mar 25 17:26:33 2011 -0700 41.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Fri Mar 25 18:04:45 2011 -0700 41.3 @@ -23,6 +23,7 @@ 41.4 */ 41.5 41.6 #include "precompiled.hpp" 41.7 +#include "classfile/symbolTable.hpp" 41.8 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp" 41.9 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" 41.10 #include "gc_implementation/parallelScavenge/generationSizer.hpp" 41.11 @@ -439,6 +440,14 @@ 41.12 reference_processor()->enqueue_discovered_references(NULL); 41.13 } 41.14 41.15 + if (!JavaObjectsInPerm) { 41.16 + // Unlink any dead interned Strings 41.17 + StringTable::unlink(&_is_alive_closure); 41.18 + // Process the remaining live ones 41.19 + PSScavengeRootsClosure root_closure(promotion_manager); 41.20 + StringTable::oops_do(&root_closure); 41.21 + } 41.22 + 41.23 // Finally, flush the promotion_manager's labs, and deallocate its stacks. 41.24 PSPromotionManager::post_scavenge(); 41.25
42.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp Fri Mar 25 17:26:33 2011 -0700 42.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp Fri Mar 25 18:04:45 2011 -0700 42.3 @@ -86,4 +86,21 @@ 42.4 } 42.5 } 42.6 42.7 +class PSScavengeRootsClosure: public OopClosure { 42.8 + private: 42.9 + PSPromotionManager* _promotion_manager; 42.10 + 42.11 + protected: 42.12 + template <class T> void do_oop_work(T *p) { 42.13 + if (PSScavenge::should_scavenge(p)) { 42.14 + // We never card mark roots, maybe call a func without test? 42.15 + PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p); 42.16 + } 42.17 + } 42.18 + public: 42.19 + PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { } 42.20 + void do_oop(oop* p) { PSScavengeRootsClosure::do_oop_work(p); } 42.21 + void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); } 42.22 +}; 42.23 + 42.24 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP
43.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Fri Mar 25 17:26:33 2011 -0700 43.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp Fri Mar 25 18:04:45 2011 -0700 43.3 @@ -30,7 +30,7 @@ 43.4 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" 43.5 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp" 43.6 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" 43.7 -#include "gc_implementation/parallelScavenge/psScavenge.hpp" 43.8 +#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 43.9 #include "gc_implementation/parallelScavenge/psTasks.hpp" 43.10 #include "memory/iterator.hpp" 43.11 #include "memory/universe.hpp" 43.12 @@ -46,24 +46,6 @@ 43.13 // ScavengeRootsTask 43.14 // 43.15 43.16 -// Define before use 43.17 -class PSScavengeRootsClosure: public OopClosure { 43.18 - private: 43.19 - PSPromotionManager* _promotion_manager; 43.20 - 43.21 - protected: 43.22 - template <class T> void do_oop_work(T *p) { 43.23 - if (PSScavenge::should_scavenge(p)) { 43.24 - // We never card mark roots, maybe call a func without test? 43.25 - PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p); 43.26 - } 43.27 - } 43.28 - public: 43.29 - PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { } 43.30 - void do_oop(oop* p) { PSScavengeRootsClosure::do_oop_work(p); } 43.31 - void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); } 43.32 -}; 43.33 - 43.34 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) { 43.35 assert(Universe::heap()->is_gc_active(), "called outside gc"); 43.36
44.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Mar 25 17:26:33 2011 -0700 44.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Mar 25 18:04:45 2011 -0700 44.3 @@ -656,7 +656,7 @@ 44.4 // oop rcvr = locals[0].j.r; 44.5 oop rcvr; 44.6 if (METHOD->is_static()) { 44.7 - rcvr = METHOD->constants()->pool_holder()->klass_part()->java_mirror(); 44.8 + rcvr = METHOD->constants()->pool_holder()->java_mirror(); 44.9 } else { 44.10 rcvr = LOCALS_OBJECT(0); 44.11 VERIFY_OOP(rcvr); 44.12 @@ -2111,8 +2111,8 @@ 44.13 break; 44.14 44.15 case JVM_CONSTANT_Class: 44.16 - VERIFY_OOP(constants->resolved_klass_at(index)->klass_part()->java_mirror()); 44.17 - SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0); 44.18 + VERIFY_OOP(constants->resolved_klass_at(index)->java_mirror()); 44.19 + SET_STACK_OBJECT(constants->resolved_klass_at(index)->java_mirror(), 0); 44.20 break; 44.21 44.22 case JVM_CONSTANT_UnresolvedString:
45.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Fri Mar 25 17:26:33 2011 -0700 45.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Fri Mar 25 18:04:45 2011 -0700 45.3 @@ -118,7 +118,7 @@ 45.4 45.5 if (tag.is_unresolved_klass() || tag.is_klass()) { 45.6 klassOop klass = pool->klass_at(index, CHECK); 45.7 - oop java_class = klass->klass_part()->java_mirror(); 45.8 + oop java_class = klass->java_mirror(); 45.9 thread->set_vm_result(java_class); 45.10 } else { 45.11 #ifdef ASSERT 45.12 @@ -983,7 +983,8 @@ 45.13 ConstantPoolCacheEntry *cp_entry)) 45.14 45.15 // check the access_flags for the field in the klass 45.16 - instanceKlass* ik = instanceKlass::cast((klassOop)cp_entry->f1()); 45.17 + 45.18 + instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1())); 45.19 typeArrayOop fields = ik->fields(); 45.20 int index = cp_entry->field_index(); 45.21 assert(index < fields->length(), "holders field index is out of range"); 45.22 @@ -1009,7 +1010,7 @@ 45.23 // non-static field accessors have an object, but we need a handle 45.24 h_obj = Handle(thread, obj); 45.25 } 45.26 - instanceKlassHandle h_cp_entry_f1(thread, (klassOop)cp_entry->f1()); 45.27 + instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1())); 45.28 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2(), is_static); 45.29 JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid); 45.30 IRT_END 45.31 @@ -1017,7 +1018,7 @@ 45.32 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, 45.33 oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) 45.34 45.35 - klassOop k = (klassOop)cp_entry->f1(); 45.36 + klassOop k = java_lang_Class::as_klassOop(cp_entry->f1()); 45.37 45.38 // check the access_flags for the field in the klass 45.39 instanceKlass* ik = instanceKlass::cast(k);
46.1 --- a/src/share/vm/memory/compactingPermGenGen.hpp Fri Mar 25 17:26:33 2011 -0700 46.2 +++ b/src/share/vm/memory/compactingPermGenGen.hpp Fri Mar 25 18:04:45 2011 -0700 46.3 @@ -1,5 +1,5 @@ 46.4 /* 46.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 46.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 46.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 46.8 * 46.9 * This code is free software; you can redistribute it and/or modify it 46.10 @@ -105,7 +105,7 @@ 46.11 public: 46.12 46.13 enum { 46.14 - vtbl_list_size = 16, // number of entries in the shared space vtable list. 46.15 + vtbl_list_size = 17, // number of entries in the shared space vtable list. 46.16 num_virtuals = 200 // number of virtual methods in Klass (or 46.17 // subclass) objects, or greater. 46.18 };
47.1 --- a/src/share/vm/memory/dump.cpp Fri Mar 25 17:26:33 2011 -0700 47.2 +++ b/src/share/vm/memory/dump.cpp Fri Mar 25 18:04:45 2011 -0700 47.3 @@ -1561,6 +1561,7 @@ 47.4 // thread because it requires object allocation. 47.5 LinkClassesClosure lcc(Thread::current()); 47.6 object_iterate(&lcc); 47.7 + ensure_parsability(false); // arg is actually don't care 47.8 tty->print_cr("done. "); 47.9 47.10 // Create and dump the shared spaces.
48.1 --- a/src/share/vm/memory/oopFactory.cpp Fri Mar 25 17:26:33 2011 -0700 48.2 +++ b/src/share/vm/memory/oopFactory.cpp Fri Mar 25 18:04:45 2011 -0700 48.3 @@ -1,5 +1,5 @@ 48.4 /* 48.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 48.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 48.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 48.8 * 48.9 * This code is free software; you can redistribute it and/or modify it 48.10 @@ -117,12 +117,12 @@ 48.11 } 48.12 48.13 48.14 -klassOop oopFactory::new_instanceKlass(int vtable_len, int itable_len, 48.15 +klassOop oopFactory::new_instanceKlass(Symbol* name, int vtable_len, int itable_len, 48.16 int static_field_size, 48.17 unsigned int nonstatic_oop_map_count, 48.18 ReferenceType rt, TRAPS) { 48.19 instanceKlassKlass* ikk = instanceKlassKlass::cast(Universe::instanceKlassKlassObj()); 48.20 - return ikk->allocate_instance_klass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, rt, CHECK_NULL); 48.21 + return ikk->allocate_instance_klass(name, vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, rt, CHECK_NULL); 48.22 } 48.23 48.24
49.1 --- a/src/share/vm/memory/oopFactory.hpp Fri Mar 25 17:26:33 2011 -0700 49.2 +++ b/src/share/vm/memory/oopFactory.hpp Fri Mar 25 18:04:45 2011 -0700 49.3 @@ -1,5 +1,5 @@ 49.4 /* 49.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 49.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 49.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 49.8 * 49.9 * This code is free software; you can redistribute it and/or modify it 49.10 @@ -72,7 +72,8 @@ 49.11 TRAPS); 49.12 49.13 // Instance classes 49.14 - static klassOop new_instanceKlass(int vtable_len, int itable_len, 49.15 + static klassOop new_instanceKlass(Symbol* name, 49.16 + int vtable_len, int itable_len, 49.17 int static_field_size, 49.18 unsigned int nonstatic_oop_map_count, 49.19 ReferenceType rt, TRAPS);
50.1 --- a/src/share/vm/memory/sharedHeap.cpp Fri Mar 25 17:26:33 2011 -0700 50.2 +++ b/src/share/vm/memory/sharedHeap.cpp Fri Mar 25 18:04:45 2011 -0700 50.3 @@ -171,11 +171,13 @@ 50.4 } 50.5 50.6 if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) { 50.7 - if (so & SO_Strings) { 50.8 - StringTable::oops_do(roots); 50.9 - } 50.10 - // Verify if the string table contents are in the perm gen 50.11 - NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure)); 50.12 + if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) { 50.13 + StringTable::oops_do(roots); 50.14 + } 50.15 + if (JavaObjectsInPerm) { 50.16 + // Verify the string table contents are in the perm gen 50.17 + NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure)); 50.18 + } 50.19 } 50.20 50.21 if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
51.1 --- a/src/share/vm/memory/universe.cpp Fri Mar 25 17:26:33 2011 -0700 51.2 +++ b/src/share/vm/memory/universe.cpp Fri Mar 25 18:04:45 2011 -0700 51.3 @@ -1,5 +1,5 @@ 51.4 /* 51.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 51.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 51.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 51.8 * 51.9 * This code is free software; you can redistribute it and/or modify it 51.10 @@ -51,6 +51,7 @@ 51.11 #include "oops/cpCacheKlass.hpp" 51.12 #include "oops/cpCacheOop.hpp" 51.13 #include "oops/instanceKlass.hpp" 51.14 +#include "oops/instanceMirrorKlass.hpp" 51.15 #include "oops/instanceKlassKlass.hpp" 51.16 #include "oops/instanceRefKlass.hpp" 51.17 #include "oops/klassKlass.hpp" 51.18 @@ -521,6 +522,7 @@ 51.19 { objArrayKlassKlass o; add_vtable(list, &n, &o, count); } 51.20 { instanceKlassKlass o; add_vtable(list, &n, &o, count); } 51.21 { instanceKlass o; add_vtable(list, &n, &o, count); } 51.22 + { instanceMirrorKlass o; add_vtable(list, &n, &o, count); } 51.23 { instanceRefKlass o; add_vtable(list, &n, &o, count); } 51.24 { typeArrayKlassKlass o; add_vtable(list, &n, &o, count); } 51.25 { typeArrayKlass o; add_vtable(list, &n, &o, count); } 51.26 @@ -547,7 +549,7 @@ 51.27 KlassHandle k(THREAD, klassOop(obj)); 51.28 // We will never reach the CATCH below since Exceptions::_throw will cause 51.29 // the VM to exit if an exception is thrown during initialization 51.30 - java_lang_Class::create_mirror(k, CATCH); 51.31 + java_lang_Class::fixup_mirror(k, CATCH); 51.32 // This call unconditionally creates a new mirror for k, 51.33 // and links in k's component_mirror field if k is an array. 51.34 // If k is an objArray, k's element type must already have 51.35 @@ -605,6 +607,10 @@ 51.36 // walk over permanent objects created so far (mostly classes) and fixup their mirrors. Note 51.37 // that the number of objects allocated at this point is very small. 51.38 assert(SystemDictionary::Class_klass_loaded(), "java.lang.Class should be loaded"); 51.39 + 51.40 + // Cache the start of the static fields 51.41 + instanceMirrorKlass::init_offset_of_static_fields(); 51.42 + 51.43 FixupMirrorClosure blk; 51.44 Universe::heap()->permanent_object_iterate(&blk); 51.45 } 51.46 @@ -1313,6 +1319,8 @@ 51.47 JNIHandles::verify(); 51.48 if (!silent) gclog_or_tty->print("C-heap "); 51.49 os::check_heap(); 51.50 + if (!silent) gclog_or_tty->print("code cache "); 51.51 + CodeCache::verify_oops(); 51.52 if (!silent) gclog_or_tty->print_cr("]"); 51.53 51.54 _verify_in_progress = false;
52.1 --- a/src/share/vm/oops/arrayKlassKlass.cpp Fri Mar 25 17:26:33 2011 -0700 52.2 +++ b/src/share/vm/oops/arrayKlassKlass.cpp Fri Mar 25 18:04:45 2011 -0700 52.3 @@ -28,6 +28,13 @@ 52.4 #include "oops/arrayKlassKlass.hpp" 52.5 #include "oops/oop.inline.hpp" 52.6 #include "runtime/handles.inline.hpp" 52.7 +#ifndef SERIALGC 52.8 +#include "gc_implementation/parNew/parOopClosures.inline.hpp" 52.9 +#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" 52.10 +#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 52.11 +#include "memory/cardTableRS.hpp" 52.12 +#include "oops/oop.pcgc.inline.hpp" 52.13 +#endif 52.14 52.15 52.16 klassOop arrayKlassKlass::create_klass(TRAPS) { 52.17 @@ -104,9 +111,12 @@ 52.18 int arrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { 52.19 assert(obj->is_klass(), "must be klass"); 52.20 arrayKlass* ak = arrayKlass::cast(klassOop(obj)); 52.21 - blk->do_oop(ak->adr_component_mirror()); 52.22 - blk->do_oop(ak->adr_lower_dimension()); 52.23 - blk->do_oop(ak->adr_higher_dimension()); 52.24 + oop* addr = ak->adr_component_mirror(); 52.25 + if (mr.contains(addr)) blk->do_oop(addr); 52.26 + addr = ak->adr_lower_dimension(); 52.27 + if (mr.contains(addr)) blk->do_oop(addr); 52.28 + addr = ak->adr_higher_dimension(); 52.29 + if (mr.contains(addr)) blk->do_oop(addr); 52.30 ak->vtable()->oop_oop_iterate_m(blk, mr); 52.31 return klassKlass::oop_oop_iterate_m(obj, blk, mr); 52.32 } 52.33 @@ -114,6 +124,12 @@ 52.34 #ifndef SERIALGC 52.35 void arrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 52.36 assert(obj->blueprint()->oop_is_arrayKlass(),"must be an array klass"); 52.37 + arrayKlass* ak = arrayKlass::cast(klassOop(obj)); 52.38 + oop* p = ak->adr_component_mirror(); 52.39 + if (PSScavenge::should_scavenge(p)) { 52.40 + pm->claim_or_forward_depth(p); 52.41 + } 52.42 + klassKlass::oop_push_contents(pm, obj); 52.43 } 52.44 52.45 int arrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
53.1 --- a/src/share/vm/oops/constantPoolKlass.cpp Fri Mar 25 17:26:33 2011 -0700 53.2 +++ b/src/share/vm/oops/constantPoolKlass.cpp Fri Mar 25 18:04:45 2011 -0700 53.3 @@ -285,10 +285,11 @@ 53.4 void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 53.5 assert(obj->is_constantPool(), "should be constant pool"); 53.6 constantPoolOop cp = (constantPoolOop) obj; 53.7 - if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) { 53.8 - oop* base = (oop*)cp->base(); 53.9 - for (int i = 0; i < cp->length(); ++i, ++base) { 53.10 + if (cp->tags() != NULL && 53.11 + (!JavaObjectsInPerm || (AnonymousClasses && cp->has_pseudo_string()))) { 53.12 + for (int i = 1; i < cp->length(); ++i) { 53.13 if (cp->tag_at(i).is_string()) { 53.14 + oop* base = cp->obj_at_addr_raw(i); 53.15 if (PSScavenge::should_scavenge(base)) { 53.16 pm->claim_or_forward_depth(base); 53.17 } 53.18 @@ -460,7 +461,8 @@ 53.19 if (cp->tag_at(i).is_string()) { 53.20 if (!cp->has_pseudo_string()) { 53.21 if (entry.is_oop()) { 53.22 - guarantee(entry.get_oop()->is_perm(), "should be in permspace"); 53.23 + guarantee(!JavaObjectsInPerm || entry.get_oop()->is_perm(), 53.24 + "should be in permspace"); 53.25 guarantee(entry.get_oop()->is_instance(), "should be instance"); 53.26 } 53.27 } else {
54.1 --- a/src/share/vm/oops/constantPoolOop.cpp Fri Mar 25 17:26:33 2011 -0700 54.2 +++ b/src/share/vm/oops/constantPoolOop.cpp Fri Mar 25 18:04:45 2011 -0700 54.3 @@ -1,5 +1,5 @@ 54.4 /* 54.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 54.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 54.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 54.8 * 54.9 * This code is free software; you can redistribute it and/or modify it 54.10 @@ -481,7 +481,7 @@ 54.11 { 54.12 klassOop resolved = klass_at_impl(this_oop, index, CHECK_NULL); 54.13 // ldc wants the java mirror. 54.14 - result_oop = resolved->klass_part()->java_mirror(); 54.15 + result_oop = resolved->java_mirror(); 54.16 break; 54.17 } 54.18
55.1 --- a/src/share/vm/oops/cpCacheKlass.cpp Fri Mar 25 17:26:33 2011 -0700 55.2 +++ b/src/share/vm/oops/cpCacheKlass.cpp Fri Mar 25 18:04:45 2011 -0700 55.3 @@ -168,22 +168,18 @@ 55.4 void constantPoolCacheKlass::oop_push_contents(PSPromotionManager* pm, 55.5 oop obj) { 55.6 assert(obj->is_constantPoolCache(), "should be constant pool"); 55.7 - if (EnableInvokeDynamic) { 55.8 + if (ScavengeRootsInCode) { 55.9 constantPoolCacheOop cache = (constantPoolCacheOop)obj; 55.10 // during a scavenge, it is safe to inspect my pool, since it is perm 55.11 constantPoolOop pool = cache->constant_pool(); 55.12 assert(pool->is_constantPool(), "should be constant pool"); 55.13 - if (pool->has_invokedynamic()) { 55.14 - for (int i = 0; i < cache->length(); i++) { 55.15 - ConstantPoolCacheEntry* e = cache->entry_at(i); 55.16 - oop* p = (oop*)&e->_f1; 55.17 - if (e->is_secondary_entry()) { 55.18 - if (PSScavenge::should_scavenge(p)) 55.19 - pm->claim_or_forward_depth(p); 55.20 - assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)), 55.21 - "no live oops here"); 55.22 - } 55.23 - } 55.24 + for (int i = 0; i < cache->length(); i++) { 55.25 + ConstantPoolCacheEntry* e = cache->entry_at(i); 55.26 + oop* p = (oop*)&e->_f1; 55.27 + if (PSScavenge::should_scavenge(p)) 55.28 + pm->claim_or_forward_depth(p); 55.29 + assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)), 55.30 + "no live oops here"); 55.31 } 55.32 } 55.33 }
56.1 --- a/src/share/vm/oops/cpCacheOop.cpp Fri Mar 25 17:26:33 2011 -0700 56.2 +++ b/src/share/vm/oops/cpCacheOop.cpp Fri Mar 25 18:04:45 2011 -0700 56.3 @@ -133,7 +133,7 @@ 56.4 TosState field_type, 56.5 bool is_final, 56.6 bool is_volatile) { 56.7 - set_f1(field_holder()); 56.8 + set_f1(field_holder()->java_mirror()); 56.9 set_f2(field_offset); 56.10 // The field index is used by jvm/ti and is the index into fields() array 56.11 // in holder instanceKlass. This is scaled by instanceKlass::next_offset.
57.1 --- a/src/share/vm/oops/instanceKlass.cpp Fri Mar 25 17:26:33 2011 -0700 57.2 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Mar 25 18:04:45 2011 -0700 57.3 @@ -37,6 +37,7 @@ 57.4 #include "memory/oopFactory.hpp" 57.5 #include "memory/permGen.hpp" 57.6 #include "oops/instanceKlass.hpp" 57.7 +#include "oops/instanceMirrorKlass.hpp" 57.8 #include "oops/instanceOop.hpp" 57.9 #include "oops/methodOop.hpp" 57.10 #include "oops/objArrayKlassKlass.hpp" 57.11 @@ -649,6 +650,7 @@ 57.12 } 57.13 57.14 instanceOop instanceKlass::allocate_instance(TRAPS) { 57.15 + assert(!oop_is_instanceMirror(), "wrong allocation path"); 57.16 bool has_finalizer_flag = has_finalizer(); // Query before possible GC 57.17 int size = size_helper(); // Query before forming handle. 57.18 57.19 @@ -669,6 +671,7 @@ 57.20 // instances so simply disallow finalizable perm objects. This can 57.21 // be relaxed if a need for it is found. 57.22 assert(!has_finalizer(), "perm objects not allowed to have finalizers"); 57.23 + assert(!oop_is_instanceMirror(), "wrong allocation path"); 57.24 int size = size_helper(); // Query before forming handle. 57.25 KlassHandle h_k(THREAD, as_klassOop()); 57.26 instanceOop i = (instanceOop) 57.27 @@ -898,6 +901,7 @@ 57.28 } 57.29 } 57.30 57.31 + 57.32 void instanceKlass::do_local_static_fields(FieldClosure* cl) { 57.33 fieldDescriptor fd; 57.34 int length = fields()->length(); 57.35 @@ -1609,36 +1613,6 @@ 57.36 // The following macros call specialized macros, passing either oop or 57.37 // narrowOop as the specialization type. These test the UseCompressedOops 57.38 // flag. 57.39 -#define InstanceKlass_OOP_ITERATE(start_p, count, \ 57.40 - do_oop, assert_fn) \ 57.41 -{ \ 57.42 - if (UseCompressedOops) { \ 57.43 - InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \ 57.44 - start_p, count, \ 57.45 - do_oop, assert_fn) \ 57.46 - } else { \ 57.47 - InstanceKlass_SPECIALIZED_OOP_ITERATE(oop, \ 57.48 - start_p, count, \ 57.49 - do_oop, assert_fn) \ 57.50 - } \ 57.51 -} 57.52 - 57.53 -#define InstanceKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \ 57.54 - do_oop, assert_fn) \ 57.55 -{ \ 57.56 - if (UseCompressedOops) { \ 57.57 - InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \ 57.58 - start_p, count, \ 57.59 - low, high, \ 57.60 - do_oop, assert_fn) \ 57.61 - } else { \ 57.62 - InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \ 57.63 - start_p, count, \ 57.64 - low, high, \ 57.65 - do_oop, assert_fn) \ 57.66 - } \ 57.67 -} 57.68 - 57.69 #define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn) \ 57.70 { \ 57.71 /* Compute oopmap block range. The common case \ 57.72 @@ -1711,38 +1685,6 @@ 57.73 } \ 57.74 } 57.75 57.76 -void instanceKlass::follow_static_fields() { 57.77 - InstanceKlass_OOP_ITERATE( \ 57.78 - start_of_static_fields(), static_oop_field_size(), \ 57.79 - MarkSweep::mark_and_push(p), \ 57.80 - assert_is_in_closed_subset) 57.81 -} 57.82 - 57.83 -#ifndef SERIALGC 57.84 -void instanceKlass::follow_static_fields(ParCompactionManager* cm) { 57.85 - InstanceKlass_OOP_ITERATE( \ 57.86 - start_of_static_fields(), static_oop_field_size(), \ 57.87 - PSParallelCompact::mark_and_push(cm, p), \ 57.88 - assert_is_in) 57.89 -} 57.90 -#endif // SERIALGC 57.91 - 57.92 -void instanceKlass::adjust_static_fields() { 57.93 - InstanceKlass_OOP_ITERATE( \ 57.94 - start_of_static_fields(), static_oop_field_size(), \ 57.95 - MarkSweep::adjust_pointer(p), \ 57.96 - assert_nothing) 57.97 -} 57.98 - 57.99 -#ifndef SERIALGC 57.100 -void instanceKlass::update_static_fields() { 57.101 - InstanceKlass_OOP_ITERATE( \ 57.102 - start_of_static_fields(), static_oop_field_size(), \ 57.103 - PSParallelCompact::adjust_pointer(p), \ 57.104 - assert_nothing) 57.105 -} 57.106 -#endif // SERIALGC 57.107 - 57.108 void instanceKlass::oop_follow_contents(oop obj) { 57.109 assert(obj != NULL, "can't follow the content of NULL object"); 57.110 obj->follow_header(); 57.111 @@ -1829,22 +1771,6 @@ 57.112 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) 57.113 #endif // !SERIALGC 57.114 57.115 -void instanceKlass::iterate_static_fields(OopClosure* closure) { 57.116 - InstanceKlass_OOP_ITERATE( \ 57.117 - start_of_static_fields(), static_oop_field_size(), \ 57.118 - closure->do_oop(p), \ 57.119 - assert_is_in_reserved) 57.120 -} 57.121 - 57.122 -void instanceKlass::iterate_static_fields(OopClosure* closure, 57.123 - MemRegion mr) { 57.124 - InstanceKlass_BOUNDED_OOP_ITERATE( \ 57.125 - start_of_static_fields(), static_oop_field_size(), \ 57.126 - mr.start(), mr.end(), \ 57.127 - (closure)->do_oop_v(p), \ 57.128 - assert_is_in_closed_subset) 57.129 -} 57.130 - 57.131 int instanceKlass::oop_adjust_pointers(oop obj) { 57.132 int size = size_helper(); 57.133 InstanceKlass_OOP_MAP_ITERATE( \ 57.134 @@ -1873,21 +1799,6 @@ 57.135 return size_helper(); 57.136 } 57.137 57.138 -void instanceKlass::push_static_fields(PSPromotionManager* pm) { 57.139 - InstanceKlass_OOP_ITERATE( \ 57.140 - start_of_static_fields(), static_oop_field_size(), \ 57.141 - if (PSScavenge::should_scavenge(p)) { \ 57.142 - pm->claim_or_forward_depth(p); \ 57.143 - }, \ 57.144 - assert_nothing ) 57.145 -} 57.146 - 57.147 -void instanceKlass::copy_static_fields(ParCompactionManager* cm) { 57.148 - InstanceKlass_OOP_ITERATE( \ 57.149 - start_of_static_fields(), static_oop_field_size(), \ 57.150 - PSParallelCompact::adjust_pointer(p), \ 57.151 - assert_is_in) 57.152 -} 57.153 #endif // SERIALGC 57.154 57.155 // This klass is alive but the implementor link is not followed/updated. 57.156 @@ -2002,6 +1913,11 @@ 57.157 if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount(); 57.158 } 57.159 57.160 +address instanceKlass::static_field_addr(int offset) { 57.161 + return (address)(offset + instanceMirrorKlass::offset_of_static_fields() + (intptr_t)java_mirror()); 57.162 +} 57.163 + 57.164 + 57.165 const char* instanceKlass::signature_name() const { 57.166 const char* src = (const char*) (name()->as_C_string()); 57.167 const int src_length = (int)strlen(src); 57.168 @@ -2369,7 +2285,7 @@ 57.169 57.170 void FieldPrinter::do_field(fieldDescriptor* fd) { 57.171 _st->print(BULLET); 57.172 - if (fd->is_static() || (_obj == NULL)) { 57.173 + if (_obj == NULL) { 57.174 fd->print_on(_st); 57.175 _st->cr(); 57.176 } else { 57.177 @@ -2399,8 +2315,8 @@ 57.178 } 57.179 57.180 st->print_cr(BULLET"---- fields (total size %d words):", oop_size(obj)); 57.181 - FieldPrinter print_nonstatic_field(st, obj); 57.182 - do_nonstatic_fields(&print_nonstatic_field); 57.183 + FieldPrinter print_field(st, obj); 57.184 + do_nonstatic_fields(&print_field); 57.185 57.186 if (as_klassOop() == SystemDictionary::Class_klass()) { 57.187 st->print(BULLET"signature: "); 57.188 @@ -2418,6 +2334,12 @@ 57.189 st->print(BULLET"fake entry for array: "); 57.190 array_klass->print_value_on(st); 57.191 st->cr(); 57.192 + st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj)); 57.193 + st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj)); 57.194 + klassOop real_klass = java_lang_Class::as_klassOop(obj); 57.195 + if (real_klass && real_klass->klass_part()->oop_is_instance()) { 57.196 + instanceKlass::cast(real_klass)->do_local_static_fields(&print_field); 57.197 + } 57.198 } else if (as_klassOop() == SystemDictionary::MethodType_klass()) { 57.199 st->print(BULLET"signature: "); 57.200 java_lang_invoke_MethodType::print_signature(obj, st); 57.201 @@ -2560,7 +2482,7 @@ 57.202 57.203 57.204 void JNIid::verify(klassOop holder) { 57.205 - int first_field_offset = instanceKlass::cast(holder)->offset_of_static_fields(); 57.206 + int first_field_offset = instanceMirrorKlass::offset_of_static_fields(); 57.207 int end_field_offset; 57.208 end_field_offset = first_field_offset + (instanceKlass::cast(holder)->static_field_size() * wordSize); 57.209
58.1 --- a/src/share/vm/oops/instanceKlass.hpp Fri Mar 25 17:26:33 2011 -0700 58.2 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Mar 25 18:04:45 2011 -0700 58.3 @@ -75,8 +75,6 @@ 58.4 // [Java vtable length ] 58.5 // [oop map cache (stack maps) ] 58.6 // [EMBEDDED Java vtable ] size in words = vtable_len 58.7 -// [EMBEDDED static oop fields ] size in words = static_oop_fields_size 58.8 -// [ static non-oop fields ] size in words = static_field_size - static_oop_fields_size 58.9 // [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size 58.10 // 58.11 // The embedded nonstatic oop-map blocks are short pairs (offset, length) indicating 58.12 @@ -230,7 +228,7 @@ 58.13 // (including inherited fields but after header_size()). 58.14 int _nonstatic_field_size; 58.15 int _static_field_size; // number words used by static fields (oop and non-oop) in this klass 58.16 - int _static_oop_field_size;// number of static oop fields in this klass 58.17 + int _static_oop_field_count;// number of static oop fields in this klass 58.18 int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks 58.19 bool _is_marked_dependent; // used for marking during flushing and deoptimization 58.20 bool _rewritten; // methods rewritten. 58.21 @@ -281,8 +279,8 @@ 58.22 int static_field_size() const { return _static_field_size; } 58.23 void set_static_field_size(int size) { _static_field_size = size; } 58.24 58.25 - int static_oop_field_size() const { return _static_oop_field_size; } 58.26 - void set_static_oop_field_size(int size) { _static_oop_field_size = size; } 58.27 + int static_oop_field_count() const { return _static_oop_field_count; } 58.28 + void set_static_oop_field_count(int size) { _static_oop_field_count = size; } 58.29 58.30 // Java vtable 58.31 int vtable_length() const { return _vtable_len; } 58.32 @@ -660,6 +658,7 @@ 58.33 58.34 // Casting from klassOop 58.35 static instanceKlass* cast(klassOop k) { 58.36 + assert(k->is_klass(), "must be"); 58.37 Klass* kp = k->klass_part(); 58.38 assert(kp->null_vtbl() || kp->oop_is_instance_slow(), "cast to instanceKlass"); 58.39 return (instanceKlass*) kp; 58.40 @@ -667,7 +666,7 @@ 58.41 58.42 // Sizing (in words) 58.43 static int header_size() { return align_object_offset(oopDesc::header_size() + sizeof(instanceKlass)/HeapWordSize); } 58.44 - int object_size() const { return object_size(align_object_offset(vtable_length()) + align_object_offset(itable_length()) + static_field_size() + nonstatic_oop_map_size()); } 58.45 + int object_size() const { return object_size(align_object_offset(vtable_length()) + align_object_offset(itable_length()) + nonstatic_oop_map_size()); } 58.46 static int vtable_start_offset() { return header_size(); } 58.47 static int vtable_length_offset() { return oopDesc::header_size() + offset_of(instanceKlass, _vtable_len) / HeapWordSize; } 58.48 static int object_size(int extra) { return align_object_size(header_size() + extra); } 58.49 @@ -676,20 +675,12 @@ 58.50 intptr_t* start_of_itable() const { return start_of_vtable() + align_object_offset(vtable_length()); } 58.51 int itable_offset_in_words() const { return start_of_itable() - (intptr_t*)as_klassOop(); } 58.52 58.53 - // Static field offset is an offset into the Heap, should be converted by 58.54 - // based on UseCompressedOop for traversal 58.55 - HeapWord* start_of_static_fields() const { 58.56 - return (HeapWord*)(start_of_itable() + align_object_offset(itable_length())); 58.57 - } 58.58 - 58.59 intptr_t* end_of_itable() const { return start_of_itable() + itable_length(); } 58.60 58.61 - int offset_of_static_fields() const { 58.62 - return (intptr_t)start_of_static_fields() - (intptr_t)as_klassOop(); 58.63 - } 58.64 + address static_field_addr(int offset); 58.65 58.66 OopMapBlock* start_of_nonstatic_oop_maps() const { 58.67 - return (OopMapBlock*) (start_of_static_fields() + static_field_size()); 58.68 + return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length())); 58.69 } 58.70 58.71 // Allocation profiling support 58.72 @@ -719,8 +710,6 @@ 58.73 58.74 // Garbage collection 58.75 void oop_follow_contents(oop obj); 58.76 - void follow_static_fields(); 58.77 - void adjust_static_fields(); 58.78 int oop_adjust_pointers(oop obj); 58.79 bool object_is_parsable() const { return _init_state != unparsable_by_gc; } 58.80 // Value of _init_state must be zero (unparsable_by_gc) when klass field is set. 58.81 @@ -732,16 +721,6 @@ 58.82 // Parallel Scavenge and Parallel Old 58.83 PARALLEL_GC_DECLS 58.84 58.85 -#ifndef SERIALGC 58.86 - // Parallel Scavenge 58.87 - void push_static_fields(PSPromotionManager* pm); 58.88 - 58.89 - // Parallel Old 58.90 - void follow_static_fields(ParCompactionManager* cm); 58.91 - void copy_static_fields(ParCompactionManager* cm); 58.92 - void update_static_fields(); 58.93 -#endif // SERIALGC 58.94 - 58.95 // Naming 58.96 const char* signature_name() const; 58.97 58.98 @@ -770,9 +749,6 @@ 58.99 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) 58.100 #endif // !SERIALGC 58.101 58.102 - void iterate_static_fields(OopClosure* closure); 58.103 - void iterate_static_fields(OopClosure* closure, MemRegion mr); 58.104 - 58.105 private: 58.106 // initialization state 58.107 #ifdef ASSERT 58.108 @@ -926,6 +902,10 @@ 58.109 // Identifier lookup 58.110 JNIid* find(int offset); 58.111 58.112 + bool find_local_field(fieldDescriptor* fd) { 58.113 + return instanceKlass::cast(holder())->find_local_field_from_offset(offset(), true, fd); 58.114 + } 58.115 + 58.116 // Garbage collection support 58.117 oop* holder_addr() { return (oop*)&_holder; } 58.118 void oops_do(OopClosure* f);
59.1 --- a/src/share/vm/oops/instanceKlassKlass.cpp Fri Mar 25 17:26:33 2011 -0700 59.2 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Fri Mar 25 18:04:45 2011 -0700 59.3 @@ -31,6 +31,7 @@ 59.4 #include "memory/gcLocker.hpp" 59.5 #include "oops/constantPoolOop.hpp" 59.6 #include "oops/instanceKlass.hpp" 59.7 +#include "oops/instanceMirrorKlass.hpp" 59.8 #include "oops/instanceKlassKlass.hpp" 59.9 #include "oops/instanceRefKlass.hpp" 59.10 #include "oops/objArrayKlassKlass.hpp" 59.11 @@ -86,7 +87,6 @@ 59.12 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); 59.13 59.14 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); 59.15 - ik->follow_static_fields(); 59.16 { 59.17 HandleMark hm; 59.18 ik->vtable()->oop_follow_contents(); 59.19 @@ -127,7 +127,6 @@ 59.20 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); 59.21 59.22 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); 59.23 - ik->follow_static_fields(cm); 59.24 ik->vtable()->oop_follow_contents(cm); 59.25 ik->itable()->oop_follow_contents(cm); 59.26 59.27 @@ -168,7 +167,6 @@ 59.28 // Don't call size() or oop_size() since that is a virtual call. 59.29 int size = ik->object_size(); 59.30 59.31 - ik->iterate_static_fields(blk); 59.32 ik->vtable()->oop_oop_iterate(blk); 59.33 ik->itable()->oop_oop_iterate(blk); 59.34 59.35 @@ -209,7 +207,6 @@ 59.36 // Don't call size() or oop_size() since that is a virtual call. 59.37 int size = ik->object_size(); 59.38 59.39 - ik->iterate_static_fields(blk, mr); 59.40 ik->vtable()->oop_oop_iterate_m(blk, mr); 59.41 ik->itable()->oop_oop_iterate_m(blk, mr); 59.42 59.43 @@ -266,7 +263,6 @@ 59.44 assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); 59.45 59.46 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); 59.47 - ik->adjust_static_fields(); 59.48 ik->vtable()->oop_adjust_pointers(); 59.49 ik->itable()->oop_adjust_pointers(); 59.50 59.51 @@ -300,7 +296,6 @@ 59.52 #ifndef SERIALGC 59.53 void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 59.54 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); 59.55 - ik->push_static_fields(pm); 59.56 59.57 oop* loader_addr = ik->adr_class_loader(); 59.58 if (PSScavenge::should_scavenge(loader_addr)) { 59.59 @@ -336,7 +331,6 @@ 59.60 "must be instance klass"); 59.61 59.62 instanceKlass* ik = instanceKlass::cast(klassOop(obj)); 59.63 - ik->update_static_fields(); 59.64 ik->vtable()->oop_update_pointers(cm); 59.65 ik->itable()->oop_update_pointers(cm); 59.66 59.67 @@ -356,22 +350,28 @@ 59.68 #endif // SERIALGC 59.69 59.70 klassOop 59.71 -instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_len, 59.72 +instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int itable_len, 59.73 int static_field_size, 59.74 unsigned nonstatic_oop_map_count, 59.75 ReferenceType rt, TRAPS) { 59.76 59.77 const int nonstatic_oop_map_size = 59.78 instanceKlass::nonstatic_oop_map_size(nonstatic_oop_map_count); 59.79 - int size = instanceKlass::object_size(align_object_offset(vtable_len) + align_object_offset(itable_len) + static_field_size + nonstatic_oop_map_size); 59.80 + int size = instanceKlass::object_size(align_object_offset(vtable_len) + align_object_offset(itable_len) + nonstatic_oop_map_size); 59.81 59.82 // Allocation 59.83 KlassHandle h_this_klass(THREAD, as_klassOop()); 59.84 KlassHandle k; 59.85 if (rt == REF_NONE) { 59.86 - // regular klass 59.87 - instanceKlass o; 59.88 - k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); 59.89 + if (name != vmSymbols::java_lang_Class()) { 59.90 + // regular klass 59.91 + instanceKlass o; 59.92 + k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); 59.93 + } else { 59.94 + // Class 59.95 + instanceMirrorKlass o; 59.96 + k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); 59.97 + } 59.98 } else { 59.99 // reference klass 59.100 instanceRefKlass o; 59.101 @@ -408,7 +408,7 @@ 59.102 ik->set_source_debug_extension(NULL); 59.103 ik->set_array_name(NULL); 59.104 ik->set_inner_classes(NULL); 59.105 - ik->set_static_oop_field_size(0); 59.106 + ik->set_static_oop_field_count(0); 59.107 ik->set_nonstatic_field_size(0); 59.108 ik->set_is_marked_dependent(false); 59.109 ik->set_init_state(instanceKlass::allocated); 59.110 @@ -442,9 +442,6 @@ 59.111 // To get verify to work - must be set to partial loaded before first GC point. 59.112 k()->set_partially_loaded(); 59.113 } 59.114 - 59.115 - // GC can happen here 59.116 - java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror 59.117 return k(); 59.118 } 59.119 59.120 @@ -566,13 +563,6 @@ 59.121 FieldPrinter print_nonstatic_field(st); 59.122 ik->do_nonstatic_fields(&print_nonstatic_field); 59.123 59.124 - st->print(BULLET"static oop maps: "); 59.125 - if (ik->static_oop_field_size() > 0) { 59.126 - int first_offset = ik->offset_of_static_fields(); 59.127 - st->print("%d-%d", first_offset, first_offset + ik->static_oop_field_size() - 1); 59.128 - } 59.129 - st->cr(); 59.130 - 59.131 st->print(BULLET"non-static oop maps: "); 59.132 OopMapBlock* map = ik->start_of_nonstatic_oop_maps(); 59.133 OopMapBlock* end_map = map + ik->nonstatic_oop_map_count(); 59.134 @@ -630,7 +620,6 @@ 59.135 59.136 // Verify static fields 59.137 VerifyFieldClosure blk; 59.138 - ik->iterate_static_fields(&blk); 59.139 59.140 // Verify vtables 59.141 if (ik->is_linked()) {
60.1 --- a/src/share/vm/oops/instanceKlassKlass.hpp Fri Mar 25 17:26:33 2011 -0700 60.2 +++ b/src/share/vm/oops/instanceKlassKlass.hpp Fri Mar 25 18:04:45 2011 -0700 60.3 @@ -1,5 +1,5 @@ 60.4 /* 60.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 60.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 60.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 60.8 * 60.9 * This code is free software; you can redistribute it and/or modify it 60.10 @@ -41,7 +41,8 @@ 60.11 // Allocation 60.12 DEFINE_ALLOCATE_PERMANENT(instanceKlassKlass); 60.13 static klassOop create_klass(TRAPS); 60.14 - klassOop allocate_instance_klass(int vtable_len, 60.15 + klassOop allocate_instance_klass(Symbol* name, 60.16 + int vtable_len, 60.17 int itable_len, 60.18 int static_field_size, 60.19 unsigned int nonstatic_oop_map_count,
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/src/share/vm/oops/instanceMirrorKlass.cpp Fri Mar 25 18:04:45 2011 -0700 61.3 @@ -0,0 +1,313 @@ 61.4 +/* 61.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 61.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 61.7 + * 61.8 + * This code is free software; you can redistribute it and/or modify it 61.9 + * under the terms of the GNU General Public License version 2 only, as 61.10 + * published by the Free Software Foundation. 61.11 + * 61.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 61.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 61.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 61.15 + * version 2 for more details (a copy is included in the LICENSE file that 61.16 + * accompanied this code). 61.17 + * 61.18 + * You should have received a copy of the GNU General Public License version 61.19 + * 2 along with this work; if not, write to the Free Software Foundation, 61.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 61.21 + * 61.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 61.23 + * or visit www.oracle.com if you need additional information or have any 61.24 + * questions. 61.25 + * 61.26 + */ 61.27 + 61.28 +#include "precompiled.hpp" 61.29 +#include "classfile/javaClasses.hpp" 61.30 +#include "classfile/systemDictionary.hpp" 61.31 +#include "gc_implementation/shared/markSweep.inline.hpp" 61.32 +#include "gc_interface/collectedHeap.inline.hpp" 61.33 +#include "memory/genOopClosures.inline.hpp" 61.34 +#include "memory/oopFactory.hpp" 61.35 +#include "memory/permGen.hpp" 61.36 +#include "oops/instanceKlass.hpp" 61.37 +#include "oops/instanceMirrorKlass.hpp" 61.38 +#include "oops/instanceOop.hpp" 61.39 +#include "oops/oop.inline.hpp" 61.40 +#include "oops/symbol.hpp" 61.41 +#include "runtime/handles.inline.hpp" 61.42 +#ifndef SERIALGC 61.43 +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 61.44 +#include "gc_implementation/g1/g1OopClosures.inline.hpp" 61.45 +#include "gc_implementation/g1/g1RemSet.inline.hpp" 61.46 +#include "gc_implementation/g1/heapRegionSeq.inline.hpp" 61.47 +#include "gc_implementation/parNew/parOopClosures.inline.hpp" 61.48 +#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" 61.49 +#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 61.50 +#include "oops/oop.pcgc.inline.hpp" 61.51 +#endif 61.52 + 61.53 +int instanceMirrorKlass::_offset_of_static_fields = 0; 61.54 + 61.55 +#ifdef ASSERT 61.56 +template <class T> void assert_is_in(T *p) { 61.57 + T heap_oop = oopDesc::load_heap_oop(p); 61.58 + if (!oopDesc::is_null(heap_oop)) { 61.59 + oop o = oopDesc::decode_heap_oop_not_null(heap_oop); 61.60 + assert(Universe::heap()->is_in(o), "should be in heap"); 61.61 + } 61.62 +} 61.63 +template <class T> void assert_is_in_closed_subset(T *p) { 61.64 + T heap_oop = oopDesc::load_heap_oop(p); 61.65 + if (!oopDesc::is_null(heap_oop)) { 61.66 + oop o = oopDesc::decode_heap_oop_not_null(heap_oop); 61.67 + assert(Universe::heap()->is_in_closed_subset(o), "should be in closed"); 61.68 + } 61.69 +} 61.70 +template <class T> void assert_is_in_reserved(T *p) { 61.71 + T heap_oop = oopDesc::load_heap_oop(p); 61.72 + if (!oopDesc::is_null(heap_oop)) { 61.73 + oop o = oopDesc::decode_heap_oop_not_null(heap_oop); 61.74 + assert(Universe::heap()->is_in_reserved(o), "should be in reserved"); 61.75 + } 61.76 +} 61.77 +template <class T> void assert_nothing(T *p) {} 61.78 + 61.79 +#else 61.80 +template <class T> void assert_is_in(T *p) {} 61.81 +template <class T> void assert_is_in_closed_subset(T *p) {} 61.82 +template <class T> void assert_is_in_reserved(T *p) {} 61.83 +template <class T> void assert_nothing(T *p) {} 61.84 +#endif // ASSERT 61.85 + 61.86 +#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE( \ 61.87 + T, start_p, count, do_oop, \ 61.88 + assert_fn) \ 61.89 +{ \ 61.90 + T* p = (T*)(start_p); \ 61.91 + T* const end = p + (count); \ 61.92 + while (p < end) { \ 61.93 + (assert_fn)(p); \ 61.94 + do_oop; \ 61.95 + ++p; \ 61.96 + } \ 61.97 +} 61.98 + 61.99 +#define InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \ 61.100 + T, start_p, count, low, high, \ 61.101 + do_oop, assert_fn) \ 61.102 +{ \ 61.103 + T* const l = (T*)(low); \ 61.104 + T* const h = (T*)(high); \ 61.105 + assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 && \ 61.106 + mask_bits((intptr_t)h, sizeof(T)-1) == 0, \ 61.107 + "bounded region must be properly aligned"); \ 61.108 + T* p = (T*)(start_p); \ 61.109 + T* end = p + (count); \ 61.110 + if (p < l) p = l; \ 61.111 + if (end > h) end = h; \ 61.112 + while (p < end) { \ 61.113 + (assert_fn)(p); \ 61.114 + do_oop; \ 61.115 + ++p; \ 61.116 + } \ 61.117 +} 61.118 + 61.119 + 61.120 +#define InstanceMirrorKlass_OOP_ITERATE(start_p, count, \ 61.121 + do_oop, assert_fn) \ 61.122 +{ \ 61.123 + if (UseCompressedOops) { \ 61.124 + InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \ 61.125 + start_p, count, \ 61.126 + do_oop, assert_fn) \ 61.127 + } else { \ 61.128 + InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(oop, \ 61.129 + start_p, count, \ 61.130 + do_oop, assert_fn) \ 61.131 + } \ 61.132 +} 61.133 + 61.134 +// The following macros call specialized macros, passing either oop or 61.135 +// narrowOop as the specialization type. These test the UseCompressedOops 61.136 +// flag. 61.137 +#define InstanceMirrorKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \ 61.138 + do_oop, assert_fn) \ 61.139 +{ \ 61.140 + if (UseCompressedOops) { \ 61.141 + InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \ 61.142 + start_p, count, \ 61.143 + low, high, \ 61.144 + do_oop, assert_fn) \ 61.145 + } else { \ 61.146 + InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop, \ 61.147 + start_p, count, \ 61.148 + low, high, \ 61.149 + do_oop, assert_fn) \ 61.150 + } \ 61.151 +} 61.152 + 61.153 + 61.154 +void instanceMirrorKlass::oop_follow_contents(oop obj) { 61.155 + instanceKlass::oop_follow_contents(obj); 61.156 + InstanceMirrorKlass_OOP_ITERATE( \ 61.157 + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ 61.158 + MarkSweep::mark_and_push(p), \ 61.159 + assert_is_in_closed_subset) 61.160 +} 61.161 + 61.162 +#ifndef SERIALGC 61.163 +void instanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm, 61.164 + oop obj) { 61.165 + instanceKlass::oop_follow_contents(cm, obj); 61.166 + InstanceMirrorKlass_OOP_ITERATE( \ 61.167 + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ 61.168 + PSParallelCompact::mark_and_push(cm, p), \ 61.169 + assert_is_in) 61.170 +} 61.171 +#endif // SERIALGC 61.172 + 61.173 +int instanceMirrorKlass::oop_adjust_pointers(oop obj) { 61.174 + int size = oop_size(obj); 61.175 + instanceKlass::oop_adjust_pointers(obj); 61.176 + InstanceMirrorKlass_OOP_ITERATE( \ 61.177 + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ 61.178 + MarkSweep::adjust_pointer(p), \ 61.179 + assert_nothing) 61.180 + return size; 61.181 +} 61.182 + 61.183 +#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(T, nv_suffix) \ 61.184 + InstanceMirrorKlass_OOP_ITERATE( \ 61.185 + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ 61.186 + (closure)->do_oop##nv_suffix(p), \ 61.187 + assert_is_in_closed_subset) \ 61.188 + return oop_size(obj); \ 61.189 + 61.190 +#define InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(T, nv_suffix, mr) \ 61.191 + InstanceMirrorKlass_BOUNDED_OOP_ITERATE( \ 61.192 + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ 61.193 + mr.start(), mr.end(), \ 61.194 + (closure)->do_oop##nv_suffix(p), \ 61.195 + assert_is_in_closed_subset) \ 61.196 + return oop_size(obj); \ 61.197 + 61.198 + 61.199 +// Macro to define instanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for 61.200 +// all closures. Macros calling macros above for each oop size. 61.201 + 61.202 +#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ 61.203 + \ 61.204 +int instanceMirrorKlass:: \ 61.205 +oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) { \ 61.206 + /* Get size before changing pointers */ \ 61.207 + SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ 61.208 + \ 61.209 + instanceKlass::oop_oop_iterate##nv_suffix(obj, closure); \ 61.210 + \ 61.211 + if (UseCompressedOops) { \ 61.212 + InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \ 61.213 + } else { \ 61.214 + InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \ 61.215 + } \ 61.216 +} 61.217 + 61.218 +#ifndef SERIALGC 61.219 +#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \ 61.220 + \ 61.221 +int instanceMirrorKlass:: \ 61.222 +oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) { \ 61.223 + /* Get size before changing pointers */ \ 61.224 + SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ 61.225 + \ 61.226 + instanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure); \ 61.227 + \ 61.228 + if (UseCompressedOops) { \ 61.229 + InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix); \ 61.230 + } else { \ 61.231 + InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix); \ 61.232 + } \ 61.233 +} 61.234 +#endif // !SERIALGC 61.235 + 61.236 + 61.237 +#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix) \ 61.238 + \ 61.239 +int instanceMirrorKlass:: \ 61.240 +oop_oop_iterate##nv_suffix##_m(oop obj, \ 61.241 + OopClosureType* closure, \ 61.242 + MemRegion mr) { \ 61.243 + SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk); \ 61.244 + \ 61.245 + instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr); \ 61.246 + if (UseCompressedOops) { \ 61.247 + InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr); \ 61.248 + } else { \ 61.249 + InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr); \ 61.250 + } \ 61.251 +} 61.252 + 61.253 +ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN) 61.254 +ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN) 61.255 +#ifndef SERIALGC 61.256 +ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) 61.257 +ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN) 61.258 +#endif // SERIALGC 61.259 +ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) 61.260 +ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m) 61.261 + 61.262 +#ifndef SERIALGC 61.263 +void instanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 61.264 + instanceKlass::oop_push_contents(pm, obj); 61.265 + InstanceMirrorKlass_OOP_ITERATE( \ 61.266 + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ 61.267 + if (PSScavenge::should_scavenge(p)) { \ 61.268 + pm->claim_or_forward_depth(p); \ 61.269 + }, \ 61.270 + assert_nothing ) 61.271 +} 61.272 + 61.273 +int instanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 61.274 + instanceKlass::oop_update_pointers(cm, obj); 61.275 + InstanceMirrorKlass_OOP_ITERATE( \ 61.276 + start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\ 61.277 + PSParallelCompact::adjust_pointer(p), \ 61.278 + assert_nothing) 61.279 + return oop_size(obj); 61.280 +} 61.281 +#endif // SERIALGC 61.282 + 61.283 +int instanceMirrorKlass::instance_size(KlassHandle k) { 61.284 + if (k() != NULL && k->oop_is_instance()) { 61.285 + return align_object_size(size_helper() + instanceKlass::cast(k())->static_field_size()); 61.286 + } 61.287 + return size_helper(); 61.288 +} 61.289 + 61.290 +instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) { 61.291 + // Query before forming handle. 61.292 + int size = instance_size(k); 61.293 + KlassHandle h_k(THREAD, as_klassOop()); 61.294 + instanceOop i; 61.295 + 61.296 + if (JavaObjectsInPerm) { 61.297 + i = (instanceOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); 61.298 + } else { 61.299 + assert(ScavengeRootsInCode > 0, "must be"); 61.300 + i = (instanceOop) CollectedHeap::obj_allocate(h_k, size, CHECK_NULL); 61.301 + } 61.302 + 61.303 + return i; 61.304 +} 61.305 + 61.306 +int instanceMirrorKlass::oop_size(oop obj) const { 61.307 + return java_lang_Class::oop_size(obj); 61.308 +} 61.309 + 61.310 +int instanceMirrorKlass::compute_static_oop_field_count(oop obj) { 61.311 + klassOop k = java_lang_Class::as_klassOop(obj); 61.312 + if (k != NULL && k->klass_part()->oop_is_instance()) { 61.313 + return instanceKlass::cast(k)->static_oop_field_count(); 61.314 + } 61.315 + return 0; 61.316 +}
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/src/share/vm/oops/instanceMirrorKlass.hpp Fri Mar 25 18:04:45 2011 -0700 62.3 @@ -0,0 +1,110 @@ 62.4 +/* 62.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 62.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 62.7 + * 62.8 + * This code is free software; you can redistribute it and/or modify it 62.9 + * under the terms of the GNU General Public License version 2 only, as 62.10 + * published by the Free Software Foundation. 62.11 + * 62.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 62.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 62.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 62.15 + * version 2 for more details (a copy is included in the LICENSE file that 62.16 + * accompanied this code). 62.17 + * 62.18 + * You should have received a copy of the GNU General Public License version 62.19 + * 2 along with this work; if not, write to the Free Software Foundation, 62.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 62.21 + * 62.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 62.23 + * or visit www.oracle.com if you need additional information or have any 62.24 + * questions. 62.25 + * 62.26 + */ 62.27 + 62.28 +#ifndef SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP 62.29 +#define SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP 62.30 + 62.31 +#include "oops/instanceKlass.hpp" 62.32 + 62.33 +// An instanceMirrorKlass is a specialized instanceKlass for 62.34 +// java.lang.Class instances. These instances are special because 62.35 +// they contain the static fields of the class in addition to the 62.36 +// normal fields of Class. This means they are variable sized 62.37 +// instances and need special logic for computing their size and for 62.38 +// iteration of their oops. 62.39 + 62.40 + 62.41 +class instanceMirrorKlass: public instanceKlass { 62.42 + private: 62.43 + static int _offset_of_static_fields; 62.44 + 62.45 + public: 62.46 + // Type testing 62.47 + bool oop_is_instanceMirror() const { return true; } 62.48 + 62.49 + // Casting from klassOop 62.50 + static instanceMirrorKlass* cast(klassOop k) { 62.51 + assert(k->klass_part()->oop_is_instanceMirror(), "cast to instanceMirrorKlass"); 62.52 + return (instanceMirrorKlass*) k->klass_part(); 62.53 + } 62.54 + 62.55 + // Returns the size of the instance including the extra static fields. 62.56 + virtual int oop_size(oop obj) const; 62.57 + 62.58 + // Static field offset is an offset into the Heap, should be converted by 62.59 + // based on UseCompressedOop for traversal 62.60 + static HeapWord* start_of_static_fields(oop obj) { 62.61 + return (HeapWord*)((intptr_t)obj + offset_of_static_fields()); 62.62 + } 62.63 + 62.64 + static void init_offset_of_static_fields() { 62.65 + // Cache the offset of the static fields in the Class instance 62.66 + assert(_offset_of_static_fields == 0, "once"); 62.67 + _offset_of_static_fields = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->size_helper() << LogHeapWordSize; 62.68 + } 62.69 + 62.70 + static int offset_of_static_fields() { 62.71 + return _offset_of_static_fields; 62.72 + } 62.73 + 62.74 + int compute_static_oop_field_count(oop obj); 62.75 + 62.76 + // Given a Klass return the size of the instance 62.77 + int instance_size(KlassHandle k); 62.78 + 62.79 + // allocation 62.80 + DEFINE_ALLOCATE_PERMANENT(instanceMirrorKlass); 62.81 + instanceOop allocate_instance(KlassHandle k, TRAPS); 62.82 + 62.83 + // Garbage collection 62.84 + int oop_adjust_pointers(oop obj); 62.85 + void oop_follow_contents(oop obj); 62.86 + 62.87 + // Parallel Scavenge and Parallel Old 62.88 + PARALLEL_GC_DECLS 62.89 + 62.90 + int oop_oop_iterate(oop obj, OopClosure* blk) { 62.91 + return oop_oop_iterate_v(obj, blk); 62.92 + } 62.93 + int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { 62.94 + return oop_oop_iterate_v_m(obj, blk, mr); 62.95 + } 62.96 + 62.97 +#define InstanceMirrorKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix) \ 62.98 + int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk); \ 62.99 + int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk, MemRegion mr); 62.100 + 62.101 + ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL) 62.102 + ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL) 62.103 + 62.104 +#ifndef SERIALGC 62.105 +#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \ 62.106 + int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk); 62.107 + 62.108 + ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) 62.109 + ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL) 62.110 +#endif // !SERIALGC 62.111 +}; 62.112 + 62.113 +#endif // SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
63.1 --- a/src/share/vm/oops/klass.hpp Fri Mar 25 17:26:33 2011 -0700 63.2 +++ b/src/share/vm/oops/klass.hpp Fri Mar 25 18:04:45 2011 -0700 63.3 @@ -1,5 +1,5 @@ 63.4 /* 63.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 63.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 63.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 63.8 * 63.9 * This code is free software; you can redistribute it and/or modify it 63.10 @@ -577,6 +577,7 @@ 63.11 public: 63.12 // type testing operations 63.13 virtual bool oop_is_instance_slow() const { return false; } 63.14 + virtual bool oop_is_instanceMirror() const { return false; } 63.15 virtual bool oop_is_instanceRef() const { return false; } 63.16 virtual bool oop_is_array() const { return false; } 63.17 virtual bool oop_is_objArray_slow() const { return false; } 63.18 @@ -811,4 +812,8 @@ 63.19 #endif 63.20 }; 63.21 63.22 + 63.23 +inline oop klassOopDesc::java_mirror() const { return klass_part()->java_mirror(); } 63.24 + 63.25 + 63.26 #endif // SHARE_VM_OOPS_KLASS_HPP
64.1 --- a/src/share/vm/oops/klassKlass.cpp Fri Mar 25 17:26:33 2011 -0700 64.2 +++ b/src/share/vm/oops/klassKlass.cpp Fri Mar 25 18:04:45 2011 -0700 64.3 @@ -41,6 +41,10 @@ 64.4 #include "oops/typeArrayKlass.hpp" 64.5 #include "runtime/handles.inline.hpp" 64.6 #ifndef SERIALGC 64.7 +#include "gc_implementation/parNew/parOopClosures.inline.hpp" 64.8 +#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" 64.9 +#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 64.10 +#include "memory/cardTableRS.hpp" 64.11 #include "oops/oop.pcgc.inline.hpp" 64.12 #endif 64.13 64.14 @@ -175,6 +179,12 @@ 64.15 64.16 #ifndef SERIALGC 64.17 void klassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 64.18 + Klass* k = Klass::cast(klassOop(obj)); 64.19 + 64.20 + oop* p = k->adr_java_mirror(); 64.21 + if (PSScavenge::should_scavenge(p)) { 64.22 + pm->claim_or_forward_depth(p); 64.23 + } 64.24 } 64.25 64.26 int klassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 64.27 @@ -233,7 +243,7 @@ 64.28 64.29 if (k->java_mirror() != NULL || (k->oop_is_instance() && instanceKlass::cast(klassOop(obj))->is_loaded())) { 64.30 guarantee(k->java_mirror() != NULL, "should be allocated"); 64.31 - guarantee(k->java_mirror()->is_perm(), "should be in permspace"); 64.32 + guarantee(k->java_mirror()->is_perm() || !JavaObjectsInPerm, "should be in permspace"); 64.33 guarantee(k->java_mirror()->is_instance(), "should be instance"); 64.34 } 64.35 }
65.1 --- a/src/share/vm/oops/klassOop.hpp Fri Mar 25 17:26:33 2011 -0700 65.2 +++ b/src/share/vm/oops/klassOop.hpp Fri Mar 25 18:04:45 2011 -0700 65.3 @@ -1,5 +1,5 @@ 65.4 /* 65.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 65.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 65.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 65.8 * 65.9 * This code is free software; you can redistribute it and/or modify it 65.10 @@ -45,7 +45,73 @@ 65.11 static int klass_part_offset_in_bytes() { return sizeof(klassOopDesc); } 65.12 65.13 // returns the Klass part containing dispatching behavior 65.14 - Klass* klass_part() { return (Klass*)((address)this + klass_part_offset_in_bytes()); } 65.15 + Klass* klass_part() const { return (Klass*)((address)this + klass_part_offset_in_bytes()); } 65.16 + 65.17 + // Convenience wrapper 65.18 + inline oop java_mirror() const; 65.19 + 65.20 + private: 65.21 + // These have no implementation since klassOop should never be accessed in this fashion 65.22 + oop obj_field(int offset) const; 65.23 + void obj_field_put(int offset, oop value); 65.24 + void obj_field_raw_put(int offset, oop value); 65.25 + 65.26 + jbyte byte_field(int offset) const; 65.27 + void byte_field_put(int offset, jbyte contents); 65.28 + 65.29 + jchar char_field(int offset) const; 65.30 + void char_field_put(int offset, jchar contents); 65.31 + 65.32 + jboolean bool_field(int offset) const; 65.33 + void bool_field_put(int offset, jboolean contents); 65.34 + 65.35 + jint int_field(int offset) const; 65.36 + void int_field_put(int offset, jint contents); 65.37 + 65.38 + jshort short_field(int offset) const; 65.39 + void short_field_put(int offset, jshort contents); 65.40 + 65.41 + jlong long_field(int offset) const; 65.42 + void long_field_put(int offset, jlong contents); 65.43 + 65.44 + jfloat float_field(int offset) const; 65.45 + void float_field_put(int offset, jfloat contents); 65.46 + 65.47 + jdouble double_field(int offset) const; 65.48 + void double_field_put(int offset, jdouble contents); 65.49 + 65.50 + address address_field(int offset) const; 65.51 + void address_field_put(int offset, address contents); 65.52 + 65.53 + oop obj_field_acquire(int offset) const; 65.54 + void release_obj_field_put(int offset, oop value); 65.55 + 65.56 + jbyte byte_field_acquire(int offset) const; 65.57 + void release_byte_field_put(int offset, jbyte contents); 65.58 + 65.59 + jchar char_field_acquire(int offset) const; 65.60 + void release_char_field_put(int offset, jchar contents); 65.61 + 65.62 + jboolean bool_field_acquire(int offset) const; 65.63 + void release_bool_field_put(int offset, jboolean contents); 65.64 + 65.65 + jint int_field_acquire(int offset) const; 65.66 + void release_int_field_put(int offset, jint contents); 65.67 + 65.68 + jshort short_field_acquire(int offset) const; 65.69 + void release_short_field_put(int offset, jshort contents); 65.70 + 65.71 + jlong long_field_acquire(int offset) const; 65.72 + void release_long_field_put(int offset, jlong contents); 65.73 + 65.74 + jfloat float_field_acquire(int offset) const; 65.75 + void release_float_field_put(int offset, jfloat contents); 65.76 + 65.77 + jdouble double_field_acquire(int offset) const; 65.78 + void release_double_field_put(int offset, jdouble contents); 65.79 + 65.80 + address address_field_acquire(int offset) const; 65.81 + void release_address_field_put(int offset, address contents); 65.82 }; 65.83 65.84 #endif // SHARE_VM_OOPS_KLASSOOP_HPP
66.1 --- a/src/share/vm/oops/klassVtable.cpp Fri Mar 25 17:26:33 2011 -0700 66.2 +++ b/src/share/vm/oops/klassVtable.cpp Fri Mar 25 18:04:45 2011 -0700 66.3 @@ -1095,7 +1095,7 @@ 66.4 itableOffsetEntry* ioe = (itableOffsetEntry*)klass->start_of_itable(); 66.5 itableMethodEntry* ime = (itableMethodEntry*)(ioe + nof_interfaces); 66.6 intptr_t* end = klass->end_of_itable(); 66.7 - assert((oop*)(ime + nof_methods) <= (oop*)klass->start_of_static_fields(), "wrong offset calculation (1)"); 66.8 + assert((oop*)(ime + nof_methods) <= (oop*)klass->start_of_nonstatic_oop_maps(), "wrong offset calculation (1)"); 66.9 assert((oop*)(end) == (oop*)(ime + nof_methods), "wrong offset calculation (2)"); 66.10 66.11 // Visit all interfaces and initialize itable offset table
67.1 --- a/src/share/vm/oops/objArrayKlassKlass.cpp Fri Mar 25 17:26:33 2011 -0700 67.2 +++ b/src/share/vm/oops/objArrayKlassKlass.cpp Fri Mar 25 18:04:45 2011 -0700 67.3 @@ -31,6 +31,13 @@ 67.4 #include "oops/objArrayKlassKlass.hpp" 67.5 #include "oops/oop.inline.hpp" 67.6 #include "oops/oop.inline2.hpp" 67.7 +#ifndef SERIALGC 67.8 +#include "gc_implementation/parNew/parOopClosures.inline.hpp" 67.9 +#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" 67.10 +#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" 67.11 +#include "memory/cardTableRS.hpp" 67.12 +#include "oops/oop.pcgc.inline.hpp" 67.13 +#endif 67.14 67.15 klassOop objArrayKlassKlass::create_klass(TRAPS) { 67.16 objArrayKlassKlass o; 67.17 @@ -236,12 +243,23 @@ 67.18 addr = oak->bottom_klass_addr(); 67.19 if (mr.contains(addr)) blk->do_oop(addr); 67.20 67.21 - return arrayKlassKlass::oop_oop_iterate(obj, blk); 67.22 + return arrayKlassKlass::oop_oop_iterate_m(obj, blk, mr); 67.23 } 67.24 67.25 #ifndef SERIALGC 67.26 void objArrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 67.27 assert(obj->blueprint()->oop_is_objArrayKlass(),"must be an obj array klass"); 67.28 + objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 67.29 + oop* p = oak->element_klass_addr(); 67.30 + if (PSScavenge::should_scavenge(p)) { 67.31 + pm->claim_or_forward_depth(p); 67.32 + } 67.33 + p = oak->bottom_klass_addr(); 67.34 + if (PSScavenge::should_scavenge(p)) { 67.35 + pm->claim_or_forward_depth(p); 67.36 + } 67.37 + 67.38 + arrayKlassKlass::oop_push_contents(pm, obj); 67.39 } 67.40 67.41 int objArrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 67.42 @@ -287,7 +305,7 @@ 67.43 // Verification 67.44 67.45 void objArrayKlassKlass::oop_verify_on(oop obj, outputStream* st) { 67.46 - klassKlass::oop_verify_on(obj, st); 67.47 + arrayKlassKlass::oop_verify_on(obj, st); 67.48 objArrayKlass* oak = objArrayKlass::cast((klassOop)obj); 67.49 guarantee(oak->element_klass()->is_perm(), "should be in permspace"); 67.50 guarantee(oak->element_klass()->is_klass(), "should be klass");
68.1 --- a/src/share/vm/oops/oop.hpp Fri Mar 25 17:26:33 2011 -0700 68.2 +++ b/src/share/vm/oops/oop.hpp Fri Mar 25 18:04:45 2011 -0700 68.3 @@ -129,6 +129,7 @@ 68.4 68.5 // type test operations (inlined in oop.inline.h) 68.6 bool is_instance() const; 68.7 + bool is_instanceMirror() const; 68.8 bool is_instanceRef() const; 68.9 bool is_array() const; 68.10 bool is_objArray() const;
69.1 --- a/src/share/vm/oops/oop.inline.hpp Fri Mar 25 17:26:33 2011 -0700 69.2 +++ b/src/share/vm/oops/oop.inline.hpp Fri Mar 25 18:04:45 2011 -0700 69.3 @@ -1,5 +1,5 @@ 69.4 /* 69.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 69.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 69.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 69.8 * 69.9 * This code is free software; you can redistribute it and/or modify it 69.10 @@ -141,6 +141,7 @@ 69.11 inline bool oopDesc::is_a(klassOop k) const { return blueprint()->is_subtype_of(k); } 69.12 69.13 inline bool oopDesc::is_instance() const { return blueprint()->oop_is_instance(); } 69.14 +inline bool oopDesc::is_instanceMirror() const { return blueprint()->oop_is_instanceMirror(); } 69.15 inline bool oopDesc::is_instanceRef() const { return blueprint()->oop_is_instanceRef(); } 69.16 inline bool oopDesc::is_array() const { return blueprint()->oop_is_array(); } 69.17 inline bool oopDesc::is_objArray() const { return blueprint()->oop_is_objArray(); } 69.18 @@ -399,7 +400,7 @@ 69.19 69.20 inline int oopDesc::size_given_klass(Klass* klass) { 69.21 int lh = klass->layout_helper(); 69.22 - int s = lh >> LogHeapWordSize; // deliver size scaled by wordSize 69.23 + int s; 69.24 69.25 // lh is now a value computed at class initialization that may hint 69.26 // at the size. For instances, this is positive and equal to the 69.27 @@ -412,7 +413,13 @@ 69.28 // alive or dead. So the speed here is equal in importance to the 69.29 // speed of allocation. 69.30 69.31 - if (lh <= Klass::_lh_neutral_value) { 69.32 + if (lh > Klass::_lh_neutral_value) { 69.33 + if (!Klass::layout_helper_needs_slow_path(lh)) { 69.34 + s = lh >> LogHeapWordSize; // deliver size scaled by wordSize 69.35 + } else { 69.36 + s = klass->oop_size(this); 69.37 + } 69.38 + } else if (lh <= Klass::_lh_neutral_value) { 69.39 // The most common case is instances; fall through if so. 69.40 if (lh < Klass::_lh_neutral_value) { 69.41 // Second most common case is arrays. We have to fetch the
70.1 --- a/src/share/vm/oops/oopsHierarchy.hpp Fri Mar 25 17:26:33 2011 -0700 70.2 +++ b/src/share/vm/oops/oopsHierarchy.hpp Fri Mar 25 18:04:45 2011 -0700 70.3 @@ -1,5 +1,5 @@ 70.4 /* 70.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 70.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 70.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 70.8 * 70.9 * This code is free software; you can redistribute it and/or modify it 70.10 @@ -174,6 +174,7 @@ 70.11 70.12 class Klass; 70.13 class instanceKlass; 70.14 +class instanceMirrorKlass; 70.15 class instanceRefKlass; 70.16 class methodKlass; 70.17 class constMethodKlass;
71.1 --- a/src/share/vm/opto/c2_globals.hpp Fri Mar 25 17:26:33 2011 -0700 71.2 +++ b/src/share/vm/opto/c2_globals.hpp Fri Mar 25 18:04:45 2011 -0700 71.3 @@ -180,6 +180,9 @@ 71.4 develop(bool, TraceLoopPredicate, false, \ 71.5 "Trace generation of loop predicates") \ 71.6 \ 71.7 + develop(bool, TraceLoopOpts, false, \ 71.8 + "Trace executed loop optimizations") \ 71.9 + \ 71.10 product(bool, OptimizeFill, false, \ 71.11 "convert fill/copy loops into intrinsic") \ 71.12 \
72.1 --- a/src/share/vm/opto/compile.cpp Fri Mar 25 17:26:33 2011 -0700 72.2 +++ b/src/share/vm/opto/compile.cpp Fri Mar 25 18:04:45 2011 -0700 72.3 @@ -1,5 +1,5 @@ 72.4 /* 72.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 72.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 72.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 72.8 * 72.9 * This code is free software; you can redistribute it and/or modify it 72.10 @@ -1202,11 +1202,15 @@ 72.11 // Oop pointers need some flattening 72.12 const TypeInstPtr *to = tj->isa_instptr(); 72.13 if( to && _AliasLevel >= 2 && to != TypeOopPtr::BOTTOM ) { 72.14 + ciInstanceKlass *k = to->klass()->as_instance_klass(); 72.15 if( ptr == TypePtr::Constant ) { 72.16 - // No constant oop pointers (such as Strings); they alias with 72.17 - // unknown strings. 72.18 - assert(!is_known_inst, "not scalarizable allocation"); 72.19 - tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); 72.20 + if (to->klass() != ciEnv::current()->Class_klass() || 72.21 + offset < k->size_helper() * wordSize) { 72.22 + // No constant oop pointers (such as Strings); they alias with 72.23 + // unknown strings. 72.24 + assert(!is_known_inst, "not scalarizable allocation"); 72.25 + tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); 72.26 + } 72.27 } else if( is_known_inst ) { 72.28 tj = to; // Keep NotNull and klass_is_exact for instance type 72.29 } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { 72.30 @@ -1216,7 +1220,6 @@ 72.31 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); 72.32 } 72.33 // Canonicalize the holder of this field 72.34 - ciInstanceKlass *k = to->klass()->as_instance_klass(); 72.35 if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { 72.36 // First handle header references such as a LoadKlassNode, even if the 72.37 // object's klass is unloaded at compile time (4965979). 72.38 @@ -1224,9 +1227,13 @@ 72.39 tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); 72.40 } 72.41 } else if (offset < 0 || offset >= k->size_helper() * wordSize) { 72.42 - to = NULL; 72.43 - tj = TypeOopPtr::BOTTOM; 72.44 - offset = tj->offset(); 72.45 + // Static fields are in the space above the normal instance 72.46 + // fields in the java.lang.Class instance. 72.47 + if (to->klass() != ciEnv::current()->Class_klass()) { 72.48 + to = NULL; 72.49 + tj = TypeOopPtr::BOTTOM; 72.50 + offset = tj->offset(); 72.51 + } 72.52 } else { 72.53 ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset); 72.54 if (!k->equals(canonical_holder) || tj->offset() != offset) { 72.55 @@ -1399,7 +1406,7 @@ 72.56 72.57 72.58 //--------------------------------find_alias_type------------------------------ 72.59 -Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create) { 72.60 +Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create, ciField* original_field) { 72.61 if (_AliasLevel == 0) 72.62 return alias_type(AliasIdxBot); 72.63 72.64 @@ -1464,22 +1471,28 @@ 72.65 // but the base pointer type is not distinctive enough to identify 72.66 // references into JavaThread.) 72.67 72.68 - // Check for final instance fields. 72.69 + // Check for final fields. 72.70 const TypeInstPtr* tinst = flat->isa_instptr(); 72.71 if (tinst && tinst->offset() >= instanceOopDesc::base_offset_in_bytes()) { 72.72 - ciInstanceKlass *k = tinst->klass()->as_instance_klass(); 72.73 - ciField* field = k->get_field_by_offset(tinst->offset(), false); 72.74 + ciField* field; 72.75 + if (tinst->const_oop() != NULL && 72.76 + tinst->klass() == ciEnv::current()->Class_klass() && 72.77 + tinst->offset() >= (tinst->klass()->as_instance_klass()->size_helper() * wordSize)) { 72.78 + // static field 72.79 + ciInstanceKlass* k = tinst->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass(); 72.80 + field = k->get_field_by_offset(tinst->offset(), true); 72.81 + } else { 72.82 + ciInstanceKlass *k = tinst->klass()->as_instance_klass(); 72.83 + field = k->get_field_by_offset(tinst->offset(), false); 72.84 + } 72.85 + assert(field == NULL || 72.86 + original_field == NULL || 72.87 + (field->holder() == original_field->holder() && 72.88 + field->offset() == original_field->offset() && 72.89 + field->is_static() == original_field->is_static()), "wrong field?"); 72.90 // Set field() and is_rewritable() attributes. 72.91 if (field != NULL) alias_type(idx)->set_field(field); 72.92 } 72.93 - const TypeKlassPtr* tklass = flat->isa_klassptr(); 72.94 - // Check for final static fields. 72.95 - if (tklass && tklass->klass()->is_instance_klass()) { 72.96 - ciInstanceKlass *k = tklass->klass()->as_instance_klass(); 72.97 - ciField* field = k->get_field_by_offset(tklass->offset(), true); 72.98 - // Set field() and is_rewritable() attributes. 72.99 - if (field != NULL) alias_type(idx)->set_field(field); 72.100 - } 72.101 } 72.102 72.103 // Fill the cache for next time. 72.104 @@ -1502,10 +1515,10 @@ 72.105 Compile::AliasType* Compile::alias_type(ciField* field) { 72.106 const TypeOopPtr* t; 72.107 if (field->is_static()) 72.108 - t = TypeKlassPtr::make(field->holder()); 72.109 + t = TypeInstPtr::make(field->holder()->java_mirror()); 72.110 else 72.111 t = TypeOopPtr::make_from_klass_raw(field->holder()); 72.112 - AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes())); 72.113 + AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()), field); 72.114 assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct"); 72.115 return atp; 72.116 } 72.117 @@ -1522,7 +1535,7 @@ 72.118 if (adr_type == NULL) return true; 72.119 if (adr_type == TypePtr::BOTTOM) return true; 72.120 72.121 - return find_alias_type(adr_type, true) != NULL; 72.122 + return find_alias_type(adr_type, true, NULL) != NULL; 72.123 } 72.124 72.125 //-----------------------------must_alias--------------------------------------
73.1 --- a/src/share/vm/opto/compile.hpp Fri Mar 25 17:26:33 2011 -0700 73.2 +++ b/src/share/vm/opto/compile.hpp Fri Mar 25 18:04:45 2011 -0700 73.3 @@ -1,5 +1,5 @@ 73.4 /* 73.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 73.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 73.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 73.8 * 73.9 * This code is free software; you can redistribute it and/or modify it 73.10 @@ -596,7 +596,7 @@ 73.11 } 73.12 73.13 AliasType* alias_type(int idx) { assert(idx < num_alias_types(), "oob"); return _alias_types[idx]; } 73.14 - AliasType* alias_type(const TypePtr* adr_type) { return find_alias_type(adr_type, false); } 73.15 + AliasType* alias_type(const TypePtr* adr_type, ciField* field = NULL) { return find_alias_type(adr_type, false, field); } 73.16 bool have_alias_type(const TypePtr* adr_type); 73.17 AliasType* alias_type(ciField* field); 73.18 73.19 @@ -835,7 +835,7 @@ 73.20 void grow_alias_types(); 73.21 AliasCacheEntry* probe_alias_cache(const TypePtr* adr_type); 73.22 const TypePtr *flatten_alias_type(const TypePtr* adr_type) const; 73.23 - AliasType* find_alias_type(const TypePtr* adr_type, bool no_create); 73.24 + AliasType* find_alias_type(const TypePtr* adr_type, bool no_create, ciField* field); 73.25 73.26 void verify_top(Node*) const PRODUCT_RETURN; 73.27
74.1 --- a/src/share/vm/opto/graphKit.cpp Fri Mar 25 17:26:33 2011 -0700 74.2 +++ b/src/share/vm/opto/graphKit.cpp Fri Mar 25 18:04:45 2011 -0700 74.3 @@ -3338,6 +3338,49 @@ 74.4 return NULL; 74.5 } 74.6 74.7 +//----------------------------- loop predicates --------------------------- 74.8 + 74.9 +//------------------------------add_predicate_impl---------------------------- 74.10 +void GraphKit::add_predicate_impl(Deoptimization::DeoptReason reason, int nargs) { 74.11 + // Too many traps seen? 74.12 + if (too_many_traps(reason)) { 74.13 +#ifdef ASSERT 74.14 + if (TraceLoopPredicate) { 74.15 + int tc = C->trap_count(reason); 74.16 + tty->print("too many traps=%s tcount=%d in ", 74.17 + Deoptimization::trap_reason_name(reason), tc); 74.18 + method()->print(); // which method has too many predicate traps 74.19 + tty->cr(); 74.20 + } 74.21 +#endif 74.22 + // We cannot afford to take more traps here, 74.23 + // do not generate predicate. 74.24 + return; 74.25 + } 74.26 + 74.27 + Node *cont = _gvn.intcon(1); 74.28 + Node* opq = _gvn.transform(new (C, 2) Opaque1Node(C, cont)); 74.29 + Node *bol = _gvn.transform(new (C, 2) Conv2BNode(opq)); 74.30 + IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); 74.31 + Node* iffalse = _gvn.transform(new (C, 1) IfFalseNode(iff)); 74.32 + C->add_predicate_opaq(opq); 74.33 + { 74.34 + PreserveJVMState pjvms(this); 74.35 + set_control(iffalse); 74.36 + _sp += nargs; 74.37 + uncommon_trap(reason, Deoptimization::Action_maybe_recompile); 74.38 + } 74.39 + Node* iftrue = _gvn.transform(new (C, 1) IfTrueNode(iff)); 74.40 + set_control(iftrue); 74.41 +} 74.42 + 74.43 +//------------------------------add_predicate--------------------------------- 74.44 +void GraphKit::add_predicate(int nargs) { 74.45 + if (UseLoopPredicate) { 74.46 + add_predicate_impl(Deoptimization::Reason_predicate, nargs); 74.47 + } 74.48 +} 74.49 + 74.50 //----------------------------- store barriers ---------------------------- 74.51 #define __ ideal. 74.52
75.1 --- a/src/share/vm/opto/graphKit.hpp Fri Mar 25 17:26:33 2011 -0700 75.2 +++ b/src/share/vm/opto/graphKit.hpp Fri Mar 25 18:04:45 2011 -0700 75.3 @@ -793,6 +793,10 @@ 75.4 if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later 75.5 return iff; 75.6 } 75.7 + 75.8 + // Insert a loop predicate into the graph 75.9 + void add_predicate(int nargs = 0); 75.10 + void add_predicate_impl(Deoptimization::DeoptReason reason, int nargs); 75.11 }; 75.12 75.13 // Helper class to support building of control flow branches. Upon
76.1 --- a/src/share/vm/opto/idealKit.cpp Fri Mar 25 17:26:33 2011 -0700 76.2 +++ b/src/share/vm/opto/idealKit.cpp Fri Mar 25 18:04:45 2011 -0700 76.3 @@ -154,8 +154,18 @@ 76.4 // 76.5 // Pushes the loop top cvstate first, then the else (loop exit) cvstate 76.6 // onto the stack. 76.7 -void IdealKit::loop(IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) { 76.8 +void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) { 76.9 assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop"); 76.10 + 76.11 + // Sync IdealKit and graphKit. 76.12 + gkit->set_all_memory(this->merged_memory()); 76.13 + gkit->set_control(this->ctrl()); 76.14 + // Add loop predicate. 76.15 + gkit->add_predicate(nargs); 76.16 + // Update IdealKit memory. 76.17 + this->set_all_memory(gkit->merged_memory()); 76.18 + this->set_ctrl(gkit->control()); 76.19 + 76.20 set(iv, init); 76.21 Node* head = make_label(1); 76.22 bind(head);
77.1 --- a/src/share/vm/opto/idealKit.hpp Fri Mar 25 17:26:33 2011 -0700 77.2 +++ b/src/share/vm/opto/idealKit.hpp Fri Mar 25 18:04:45 2011 -0700 77.3 @@ -29,6 +29,7 @@ 77.4 #include "opto/cfgnode.hpp" 77.5 #include "opto/connode.hpp" 77.6 #include "opto/divnode.hpp" 77.7 +#include "opto/graphKit.hpp" 77.8 #include "opto/mulnode.hpp" 77.9 #include "opto/phaseX.hpp" 77.10 #include "opto/subnode.hpp" 77.11 @@ -160,7 +161,7 @@ 77.12 bool push_new_state = true); 77.13 void else_(); 77.14 void end_if(); 77.15 - void loop(IdealVariable& iv, Node* init, BoolTest::mask cmp, Node* limit, 77.16 + void loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask cmp, Node* limit, 77.17 float prob = PROB_LIKELY(0.9), float cnt = COUNT_UNKNOWN); 77.18 void end_loop(); 77.19 Node* make_label(int goto_ct);
78.1 --- a/src/share/vm/opto/library_call.cpp Fri Mar 25 17:26:33 2011 -0700 78.2 +++ b/src/share/vm/opto/library_call.cpp Fri Mar 25 18:04:45 2011 -0700 78.3 @@ -1101,6 +1101,8 @@ 78.4 float likely = PROB_LIKELY(0.9); 78.5 float unlikely = PROB_UNLIKELY(0.9); 78.6 78.7 + const int nargs = 2; // number of arguments to push back for uncommon trap in predicate 78.8 + 78.9 const int value_offset = java_lang_String::value_offset_in_bytes(); 78.10 const int count_offset = java_lang_String::count_offset_in_bytes(); 78.11 const int offset_offset = java_lang_String::offset_offset_in_bytes(); 78.12 @@ -1116,7 +1118,7 @@ 78.13 Node* sourcea = basic_plus_adr(string_object, string_object, value_offset); 78.14 Node* source = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset)); 78.15 78.16 - Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array)) ); 78.17 + Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) ); 78.18 jint target_length = target_array->length(); 78.19 const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); 78.20 const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); 78.21 @@ -1138,12 +1140,12 @@ 78.22 Node* return_ = __ make_label(1); 78.23 78.24 __ set(rtn,__ ConI(-1)); 78.25 - __ loop(i, sourceOffset, BoolTest::lt, sourceEnd); { 78.26 + __ loop(this, nargs, i, sourceOffset, BoolTest::lt, sourceEnd); { 78.27 Node* i2 = __ AddI(__ value(i), targetCountLess1); 78.28 // pin to prohibit loading of "next iteration" value which may SEGV (rare) 78.29 Node* src = load_array_element(__ ctrl(), source, i2, TypeAryPtr::CHARS); 78.30 __ if_then(src, BoolTest::eq, lastChar, unlikely); { 78.31 - __ loop(j, zero, BoolTest::lt, targetCountLess1); { 78.32 + __ loop(this, nargs, j, zero, BoolTest::lt, targetCountLess1); { 78.33 Node* tpj = __ AddI(targetOffset, __ value(j)); 78.34 Node* targ = load_array_element(no_ctrl, target, tpj, target_type); 78.35 Node* ipj = __ AddI(__ value(i), __ value(j));
79.1 --- a/src/share/vm/opto/loopTransform.cpp Fri Mar 25 17:26:33 2011 -0700 79.2 +++ b/src/share/vm/opto/loopTransform.cpp Fri Mar 25 18:04:45 2011 -0700 79.3 @@ -205,6 +205,8 @@ 79.4 } 79.5 phase->register_new_node(addx, phase->get_ctrl(x)); 79.6 phase->_igvn.replace_node(n1, addx); 79.7 + assert(phase->get_loop(phase->get_ctrl(n1)) == this, ""); 79.8 + _body.yank(n1); 79.9 return addx; 79.10 } 79.11 79.12 @@ -307,15 +309,21 @@ 79.13 // iterations adjusted. Therefore, we need to declare this loop as 79.14 // no longer a 'main' loop; it will need new pre and post loops before 79.15 // we can do further RCE. 79.16 +#ifndef PRODUCT 79.17 + if (TraceLoopOpts) { 79.18 + tty->print("Peel "); 79.19 + loop->dump_head(); 79.20 + } 79.21 +#endif 79.22 Node *h = loop->_head; 79.23 - if( h->is_CountedLoop() ) { 79.24 + if (h->is_CountedLoop()) { 79.25 CountedLoopNode *cl = h->as_CountedLoop(); 79.26 assert(cl->trip_count() > 0, "peeling a fully unrolled loop"); 79.27 cl->set_trip_count(cl->trip_count() - 1); 79.28 - if( cl->is_main_loop() ) { 79.29 + if (cl->is_main_loop()) { 79.30 cl->set_normal_loop(); 79.31 #ifndef PRODUCT 79.32 - if( PrintOpto && VerifyLoopOptimizations ) { 79.33 + if (PrintOpto && VerifyLoopOptimizations) { 79.34 tty->print("Peeling a 'main' loop; resetting to 'normal' "); 79.35 loop->dump_head(); 79.36 } 79.37 @@ -645,6 +653,15 @@ 79.38 // alignment. Useful to unroll loops that do no array accesses. 79.39 void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only ) { 79.40 79.41 +#ifndef PRODUCT 79.42 + if (TraceLoopOpts) { 79.43 + if (peel_only) 79.44 + tty->print("PeelMainPost "); 79.45 + else 79.46 + tty->print("PreMainPost "); 79.47 + loop->dump_head(); 79.48 + } 79.49 +#endif 79.50 C->set_major_progress(); 79.51 79.52 // Find common pieces of the loop being guarded with pre & post loops 79.53 @@ -897,16 +914,19 @@ 79.54 //------------------------------do_unroll-------------------------------------- 79.55 // Unroll the loop body one step - make each trip do 2 iterations. 79.56 void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip ) { 79.57 - assert( LoopUnrollLimit, "" ); 79.58 + assert(LoopUnrollLimit, ""); 79.59 + CountedLoopNode *loop_head = loop->_head->as_CountedLoop(); 79.60 + CountedLoopEndNode *loop_end = loop_head->loopexit(); 79.61 + assert(loop_end, ""); 79.62 #ifndef PRODUCT 79.63 - if( PrintOpto && VerifyLoopOptimizations ) { 79.64 + if (PrintOpto && VerifyLoopOptimizations) { 79.65 tty->print("Unrolling "); 79.66 loop->dump_head(); 79.67 + } else if (TraceLoopOpts) { 79.68 + tty->print("Unroll %d ", loop_head->unrolled_count()*2); 79.69 + loop->dump_head(); 79.70 } 79.71 #endif 79.72 - CountedLoopNode *loop_head = loop->_head->as_CountedLoop(); 79.73 - CountedLoopEndNode *loop_end = loop_head->loopexit(); 79.74 - assert( loop_end, "" ); 79.75 79.76 // Remember loop node count before unrolling to detect 79.77 // if rounds of unroll,optimize are making progress 79.78 @@ -915,7 +935,7 @@ 79.79 Node *ctrl = loop_head->in(LoopNode::EntryControl); 79.80 Node *limit = loop_head->limit(); 79.81 Node *init = loop_head->init_trip(); 79.82 - Node *strid = loop_head->stride(); 79.83 + Node *stride = loop_head->stride(); 79.84 79.85 Node *opaq = NULL; 79.86 if( adjust_min_trip ) { // If not maximally unrolling, need adjustment 79.87 @@ -955,13 +975,13 @@ 79.88 // odd iteration: (trip_cnt & ~1). Then back compute a new limit. 79.89 Node *span = new (C, 3) SubINode( limit, init ); 79.90 register_new_node( span, ctrl ); 79.91 - Node *trip = new (C, 3) DivINode( 0, span, strid ); 79.92 + Node *trip = new (C, 3) DivINode( 0, span, stride ); 79.93 register_new_node( trip, ctrl ); 79.94 Node *mtwo = _igvn.intcon(-2); 79.95 set_ctrl(mtwo, C->root()); 79.96 Node *rond = new (C, 3) AndINode( trip, mtwo ); 79.97 register_new_node( rond, ctrl ); 79.98 - Node *spn2 = new (C, 3) MulINode( rond, strid ); 79.99 + Node *spn2 = new (C, 3) MulINode( rond, stride ); 79.100 register_new_node( spn2, ctrl ); 79.101 Node *lim2 = new (C, 3) AddINode( spn2, init ); 79.102 register_new_node( lim2, ctrl ); 79.103 @@ -1040,17 +1060,23 @@ 79.104 79.105 void PhaseIdealLoop::do_maximally_unroll( IdealLoopTree *loop, Node_List &old_new ) { 79.106 CountedLoopNode *cl = loop->_head->as_CountedLoop(); 79.107 - assert( cl->trip_count() > 0, ""); 79.108 + assert(cl->trip_count() > 0, ""); 79.109 +#ifndef PRODUCT 79.110 + if (TraceLoopOpts) { 79.111 + tty->print("MaxUnroll %d ", cl->trip_count()); 79.112 + loop->dump_head(); 79.113 + } 79.114 +#endif 79.115 79.116 // If loop is tripping an odd number of times, peel odd iteration 79.117 - if( (cl->trip_count() & 1) == 1 ) { 79.118 - do_peeling( loop, old_new ); 79.119 + if ((cl->trip_count() & 1) == 1) { 79.120 + do_peeling(loop, old_new); 79.121 } 79.122 79.123 // Now its tripping an even number of times remaining. Double loop body. 79.124 // Do not adjust pre-guards; they are not needed and do not exist. 79.125 - if( cl->trip_count() > 0 ) { 79.126 - do_unroll( loop, old_new, false ); 79.127 + if (cl->trip_count() > 0) { 79.128 + do_unroll(loop, old_new, false); 79.129 } 79.130 } 79.131 79.132 @@ -1227,35 +1253,55 @@ 79.133 // Eliminate range-checks and other trip-counter vs loop-invariant tests. 79.134 void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) { 79.135 #ifndef PRODUCT 79.136 - if( PrintOpto && VerifyLoopOptimizations ) { 79.137 + if (PrintOpto && VerifyLoopOptimizations) { 79.138 tty->print("Range Check Elimination "); 79.139 loop->dump_head(); 79.140 + } else if (TraceLoopOpts) { 79.141 + tty->print("RangeCheck "); 79.142 + loop->dump_head(); 79.143 } 79.144 #endif 79.145 - assert( RangeCheckElimination, "" ); 79.146 + assert(RangeCheckElimination, ""); 79.147 CountedLoopNode *cl = loop->_head->as_CountedLoop(); 79.148 - assert( cl->is_main_loop(), "" ); 79.149 + assert(cl->is_main_loop(), ""); 79.150 + 79.151 + // protect against stride not being a constant 79.152 + if (!cl->stride_is_con()) 79.153 + return; 79.154 79.155 // Find the trip counter; we are iteration splitting based on it 79.156 Node *trip_counter = cl->phi(); 79.157 // Find the main loop limit; we will trim it's iterations 79.158 // to not ever trip end tests 79.159 Node *main_limit = cl->limit(); 79.160 + 79.161 + // Need to find the main-loop zero-trip guard 79.162 + Node *ctrl = cl->in(LoopNode::EntryControl); 79.163 + assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); 79.164 + Node *iffm = ctrl->in(0); 79.165 + assert(iffm->Opcode() == Op_If, ""); 79.166 + Node *bolzm = iffm->in(1); 79.167 + assert(bolzm->Opcode() == Op_Bool, ""); 79.168 + Node *cmpzm = bolzm->in(1); 79.169 + assert(cmpzm->is_Cmp(), ""); 79.170 + Node *opqzm = cmpzm->in(2); 79.171 + // Can not optimize a loop if pre-loop Opaque1 node is optimized 79.172 + // away and then another round of loop opts attempted. 79.173 + if (opqzm->Opcode() != Op_Opaque1) 79.174 + return; 79.175 + assert(opqzm->in(1) == main_limit, "do not understand situation"); 79.176 + 79.177 // Find the pre-loop limit; we will expand it's iterations to 79.178 // not ever trip low tests. 79.179 - Node *ctrl = cl->in(LoopNode::EntryControl); 79.180 - assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); 79.181 - Node *iffm = ctrl->in(0); 79.182 - assert( iffm->Opcode() == Op_If, "" ); 79.183 Node *p_f = iffm->in(0); 79.184 - assert( p_f->Opcode() == Op_IfFalse, "" ); 79.185 + assert(p_f->Opcode() == Op_IfFalse, ""); 79.186 CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd(); 79.187 - assert( pre_end->loopnode()->is_pre_loop(), "" ); 79.188 + assert(pre_end->loopnode()->is_pre_loop(), ""); 79.189 Node *pre_opaq1 = pre_end->limit(); 79.190 // Occasionally it's possible for a pre-loop Opaque1 node to be 79.191 // optimized away and then another round of loop opts attempted. 79.192 // We can not optimize this particular loop in that case. 79.193 - if( pre_opaq1->Opcode() != Op_Opaque1 ) 79.194 + if (pre_opaq1->Opcode() != Op_Opaque1) 79.195 return; 79.196 Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1; 79.197 Node *pre_limit = pre_opaq->in(1); 79.198 @@ -1266,25 +1312,11 @@ 79.199 // Ensure the original loop limit is available from the 79.200 // pre-loop Opaque1 node. 79.201 Node *orig_limit = pre_opaq->original_loop_limit(); 79.202 - if( orig_limit == NULL || _igvn.type(orig_limit) == Type::TOP ) 79.203 + if (orig_limit == NULL || _igvn.type(orig_limit) == Type::TOP) 79.204 return; 79.205 79.206 - // Need to find the main-loop zero-trip guard 79.207 - Node *bolzm = iffm->in(1); 79.208 - assert( bolzm->Opcode() == Op_Bool, "" ); 79.209 - Node *cmpzm = bolzm->in(1); 79.210 - assert( cmpzm->is_Cmp(), "" ); 79.211 - Node *opqzm = cmpzm->in(2); 79.212 - if( opqzm->Opcode() != Op_Opaque1 ) 79.213 - return; 79.214 - assert( opqzm->in(1) == main_limit, "do not understand situation" ); 79.215 - 79.216 // Must know if its a count-up or count-down loop 79.217 79.218 - // protect against stride not being a constant 79.219 - if ( !cl->stride_is_con() ) { 79.220 - return; 79.221 - } 79.222 int stride_con = cl->stride_con(); 79.223 Node *zero = _igvn.intcon(0); 79.224 Node *one = _igvn.intcon(1); 79.225 @@ -1566,16 +1598,24 @@ 79.226 // have on the last iteration. This will break the loop. 79.227 bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) { 79.228 // Minimum size must be empty loop 79.229 - if( _body.size() > 7/*number of nodes in an empty loop*/ ) return false; 79.230 + if (_body.size() > 7/*number of nodes in an empty loop*/) 79.231 + return false; 79.232 79.233 - if( !_head->is_CountedLoop() ) return false; // Dead loop 79.234 + if (!_head->is_CountedLoop()) 79.235 + return false; // Dead loop 79.236 CountedLoopNode *cl = _head->as_CountedLoop(); 79.237 - if( !cl->loopexit() ) return false; // Malformed loop 79.238 - if( !phase->is_member(this,phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue)) ) ) 79.239 + if (!cl->loopexit()) 79.240 + return false; // Malformed loop 79.241 + if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue)))) 79.242 return false; // Infinite loop 79.243 #ifndef PRODUCT 79.244 - if( PrintOpto ) 79.245 - tty->print_cr("Removing empty loop"); 79.246 + if (PrintOpto) { 79.247 + tty->print("Removing empty loop"); 79.248 + this->dump_head(); 79.249 + } else if (TraceLoopOpts) { 79.250 + tty->print("Empty "); 79.251 + this->dump_head(); 79.252 + } 79.253 #endif 79.254 #ifdef ASSERT 79.255 // Ensure only one phi which is the iv. 79.256 @@ -1720,7 +1760,7 @@ 79.257 //------------------------------iteration_split-------------------------------- 79.258 bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) { 79.259 // Recursively iteration split nested loops 79.260 - if( _child && !_child->iteration_split( phase, old_new )) 79.261 + if (_child && !_child->iteration_split(phase, old_new)) 79.262 return false; 79.263 79.264 // Clean out prior deadwood 79.265 @@ -1729,21 +1769,20 @@ 79.266 79.267 // Look for loop-exit tests with my 50/50 guesses from the Parsing stage. 79.268 // Replace with a 1-in-10 exit guess. 79.269 - if( _parent /*not the root loop*/ && 79.270 + if (_parent /*not the root loop*/ && 79.271 !_irreducible && 79.272 // Also ignore the occasional dead backedge 79.273 - !tail()->is_top() ) { 79.274 + !tail()->is_top()) { 79.275 adjust_loop_exit_prob(phase); 79.276 } 79.277 79.278 - 79.279 // Gate unrolling, RCE and peeling efforts. 79.280 - if( !_child && // If not an inner loop, do not split 79.281 + if (!_child && // If not an inner loop, do not split 79.282 !_irreducible && 79.283 _allow_optimizations && 79.284 - !tail()->is_top() ) { // Also ignore the occasional dead backedge 79.285 + !tail()->is_top()) { // Also ignore the occasional dead backedge 79.286 if (!_has_call) { 79.287 - if (!iteration_split_impl( phase, old_new )) { 79.288 + if (!iteration_split_impl(phase, old_new)) { 79.289 return false; 79.290 } 79.291 } else if (policy_unswitching(phase)) { 79.292 @@ -1752,16 +1791,17 @@ 79.293 } 79.294 79.295 // Minor offset re-organization to remove loop-fallout uses of 79.296 - // trip counter. 79.297 - if( _head->is_CountedLoop() ) phase->reorg_offsets( this ); 79.298 - if( _next && !_next->iteration_split( phase, old_new )) 79.299 + // trip counter when there was no major reshaping. 79.300 + phase->reorg_offsets(this); 79.301 + 79.302 + if (_next && !_next->iteration_split(phase, old_new)) 79.303 return false; 79.304 return true; 79.305 } 79.306 79.307 //-------------------------------is_uncommon_trap_proj---------------------------- 79.308 // Return true if proj is the form of "proj->[region->..]call_uct" 79.309 -bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, bool must_reason_predicate) { 79.310 +bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason) { 79.311 int path_limit = 10; 79.312 assert(proj, "invalid argument"); 79.313 Node* out = proj; 79.314 @@ -1772,8 +1812,8 @@ 79.315 if (out->is_CallStaticJava()) { 79.316 int req = out->as_CallStaticJava()->uncommon_trap_request(); 79.317 if (req != 0) { 79.318 - Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(req); 79.319 - if (!must_reason_predicate || reason == Deoptimization::Reason_predicate){ 79.320 + Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); 79.321 + if (trap_reason == reason || reason == Deoptimization::Reason_none) { 79.322 return true; 79.323 } 79.324 } 79.325 @@ -1790,15 +1830,15 @@ 79.326 // other_proj->[region->..]call_uct" 79.327 // 79.328 // "must_reason_predicate" means the uct reason must be Reason_predicate 79.329 -bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, bool must_reason_predicate) { 79.330 +bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, Deoptimization::DeoptReason reason) { 79.331 Node *in0 = proj->in(0); 79.332 if (!in0->is_If()) return false; 79.333 // Variation of a dead If node. 79.334 if (in0->outcnt() < 2) return false; 79.335 IfNode* iff = in0->as_If(); 79.336 79.337 - // we need "If(Conv2B(Opaque1(...)))" pattern for must_reason_predicate 79.338 - if (must_reason_predicate) { 79.339 + // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate 79.340 + if (reason != Deoptimization::Reason_none) { 79.341 if (iff->in(1)->Opcode() != Op_Conv2B || 79.342 iff->in(1)->in(1)->Opcode() != Op_Opaque1) { 79.343 return false; 79.344 @@ -1806,7 +1846,19 @@ 79.345 } 79.346 79.347 ProjNode* other_proj = iff->proj_out(1-proj->_con)->as_Proj(); 79.348 - return is_uncommon_trap_proj(other_proj, must_reason_predicate); 79.349 + return is_uncommon_trap_proj(other_proj, reason); 79.350 +} 79.351 + 79.352 +//-------------------------------register_control------------------------- 79.353 +void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) { 79.354 + assert(n->is_CFG(), "must be control node"); 79.355 + _igvn.register_new_node_with_optimizer(n); 79.356 + loop->_body.push(n); 79.357 + set_loop(n, loop); 79.358 + // When called from beautify_loops() idom is not constructed yet. 79.359 + if (_idom != NULL) { 79.360 + set_idom(n, pred, dom_depth(pred)); 79.361 + } 79.362 } 79.363 79.364 //------------------------------create_new_if_for_predicate------------------------ 79.365 @@ -1843,8 +1895,10 @@ 79.366 // 79.367 // We will create a region to guard the uct call if there is no one there. 79.368 // The true projecttion (if_cont) of the new_iff is returned. 79.369 -ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj) { 79.370 - assert(is_uncommon_trap_if_pattern(cont_proj, true), "must be a uct if pattern!"); 79.371 +// This code is also used to clone predicates to clonned loops. 79.372 +ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, 79.373 + Deoptimization::DeoptReason reason) { 79.374 + assert(is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!"); 79.375 IfNode* iff = cont_proj->in(0)->as_If(); 79.376 79.377 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); 79.378 @@ -1854,57 +1908,84 @@ 79.379 if (!rgn->is_Region()) { // create a region to guard the call 79.380 assert(rgn->is_Call(), "must be call uct"); 79.381 CallNode* call = rgn->as_Call(); 79.382 + IdealLoopTree* loop = get_loop(call); 79.383 rgn = new (C, 1) RegionNode(1); 79.384 - _igvn.set_type(rgn, rgn->bottom_type()); 79.385 rgn->add_req(uncommon_proj); 79.386 - set_idom(rgn, idom(uncommon_proj), dom_depth(uncommon_proj)+1); 79.387 + register_control(rgn, loop, uncommon_proj); 79.388 _igvn.hash_delete(call); 79.389 call->set_req(0, rgn); 79.390 + // When called from beautify_loops() idom is not constructed yet. 79.391 + if (_idom != NULL) { 79.392 + set_idom(call, rgn, dom_depth(rgn)); 79.393 + } 79.394 } 79.395 79.396 + Node* entry = iff->in(0); 79.397 + if (new_entry != NULL) { 79.398 + // Clonning the predicate to new location. 79.399 + entry = new_entry; 79.400 + } 79.401 // Create new_iff 79.402 - uint iffdd = dom_depth(iff); 79.403 - IdealLoopTree* lp = get_loop(iff); 79.404 - IfNode *new_iff = new (C, 2) IfNode(iff->in(0), NULL, iff->_prob, iff->_fcnt); 79.405 - register_node(new_iff, lp, idom(iff), iffdd); 79.406 + IdealLoopTree* lp = get_loop(entry); 79.407 + IfNode *new_iff = new (C, 2) IfNode(entry, NULL, iff->_prob, iff->_fcnt); 79.408 + register_control(new_iff, lp, entry); 79.409 Node *if_cont = new (C, 1) IfTrueNode(new_iff); 79.410 Node *if_uct = new (C, 1) IfFalseNode(new_iff); 79.411 if (cont_proj->is_IfFalse()) { 79.412 // Swap 79.413 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp; 79.414 } 79.415 - register_node(if_cont, lp, new_iff, iffdd); 79.416 - register_node(if_uct, get_loop(rgn), new_iff, iffdd); 79.417 - 79.418 - // if_cont to iff 79.419 - _igvn.hash_delete(iff); 79.420 - iff->set_req(0, if_cont); 79.421 - set_idom(iff, if_cont, dom_depth(iff)); 79.422 + register_control(if_cont, lp, new_iff); 79.423 + register_control(if_uct, get_loop(rgn), new_iff); 79.424 79.425 // if_uct to rgn 79.426 _igvn.hash_delete(rgn); 79.427 rgn->add_req(if_uct); 79.428 - Node* ridom = idom(rgn); 79.429 - Node* nrdom = dom_lca(ridom, new_iff); 79.430 - set_idom(rgn, nrdom, dom_depth(rgn)); 79.431 - 79.432 + // When called from beautify_loops() idom is not constructed yet. 79.433 + if (_idom != NULL) { 79.434 + Node* ridom = idom(rgn); 79.435 + Node* nrdom = dom_lca(ridom, new_iff); 79.436 + set_idom(rgn, nrdom, dom_depth(rgn)); 79.437 + } 79.438 // rgn must have no phis 79.439 assert(!rgn->as_Region()->has_phi(), "region must have no phis"); 79.440 79.441 + if (new_entry == NULL) { 79.442 + // Attach if_cont to iff 79.443 + _igvn.hash_delete(iff); 79.444 + iff->set_req(0, if_cont); 79.445 + if (_idom != NULL) { 79.446 + set_idom(iff, if_cont, dom_depth(iff)); 79.447 + } 79.448 + } 79.449 return if_cont->as_Proj(); 79.450 } 79.451 79.452 -//------------------------------find_predicate_insertion_point-------------------------- 79.453 +//--------------------------find_predicate_insertion_point------------------- 79.454 // Find a good location to insert a predicate 79.455 -ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c) { 79.456 - if (start_c == C->root() || !start_c->is_Proj()) 79.457 +ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) { 79.458 + if (start_c == NULL || !start_c->is_Proj()) 79.459 return NULL; 79.460 - if (is_uncommon_trap_if_pattern(start_c->as_Proj(), true/*Reason_Predicate*/)) { 79.461 + if (is_uncommon_trap_if_pattern(start_c->as_Proj(), reason)) { 79.462 return start_c->as_Proj(); 79.463 } 79.464 return NULL; 79.465 } 79.466 79.467 +//--------------------------find_predicate------------------------------------ 79.468 +// Find a predicate 79.469 +Node* PhaseIdealLoop::find_predicate(Node* entry) { 79.470 + Node* predicate = NULL; 79.471 + if (UseLoopPredicate) { 79.472 + predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); 79.473 + if (predicate != NULL) { // right pattern that can be used by loop predication 79.474 + assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be"); 79.475 + return entry; 79.476 + } 79.477 + } 79.478 + return NULL; 79.479 +} 79.480 + 79.481 //------------------------------Invariance----------------------------------- 79.482 // Helper class for loop_predication_impl to compute invariance on the fly and 79.483 // clone invariants. 79.484 @@ -2151,6 +2232,11 @@ 79.485 return false; 79.486 } 79.487 79.488 + if (loop->_head->unique_ctrl_out()->Opcode() == Op_NeverBranch) { 79.489 + // do nothing for infinite loops 79.490 + return false; 79.491 + } 79.492 + 79.493 CountedLoopNode *cl = NULL; 79.494 if (loop->_head->is_CountedLoop()) { 79.495 cl = loop->_head->as_CountedLoop(); 79.496 @@ -2158,40 +2244,22 @@ 79.497 if (!cl->is_normal_loop()) return false; 79.498 } 79.499 79.500 - // Too many traps seen? 79.501 - bool tmt = C->too_many_traps(C->method(), 0, Deoptimization::Reason_predicate); 79.502 - int tc = C->trap_count(Deoptimization::Reason_predicate); 79.503 - if (tmt || tc > 0) { 79.504 - if (TraceLoopPredicate) { 79.505 - tty->print_cr("too many predicate traps: %d", tc); 79.506 - C->method()->print(); // which method has too many predicate traps 79.507 - tty->print_cr(""); 79.508 - } 79.509 - return false; 79.510 - } 79.511 - 79.512 LoopNode *lpn = loop->_head->as_Loop(); 79.513 Node* entry = lpn->in(LoopNode::EntryControl); 79.514 79.515 - ProjNode *predicate_proj = find_predicate_insertion_point(entry); 79.516 - if (!predicate_proj){ 79.517 + ProjNode *predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); 79.518 + if (!predicate_proj) { 79.519 #ifndef PRODUCT 79.520 if (TraceLoopPredicate) { 79.521 tty->print("missing predicate:"); 79.522 loop->dump_head(); 79.523 + lpn->dump(1); 79.524 } 79.525 #endif 79.526 return false; 79.527 } 79.528 - 79.529 ConNode* zero = _igvn.intcon(0); 79.530 set_ctrl(zero, C->root()); 79.531 - Node *cond_false = new (C, 2) Conv2BNode(zero); 79.532 - register_new_node(cond_false, C->root()); 79.533 - ConNode* one = _igvn.intcon(1); 79.534 - set_ctrl(one, C->root()); 79.535 - Node *cond_true = new (C, 2) Conv2BNode(one); 79.536 - register_new_node(cond_true, C->root()); 79.537 79.538 ResourceArea *area = Thread::current()->resource_area(); 79.539 Invariance invar(area, loop); 79.540 @@ -2218,7 +2286,7 @@ 79.541 ProjNode* proj = if_proj_list.pop()->as_Proj(); 79.542 IfNode* iff = proj->in(0)->as_If(); 79.543 79.544 - if (!is_uncommon_trap_if_pattern(proj)) { 79.545 + if (!is_uncommon_trap_if_pattern(proj, Deoptimization::Reason_none)) { 79.546 if (loop->is_loop_exit(iff)) { 79.547 // stop processing the remaining projs in the list because the execution of them 79.548 // depends on the condition of "iff" (iff->in(1)). 79.549 @@ -2242,7 +2310,8 @@ 79.550 BoolNode* bol = test->as_Bool(); 79.551 if (invar.is_invariant(bol)) { 79.552 // Invariant test 79.553 - new_predicate_proj = create_new_if_for_predicate(predicate_proj); 79.554 + new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL, 79.555 + Deoptimization::Reason_predicate); 79.556 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0); 79.557 BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool(); 79.558 79.559 @@ -2256,8 +2325,15 @@ 79.560 IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If(); 79.561 _igvn.hash_delete(new_predicate_iff); 79.562 new_predicate_iff->set_req(1, new_predicate_bol); 79.563 - if (TraceLoopPredicate) tty->print_cr("invariant if%s: %d", negated ? " negated" : "", new_predicate_iff->_idx); 79.564 - 79.565 +#ifndef PRODUCT 79.566 + if (TraceLoopPredicate) { 79.567 + tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx); 79.568 + loop->dump_head(); 79.569 + } else if (TraceLoopOpts) { 79.570 + tty->print("Predicate IC "); 79.571 + loop->dump_head(); 79.572 + } 79.573 +#endif 79.574 } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) { 79.575 assert(proj->_con == predicate_proj->_con, "must match"); 79.576 79.577 @@ -2281,8 +2357,8 @@ 79.578 // lower_bound test will dominate the upper bound test and all 79.579 // cloned or created nodes will use the lower bound test as 79.580 // their declared control. 79.581 - ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj); 79.582 - ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj); 79.583 + ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate); 79.584 + ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate); 79.585 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); 79.586 Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0); 79.587 79.588 @@ -2311,41 +2387,24 @@ 79.589 // Fall through into rest of the clean up code which will move 79.590 // any dependent nodes onto the upper bound test. 79.591 new_predicate_proj = upper_bound_proj; 79.592 + 79.593 +#ifndef PRODUCT 79.594 + if (TraceLoopOpts && !TraceLoopPredicate) { 79.595 + tty->print("Predicate RC "); 79.596 + loop->dump_head(); 79.597 + } 79.598 +#endif 79.599 } else { 79.600 - // The other proj of the "iff" is a uncommon trap projection, and we can assume 79.601 - // the other proj will not be executed ("executed" means uct raised). 79.602 + // Loop variant check (for example, range check in non-counted loop) 79.603 + // with uncommon trap. 79.604 continue; 79.605 } 79.606 - 79.607 + assert(new_predicate_proj != NULL, "sanity"); 79.608 // Success - attach condition (new_predicate_bol) to predicate if 79.609 invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate 79.610 79.611 - // Eliminate the old if in the loop body 79.612 - _igvn.hash_delete(iff); 79.613 - iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true); 79.614 - 79.615 - Node* ctrl = new_predicate_proj; // new control 79.616 - ProjNode* dp = proj; // old control 79.617 - assert(get_loop(dp) == loop, "guaranteed at the time of collecting proj"); 79.618 - // Find nodes (depends only on the test) off the surviving projection; 79.619 - // move them outside the loop with the control of proj_clone 79.620 - for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { 79.621 - Node* cd = dp->fast_out(i); // Control-dependent node 79.622 - if (cd->depends_only_on_test()) { 79.623 - assert(cd->in(0) == dp, ""); 79.624 - _igvn.hash_delete(cd); 79.625 - cd->set_req(0, ctrl); // ctrl, not NULL 79.626 - set_early_ctrl(cd); 79.627 - _igvn._worklist.push(cd); 79.628 - IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); 79.629 - if (new_loop != loop) { 79.630 - if (!loop->_child) loop->_body.yank(cd); 79.631 - if (!new_loop->_child ) new_loop->_body.push(cd); 79.632 - } 79.633 - --i; 79.634 - --imax; 79.635 - } 79.636 - } 79.637 + // Eliminate the old If in the loop body 79.638 + dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con ); 79.639 79.640 hoisted = true; 79.641 C->set_major_progress();
80.1 --- a/src/share/vm/opto/loopUnswitch.cpp Fri Mar 25 17:26:33 2011 -0700 80.2 +++ b/src/share/vm/opto/loopUnswitch.cpp Fri Mar 25 18:04:45 2011 -0700 80.3 @@ -110,6 +110,13 @@ 80.4 IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop); 80.5 assert(unswitch_iff != NULL, "should be at least one"); 80.6 80.7 +#ifndef PRODUCT 80.8 + if (TraceLoopOpts) { 80.9 + tty->print("Unswitch %d ", head->unswitch_count()+1); 80.10 + loop->dump_head(); 80.11 + } 80.12 +#endif 80.13 + 80.14 // Need to revert back to normal loop 80.15 if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) { 80.16 head->as_CountedLoop()->set_normal_loop();
81.1 --- a/src/share/vm/opto/loopnode.cpp Fri Mar 25 17:26:33 2011 -0700 81.2 +++ b/src/share/vm/opto/loopnode.cpp Fri Mar 25 18:04:45 2011 -0700 81.3 @@ -56,12 +56,32 @@ 81.4 // Dump special per-node info 81.5 #ifndef PRODUCT 81.6 void LoopNode::dump_spec(outputStream *st) const { 81.7 - if( is_inner_loop () ) st->print( "inner " ); 81.8 - if( is_partial_peel_loop () ) st->print( "partial_peel " ); 81.9 - if( partial_peel_has_failed () ) st->print( "partial_peel_failed " ); 81.10 + if (is_inner_loop()) st->print( "inner " ); 81.11 + if (is_partial_peel_loop()) st->print( "partial_peel " ); 81.12 + if (partial_peel_has_failed()) st->print( "partial_peel_failed " ); 81.13 } 81.14 #endif 81.15 81.16 +//------------------------------is_valid_counted_loop------------------------- 81.17 +bool LoopNode::is_valid_counted_loop() const { 81.18 + if (is_CountedLoop()) { 81.19 + CountedLoopNode* l = as_CountedLoop(); 81.20 + CountedLoopEndNode* le = l->loopexit(); 81.21 + if (le != NULL && 81.22 + le->proj_out(1 /* true */) == l->in(LoopNode::LoopBackControl)) { 81.23 + Node* phi = l->phi(); 81.24 + Node* exit = le->proj_out(0 /* false */); 81.25 + if (exit != NULL && exit->Opcode() == Op_IfFalse && 81.26 + phi != NULL && phi->is_Phi() && 81.27 + phi->in(LoopNode::LoopBackControl) == l->incr() && 81.28 + le->loopnode() == l && le->stride_is_con()) { 81.29 + return true; 81.30 + } 81.31 + } 81.32 + } 81.33 + return false; 81.34 +} 81.35 + 81.36 //------------------------------get_early_ctrl--------------------------------- 81.37 // Compute earliest legal control 81.38 Node *PhaseIdealLoop::get_early_ctrl( Node *n ) { 81.39 @@ -142,43 +162,44 @@ 81.40 } 81.41 81.42 //------------------------------is_counted_loop-------------------------------- 81.43 -Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) { 81.44 +bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) { 81.45 PhaseGVN *gvn = &_igvn; 81.46 81.47 // Counted loop head must be a good RegionNode with only 3 not NULL 81.48 // control input edges: Self, Entry, LoopBack. 81.49 - if ( x->in(LoopNode::Self) == NULL || x->req() != 3 ) 81.50 - return NULL; 81.51 + if (x->in(LoopNode::Self) == NULL || x->req() != 3) 81.52 + return false; 81.53 81.54 Node *init_control = x->in(LoopNode::EntryControl); 81.55 Node *back_control = x->in(LoopNode::LoopBackControl); 81.56 - if( init_control == NULL || back_control == NULL ) // Partially dead 81.57 - return NULL; 81.58 + if (init_control == NULL || back_control == NULL) // Partially dead 81.59 + return false; 81.60 // Must also check for TOP when looking for a dead loop 81.61 - if( init_control->is_top() || back_control->is_top() ) 81.62 - return NULL; 81.63 + if (init_control->is_top() || back_control->is_top()) 81.64 + return false; 81.65 81.66 // Allow funny placement of Safepoint 81.67 - if( back_control->Opcode() == Op_SafePoint ) 81.68 + if (back_control->Opcode() == Op_SafePoint) 81.69 back_control = back_control->in(TypeFunc::Control); 81.70 81.71 // Controlling test for loop 81.72 Node *iftrue = back_control; 81.73 uint iftrue_op = iftrue->Opcode(); 81.74 - if( iftrue_op != Op_IfTrue && 81.75 - iftrue_op != Op_IfFalse ) 81.76 + if (iftrue_op != Op_IfTrue && 81.77 + iftrue_op != Op_IfFalse) 81.78 // I have a weird back-control. Probably the loop-exit test is in 81.79 // the middle of the loop and I am looking at some trailing control-flow 81.80 // merge point. To fix this I would have to partially peel the loop. 81.81 - return NULL; // Obscure back-control 81.82 + return false; // Obscure back-control 81.83 81.84 // Get boolean guarding loop-back test 81.85 Node *iff = iftrue->in(0); 81.86 - if( get_loop(iff) != loop || !iff->in(1)->is_Bool() ) return NULL; 81.87 + if (get_loop(iff) != loop || !iff->in(1)->is_Bool()) 81.88 + return false; 81.89 BoolNode *test = iff->in(1)->as_Bool(); 81.90 BoolTest::mask bt = test->_test._test; 81.91 float cl_prob = iff->as_If()->_prob; 81.92 - if( iftrue_op == Op_IfFalse ) { 81.93 + if (iftrue_op == Op_IfFalse) { 81.94 bt = BoolTest(bt).negate(); 81.95 cl_prob = 1.0 - cl_prob; 81.96 } 81.97 @@ -186,7 +207,7 @@ 81.98 Node *cmp = test->in(1); 81.99 int cmp_op = cmp->Opcode(); 81.100 if( cmp_op != Op_CmpI ) 81.101 - return NULL; // Avoid pointer & float compares 81.102 + return false; // Avoid pointer & float compares 81.103 81.104 // Find the trip-counter increment & limit. Limit must be loop invariant. 81.105 Node *incr = cmp->in(1); 81.106 @@ -196,55 +217,64 @@ 81.107 // need 'loop()' test to tell if limit is loop invariant 81.108 // --------- 81.109 81.110 - if( !is_member( loop, get_ctrl(incr) ) ) { // Swapped trip counter and limit? 81.111 - Node *tmp = incr; // Then reverse order into the CmpI 81.112 + if (!is_member(loop, get_ctrl(incr))) { // Swapped trip counter and limit? 81.113 + Node *tmp = incr; // Then reverse order into the CmpI 81.114 incr = limit; 81.115 limit = tmp; 81.116 bt = BoolTest(bt).commute(); // And commute the exit test 81.117 } 81.118 - if( is_member( loop, get_ctrl(limit) ) ) // Limit must loop-invariant 81.119 - return NULL; 81.120 + if (is_member(loop, get_ctrl(limit))) // Limit must be loop-invariant 81.121 + return false; 81.122 + if (!is_member(loop, get_ctrl(incr))) // Trip counter must be loop-variant 81.123 + return false; 81.124 81.125 + Node* phi_incr = NULL; 81.126 // Trip-counter increment must be commutative & associative. 81.127 - uint incr_op = incr->Opcode(); 81.128 - if( incr_op == Op_Phi && incr->req() == 3 ) { 81.129 - incr = incr->in(2); // Assume incr is on backedge of Phi 81.130 - incr_op = incr->Opcode(); 81.131 + if (incr->is_Phi()) { 81.132 + if (incr->as_Phi()->region() != x || incr->req() != 3) 81.133 + return false; // Not simple trip counter expression 81.134 + phi_incr = incr; 81.135 + incr = phi_incr->in(LoopNode::LoopBackControl); // Assume incr is on backedge of Phi 81.136 + if (!is_member(loop, get_ctrl(incr))) // Trip counter must be loop-variant 81.137 + return false; 81.138 } 81.139 + 81.140 Node* trunc1 = NULL; 81.141 Node* trunc2 = NULL; 81.142 const TypeInt* iv_trunc_t = NULL; 81.143 if (!(incr = CountedLoopNode::match_incr_with_optional_truncation(incr, &trunc1, &trunc2, &iv_trunc_t))) { 81.144 - return NULL; // Funny increment opcode 81.145 + return false; // Funny increment opcode 81.146 } 81.147 + assert(incr->Opcode() == Op_AddI, "wrong increment code"); 81.148 81.149 // Get merge point 81.150 Node *xphi = incr->in(1); 81.151 Node *stride = incr->in(2); 81.152 - if( !stride->is_Con() ) { // Oops, swap these 81.153 - if( !xphi->is_Con() ) // Is the other guy a constant? 81.154 - return NULL; // Nope, unknown stride, bail out 81.155 + if (!stride->is_Con()) { // Oops, swap these 81.156 + if (!xphi->is_Con()) // Is the other guy a constant? 81.157 + return false; // Nope, unknown stride, bail out 81.158 Node *tmp = xphi; // 'incr' is commutative, so ok to swap 81.159 xphi = stride; 81.160 stride = tmp; 81.161 } 81.162 - //if( loop(xphi) != l) return NULL;// Merge point is in inner loop?? 81.163 - if( !xphi->is_Phi() ) return NULL; // Too much math on the trip counter 81.164 + // Stride must be constant 81.165 + int stride_con = stride->get_int(); 81.166 + assert(stride_con != 0, "missed some peephole opt"); 81.167 + 81.168 + if (!xphi->is_Phi()) 81.169 + return false; // Too much math on the trip counter 81.170 + if (phi_incr != NULL && phi_incr != xphi) 81.171 + return false; 81.172 PhiNode *phi = xphi->as_Phi(); 81.173 81.174 - // Stride must be constant 81.175 - const Type *stride_t = stride->bottom_type(); 81.176 - int stride_con = stride_t->is_int()->get_con(); 81.177 - assert( stride_con, "missed some peephole opt" ); 81.178 - 81.179 // Phi must be of loop header; backedge must wrap to increment 81.180 - if( phi->region() != x ) return NULL; 81.181 - if( trunc1 == NULL && phi->in(LoopNode::LoopBackControl) != incr || 81.182 - trunc1 != NULL && phi->in(LoopNode::LoopBackControl) != trunc1 ) { 81.183 - return NULL; 81.184 + if (phi->region() != x) 81.185 + return false; 81.186 + if (trunc1 == NULL && phi->in(LoopNode::LoopBackControl) != incr || 81.187 + trunc1 != NULL && phi->in(LoopNode::LoopBackControl) != trunc1) { 81.188 + return false; 81.189 } 81.190 Node *init_trip = phi->in(LoopNode::EntryControl); 81.191 - //if (!init_trip->is_Con()) return NULL; // avoid rolling over MAXINT/MININT 81.192 81.193 // If iv trunc type is smaller than int, check for possible wrap. 81.194 if (!TypeInt::INT->higher_equal(iv_trunc_t)) { 81.195 @@ -267,12 +297,12 @@ 81.196 if (stride_con > 0) { 81.197 if (iv_trunc_t->_hi - phi_ft->_hi < stride_con || 81.198 iv_trunc_t->_lo > phi_ft->_lo) { 81.199 - return NULL; // truncation may occur 81.200 + return false; // truncation may occur 81.201 } 81.202 } else if (stride_con < 0) { 81.203 if (iv_trunc_t->_lo - phi_ft->_lo > stride_con || 81.204 iv_trunc_t->_hi < phi_ft->_hi) { 81.205 - return NULL; // truncation may occur 81.206 + return false; // truncation may occur 81.207 } 81.208 } 81.209 // No possibility of wrap so truncation can be discarded 81.210 @@ -281,35 +311,45 @@ 81.211 assert(trunc1 == NULL && trunc2 == NULL, "no truncation for int"); 81.212 } 81.213 81.214 + // If the condition is inverted and we will be rolling 81.215 + // through MININT to MAXINT, then bail out. 81.216 + if (bt == BoolTest::eq || // Bail out, but this loop trips at most twice! 81.217 + // Odd stride 81.218 + bt == BoolTest::ne && stride_con != 1 && stride_con != -1 || 81.219 + // Count down loop rolls through MAXINT 81.220 + (bt == BoolTest::le || bt == BoolTest::lt) && stride_con < 0 || 81.221 + // Count up loop rolls through MININT 81.222 + (bt == BoolTest::ge || bt == BoolTest::gt) && stride_con > 0 ) { 81.223 + return false; // Bail out 81.224 + } 81.225 + 81.226 + const TypeInt* init_t = gvn->type(init_trip)->is_int(); 81.227 + const TypeInt* limit_t = gvn->type(limit)->is_int(); 81.228 + 81.229 + if (stride_con > 0) { 81.230 + long init_p = (long)init_t->_lo + stride_con; 81.231 + if (init_p > (long)max_jint || init_p > (long)limit_t->_hi) 81.232 + return false; // cyclic loop or this loop trips only once 81.233 + } else { 81.234 + long init_p = (long)init_t->_hi + stride_con; 81.235 + if (init_p < (long)min_jint || init_p < (long)limit_t->_lo) 81.236 + return false; // cyclic loop or this loop trips only once 81.237 + } 81.238 + 81.239 // ================================================= 81.240 // ---- SUCCESS! Found A Trip-Counted Loop! ----- 81.241 // 81.242 - // Canonicalize the condition on the test. If we can exactly determine 81.243 - // the trip-counter exit value, then set limit to that value and use 81.244 - // a '!=' test. Otherwise use condition '<' for count-up loops and 81.245 - // '>' for count-down loops. If the condition is inverted and we will 81.246 - // be rolling through MININT to MAXINT, then bail out. 81.247 - 81.248 + assert(x->Opcode() == Op_Loop, "regular loops only"); 81.249 C->print_method("Before CountedLoop", 3); 81.250 81.251 - // Check for SafePoint on backedge and remove 81.252 - Node *sfpt = x->in(LoopNode::LoopBackControl); 81.253 - if( sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) { 81.254 - lazy_replace( sfpt, iftrue ); 81.255 - loop->_tail = iftrue; 81.256 - } 81.257 - 81.258 - 81.259 // If compare points to incr, we are ok. Otherwise the compare 81.260 // can directly point to the phi; in this case adjust the compare so that 81.261 // it points to the incr by adjusting the limit. 81.262 - if( cmp->in(1) == phi || cmp->in(2) == phi ) 81.263 + if (cmp->in(1) == phi || cmp->in(2) == phi) 81.264 limit = gvn->transform(new (C, 3) AddINode(limit,stride)); 81.265 81.266 // trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride. 81.267 // Final value for iterator should be: trip_count * stride + init_trip. 81.268 - const Type *limit_t = limit->bottom_type(); 81.269 - const Type *init_t = init_trip->bottom_type(); 81.270 Node *one_p = gvn->intcon( 1); 81.271 Node *one_m = gvn->intcon(-1); 81.272 81.273 @@ -317,15 +357,15 @@ 81.274 Node *hook = new (C, 6) Node(6); 81.275 switch( bt ) { 81.276 case BoolTest::eq: 81.277 - return NULL; // Bail out, but this loop trips at most twice! 81.278 + ShouldNotReachHere(); 81.279 case BoolTest::ne: // Ahh, the case we desire 81.280 - if( stride_con == 1 ) 81.281 + if (stride_con == 1) 81.282 trip_count = gvn->transform(new (C, 3) SubINode(limit,init_trip)); 81.283 - else if( stride_con == -1 ) 81.284 + else if (stride_con == -1) 81.285 trip_count = gvn->transform(new (C, 3) SubINode(init_trip,limit)); 81.286 else 81.287 - return NULL; // Odd stride; must prove we hit limit exactly 81.288 - set_subtree_ctrl( trip_count ); 81.289 + ShouldNotReachHere(); 81.290 + set_subtree_ctrl(trip_count); 81.291 //_loop.map(trip_count->_idx,loop(limit)); 81.292 break; 81.293 case BoolTest::le: // Maybe convert to '<' case 81.294 @@ -338,7 +378,8 @@ 81.295 //_loop.map(limit->_idx,limit_loop); 81.296 // Fall into next case 81.297 case BoolTest::lt: { // Maybe convert to '!=' case 81.298 - if( stride_con < 0 ) return NULL; // Count down loop rolls through MAXINT 81.299 + if (stride_con < 0) // Count down loop rolls through MAXINT 81.300 + ShouldNotReachHere(); 81.301 Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip)); 81.302 set_subtree_ctrl( range ); 81.303 hook->init_req(0, range); 81.304 @@ -367,7 +408,8 @@ 81.305 //_loop.map(limit->_idx,limit_loop); 81.306 // Fall into next case 81.307 case BoolTest::gt: { // Maybe convert to '!=' case 81.308 - if( stride_con > 0 ) return NULL; // count up loop rolls through MININT 81.309 + if (stride_con > 0) // count up loop rolls through MININT 81.310 + ShouldNotReachHere(); 81.311 Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip)); 81.312 set_subtree_ctrl( range ); 81.313 hook->init_req(0, range); 81.314 @@ -385,7 +427,7 @@ 81.315 hook->init_req(3, trip_count); 81.316 break; 81.317 } 81.318 - } 81.319 + } // switch( bt ) 81.320 81.321 Node *span = gvn->transform(new (C, 3) MulINode(trip_count,stride)); 81.322 set_subtree_ctrl( span ); 81.323 @@ -394,83 +436,82 @@ 81.324 limit = gvn->transform(new (C, 3) AddINode(span,init_trip)); 81.325 set_subtree_ctrl( limit ); 81.326 81.327 + // Check for SafePoint on backedge and remove 81.328 + Node *sfpt = x->in(LoopNode::LoopBackControl); 81.329 + if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) { 81.330 + lazy_replace( sfpt, iftrue ); 81.331 + loop->_tail = iftrue; 81.332 + } 81.333 + 81.334 // Build a canonical trip test. 81.335 // Clone code, as old values may be in use. 81.336 + Node* nphi = PhiNode::make(x, init_trip, TypeInt::INT); 81.337 + nphi = _igvn.register_new_node_with_optimizer(nphi); 81.338 + set_ctrl(nphi, get_ctrl(phi)); 81.339 + 81.340 incr = incr->clone(); 81.341 - incr->set_req(1,phi); 81.342 + incr->set_req(1,nphi); 81.343 incr->set_req(2,stride); 81.344 incr = _igvn.register_new_node_with_optimizer(incr); 81.345 set_early_ctrl( incr ); 81.346 - _igvn.hash_delete(phi); 81.347 - phi->set_req_X( LoopNode::LoopBackControl, incr, &_igvn ); 81.348 81.349 - // If phi type is more restrictive than Int, raise to 81.350 - // Int to prevent (almost) infinite recursion in igvn 81.351 - // which can only handle integer types for constants or minint..maxint. 81.352 - if (!TypeInt::INT->higher_equal(phi->bottom_type())) { 81.353 - Node* nphi = PhiNode::make(phi->in(0), phi->in(LoopNode::EntryControl), TypeInt::INT); 81.354 - nphi->set_req(LoopNode::LoopBackControl, phi->in(LoopNode::LoopBackControl)); 81.355 - nphi = _igvn.register_new_node_with_optimizer(nphi); 81.356 - set_ctrl(nphi, get_ctrl(phi)); 81.357 - _igvn.replace_node(phi, nphi); 81.358 - phi = nphi->as_Phi(); 81.359 - } 81.360 + nphi->set_req(LoopNode::LoopBackControl, incr); 81.361 + _igvn.replace_node(phi, nphi); 81.362 + phi = nphi->as_Phi(); 81.363 + 81.364 cmp = cmp->clone(); 81.365 cmp->set_req(1,incr); 81.366 cmp->set_req(2,limit); 81.367 cmp = _igvn.register_new_node_with_optimizer(cmp); 81.368 set_ctrl(cmp, iff->in(0)); 81.369 81.370 - Node *tmp = test->clone(); 81.371 - assert( tmp->is_Bool(), "" ); 81.372 - test = (BoolNode*)tmp; 81.373 - (*(BoolTest*)&test->_test)._test = bt; //BoolTest::ne; 81.374 + test = test->clone()->as_Bool(); 81.375 + (*(BoolTest*)&test->_test)._test = bt; 81.376 test->set_req(1,cmp); 81.377 _igvn.register_new_node_with_optimizer(test); 81.378 set_ctrl(test, iff->in(0)); 81.379 - // If the exit test is dead, STOP! 81.380 - if( test == NULL ) return NULL; 81.381 - _igvn.hash_delete(iff); 81.382 - iff->set_req_X( 1, test, &_igvn ); 81.383 81.384 // Replace the old IfNode with a new LoopEndNode 81.385 - Node *lex = _igvn.register_new_node_with_optimizer(new (C, 2) CountedLoopEndNode( iff->in(0), iff->in(1), cl_prob, iff->as_If()->_fcnt )); 81.386 + Node *lex = _igvn.register_new_node_with_optimizer(new (C, 2) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt )); 81.387 IfNode *le = lex->as_If(); 81.388 uint dd = dom_depth(iff); 81.389 set_idom(le, le->in(0), dd); // Update dominance for loop exit 81.390 set_loop(le, loop); 81.391 81.392 // Get the loop-exit control 81.393 - Node *if_f = iff->as_If()->proj_out(!(iftrue_op == Op_IfTrue)); 81.394 + Node *iffalse = iff->as_If()->proj_out(!(iftrue_op == Op_IfTrue)); 81.395 81.396 // Need to swap loop-exit and loop-back control? 81.397 - if( iftrue_op == Op_IfFalse ) { 81.398 + if (iftrue_op == Op_IfFalse) { 81.399 Node *ift2=_igvn.register_new_node_with_optimizer(new (C, 1) IfTrueNode (le)); 81.400 Node *iff2=_igvn.register_new_node_with_optimizer(new (C, 1) IfFalseNode(le)); 81.401 81.402 loop->_tail = back_control = ift2; 81.403 set_loop(ift2, loop); 81.404 - set_loop(iff2, get_loop(if_f)); 81.405 + set_loop(iff2, get_loop(iffalse)); 81.406 81.407 // Lazy update of 'get_ctrl' mechanism. 81.408 - lazy_replace_proj( if_f , iff2 ); 81.409 - lazy_replace_proj( iftrue, ift2 ); 81.410 + lazy_replace_proj( iffalse, iff2 ); 81.411 + lazy_replace_proj( iftrue, ift2 ); 81.412 81.413 // Swap names 81.414 - if_f = iff2; 81.415 - iftrue = ift2; 81.416 + iffalse = iff2; 81.417 + iftrue = ift2; 81.418 } else { 81.419 - _igvn.hash_delete(if_f ); 81.420 + _igvn.hash_delete(iffalse); 81.421 _igvn.hash_delete(iftrue); 81.422 - if_f ->set_req_X( 0, le, &_igvn ); 81.423 - iftrue->set_req_X( 0, le, &_igvn ); 81.424 + iffalse->set_req_X( 0, le, &_igvn ); 81.425 + iftrue ->set_req_X( 0, le, &_igvn ); 81.426 } 81.427 81.428 - set_idom(iftrue, le, dd+1); 81.429 - set_idom(if_f, le, dd+1); 81.430 + set_idom(iftrue, le, dd+1); 81.431 + set_idom(iffalse, le, dd+1); 81.432 + assert(iff->outcnt() == 0, "should be dead now"); 81.433 + lazy_replace( iff, le ); // fix 'get_ctrl' 81.434 81.435 // Now setup a new CountedLoopNode to replace the existing LoopNode 81.436 CountedLoopNode *l = new (C, 3) CountedLoopNode(init_control, back_control); 81.437 + l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve 81.438 // The following assert is approximately true, and defines the intention 81.439 // of can_be_counted_loop. It fails, however, because phase->type 81.440 // is not yet initialized for this loop and its parts. 81.441 @@ -491,10 +532,14 @@ 81.442 // Free up intermediate goo 81.443 _igvn.remove_dead_node(hook); 81.444 81.445 +#ifdef ASSERT 81.446 + assert(l->is_valid_counted_loop(), "counted loop shape is messed up"); 81.447 + assert(l == loop->_head && l->phi() == phi && l->loopexit() == lex, "" ); 81.448 +#endif 81.449 + 81.450 C->print_method("After CountedLoop", 3); 81.451 81.452 - // Return trip counter 81.453 - return trip_count; 81.454 + return true; 81.455 } 81.456 81.457 81.458 @@ -1256,17 +1301,98 @@ 81.459 return true; 81.460 } 81.461 81.462 +//---------------------------replace_parallel_iv------------------------------- 81.463 +// Replace parallel induction variable (parallel to trip counter) 81.464 +void PhaseIdealLoop::replace_parallel_iv(IdealLoopTree *loop) { 81.465 + assert(loop->_head->is_CountedLoop(), ""); 81.466 + CountedLoopNode *cl = loop->_head->as_CountedLoop(); 81.467 + Node *incr = cl->incr(); 81.468 + if (incr == NULL) 81.469 + return; // Dead loop? 81.470 + Node *init = cl->init_trip(); 81.471 + Node *phi = cl->phi(); 81.472 + // protect against stride not being a constant 81.473 + if (!cl->stride_is_con()) 81.474 + return; 81.475 + int stride_con = cl->stride_con(); 81.476 + 81.477 + PhaseGVN *gvn = &_igvn; 81.478 + 81.479 + // Visit all children, looking for Phis 81.480 + for (DUIterator i = cl->outs(); cl->has_out(i); i++) { 81.481 + Node *out = cl->out(i); 81.482 + // Look for other phis (secondary IVs). Skip dead ones 81.483 + if (!out->is_Phi() || out == phi || !has_node(out)) 81.484 + continue; 81.485 + PhiNode* phi2 = out->as_Phi(); 81.486 + Node *incr2 = phi2->in( LoopNode::LoopBackControl ); 81.487 + // Look for induction variables of the form: X += constant 81.488 + if (phi2->region() != loop->_head || 81.489 + incr2->req() != 3 || 81.490 + incr2->in(1) != phi2 || 81.491 + incr2 == incr || 81.492 + incr2->Opcode() != Op_AddI || 81.493 + !incr2->in(2)->is_Con()) 81.494 + continue; 81.495 + 81.496 + // Check for parallel induction variable (parallel to trip counter) 81.497 + // via an affine function. In particular, count-down loops with 81.498 + // count-up array indices are common. We only RCE references off 81.499 + // the trip-counter, so we need to convert all these to trip-counter 81.500 + // expressions. 81.501 + Node *init2 = phi2->in( LoopNode::EntryControl ); 81.502 + int stride_con2 = incr2->in(2)->get_int(); 81.503 + 81.504 + // The general case here gets a little tricky. We want to find the 81.505 + // GCD of all possible parallel IV's and make a new IV using this 81.506 + // GCD for the loop. Then all possible IVs are simple multiples of 81.507 + // the GCD. In practice, this will cover very few extra loops. 81.508 + // Instead we require 'stride_con2' to be a multiple of 'stride_con', 81.509 + // where +/-1 is the common case, but other integer multiples are 81.510 + // also easy to handle. 81.511 + int ratio_con = stride_con2/stride_con; 81.512 + 81.513 + if ((ratio_con * stride_con) == stride_con2) { // Check for exact 81.514 + // Convert to using the trip counter. The parallel induction 81.515 + // variable differs from the trip counter by a loop-invariant 81.516 + // amount, the difference between their respective initial values. 81.517 + // It is scaled by the 'ratio_con'. 81.518 + // Perform local Ideal transformation since in most cases ratio == 1. 81.519 + Node* ratio = _igvn.intcon(ratio_con); 81.520 + set_ctrl(ratio, C->root()); 81.521 + Node* hook = new (C, 3) Node(3); 81.522 + Node* ratio_init = gvn->transform(new (C, 3) MulINode(init, ratio)); 81.523 + hook->init_req(0, ratio_init); 81.524 + Node* diff = gvn->transform(new (C, 3) SubINode(init2, ratio_init)); 81.525 + hook->init_req(1, diff); 81.526 + Node* ratio_idx = gvn->transform(new (C, 3) MulINode(phi, ratio)); 81.527 + hook->init_req(2, ratio_idx); 81.528 + Node* add = gvn->transform(new (C, 3) AddINode(ratio_idx, diff)); 81.529 + set_subtree_ctrl(add); 81.530 + _igvn.replace_node( phi2, add ); 81.531 + // Free up intermediate goo 81.532 + _igvn.remove_dead_node(hook); 81.533 + // Sometimes an induction variable is unused 81.534 + if (add->outcnt() == 0) { 81.535 + _igvn.remove_dead_node(add); 81.536 + } 81.537 + --i; // deleted this phi; rescan starting with next position 81.538 + continue; 81.539 + } 81.540 + } 81.541 +} 81.542 + 81.543 //------------------------------counted_loop----------------------------------- 81.544 // Convert to counted loops where possible 81.545 void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) { 81.546 81.547 // For grins, set the inner-loop flag here 81.548 - if( !_child ) { 81.549 - if( _head->is_Loop() ) _head->as_Loop()->set_inner_loop(); 81.550 + if (!_child) { 81.551 + if (_head->is_Loop()) _head->as_Loop()->set_inner_loop(); 81.552 } 81.553 81.554 - if( _head->is_CountedLoop() || 81.555 - phase->is_counted_loop( _head, this ) ) { 81.556 + if (_head->is_CountedLoop() || 81.557 + phase->is_counted_loop(_head, this)) { 81.558 _has_sfpt = 1; // Indicate we do not need a safepoint here 81.559 81.560 // Look for a safepoint to remove 81.561 @@ -1275,79 +1401,9 @@ 81.562 phase->is_deleteable_safept(n)) 81.563 phase->lazy_replace(n,n->in(TypeFunc::Control)); 81.564 81.565 - CountedLoopNode *cl = _head->as_CountedLoop(); 81.566 - Node *incr = cl->incr(); 81.567 - if( !incr ) return; // Dead loop? 81.568 - Node *init = cl->init_trip(); 81.569 - Node *phi = cl->phi(); 81.570 - // protect against stride not being a constant 81.571 - if( !cl->stride_is_con() ) return; 81.572 - int stride_con = cl->stride_con(); 81.573 + // Look for induction variables 81.574 + phase->replace_parallel_iv(this); 81.575 81.576 - // Look for induction variables 81.577 - 81.578 - // Visit all children, looking for Phis 81.579 - for (DUIterator i = cl->outs(); cl->has_out(i); i++) { 81.580 - Node *out = cl->out(i); 81.581 - // Look for other phis (secondary IVs). Skip dead ones 81.582 - if (!out->is_Phi() || out == phi || !phase->has_node(out)) continue; 81.583 - PhiNode* phi2 = out->as_Phi(); 81.584 - Node *incr2 = phi2->in( LoopNode::LoopBackControl ); 81.585 - // Look for induction variables of the form: X += constant 81.586 - if( phi2->region() != _head || 81.587 - incr2->req() != 3 || 81.588 - incr2->in(1) != phi2 || 81.589 - incr2 == incr || 81.590 - incr2->Opcode() != Op_AddI || 81.591 - !incr2->in(2)->is_Con() ) 81.592 - continue; 81.593 - 81.594 - // Check for parallel induction variable (parallel to trip counter) 81.595 - // via an affine function. In particular, count-down loops with 81.596 - // count-up array indices are common. We only RCE references off 81.597 - // the trip-counter, so we need to convert all these to trip-counter 81.598 - // expressions. 81.599 - Node *init2 = phi2->in( LoopNode::EntryControl ); 81.600 - int stride_con2 = incr2->in(2)->get_int(); 81.601 - 81.602 - // The general case here gets a little tricky. We want to find the 81.603 - // GCD of all possible parallel IV's and make a new IV using this 81.604 - // GCD for the loop. Then all possible IVs are simple multiples of 81.605 - // the GCD. In practice, this will cover very few extra loops. 81.606 - // Instead we require 'stride_con2' to be a multiple of 'stride_con', 81.607 - // where +/-1 is the common case, but other integer multiples are 81.608 - // also easy to handle. 81.609 - int ratio_con = stride_con2/stride_con; 81.610 - 81.611 - if( ratio_con * stride_con == stride_con2 ) { // Check for exact 81.612 - // Convert to using the trip counter. The parallel induction 81.613 - // variable differs from the trip counter by a loop-invariant 81.614 - // amount, the difference between their respective initial values. 81.615 - // It is scaled by the 'ratio_con'. 81.616 - Compile* C = phase->C; 81.617 - Node* ratio = phase->_igvn.intcon(ratio_con); 81.618 - phase->set_ctrl(ratio, C->root()); 81.619 - Node* ratio_init = new (C, 3) MulINode(init, ratio); 81.620 - phase->_igvn.register_new_node_with_optimizer(ratio_init, init); 81.621 - phase->set_early_ctrl(ratio_init); 81.622 - Node* diff = new (C, 3) SubINode(init2, ratio_init); 81.623 - phase->_igvn.register_new_node_with_optimizer(diff, init2); 81.624 - phase->set_early_ctrl(diff); 81.625 - Node* ratio_idx = new (C, 3) MulINode(phi, ratio); 81.626 - phase->_igvn.register_new_node_with_optimizer(ratio_idx, phi); 81.627 - phase->set_ctrl(ratio_idx, cl); 81.628 - Node* add = new (C, 3) AddINode(ratio_idx, diff); 81.629 - phase->_igvn.register_new_node_with_optimizer(add); 81.630 - phase->set_ctrl(add, cl); 81.631 - phase->_igvn.replace_node( phi2, add ); 81.632 - // Sometimes an induction variable is unused 81.633 - if (add->outcnt() == 0) { 81.634 - phase->_igvn.remove_dead_node(add); 81.635 - } 81.636 - --i; // deleted this phi; rescan starting with next position 81.637 - continue; 81.638 - } 81.639 - } 81.640 } else if (_parent != NULL && !_irreducible) { 81.641 // Not a counted loop. 81.642 // Look for a safepoint on the idom-path to remove, preserving the first one 81.643 @@ -1366,24 +1422,31 @@ 81.644 } 81.645 81.646 // Recursively 81.647 - if( _child ) _child->counted_loop( phase ); 81.648 - if( _next ) _next ->counted_loop( phase ); 81.649 + if (_child) _child->counted_loop( phase ); 81.650 + if (_next) _next ->counted_loop( phase ); 81.651 } 81.652 81.653 #ifndef PRODUCT 81.654 //------------------------------dump_head-------------------------------------- 81.655 // Dump 1 liner for loop header info 81.656 void IdealLoopTree::dump_head( ) const { 81.657 - for( uint i=0; i<_nest; i++ ) 81.658 + for (uint i=0; i<_nest; i++) 81.659 tty->print(" "); 81.660 tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx); 81.661 - if( _irreducible ) tty->print(" IRREDUCIBLE"); 81.662 - if( _head->is_CountedLoop() ) { 81.663 + if (_irreducible) tty->print(" IRREDUCIBLE"); 81.664 + if (UseLoopPredicate) { 81.665 + Node* entry = _head->in(LoopNode::EntryControl); 81.666 + if (entry != NULL && entry->is_Proj() && 81.667 + PhaseIdealLoop::is_uncommon_trap_if_pattern(entry->as_Proj(), Deoptimization::Reason_predicate)) { 81.668 + tty->print(" predicated"); 81.669 + } 81.670 + } 81.671 + if (_head->is_CountedLoop()) { 81.672 CountedLoopNode *cl = _head->as_CountedLoop(); 81.673 tty->print(" counted"); 81.674 - if( cl->is_pre_loop () ) tty->print(" pre" ); 81.675 - if( cl->is_main_loop() ) tty->print(" main"); 81.676 - if( cl->is_post_loop() ) tty->print(" post"); 81.677 + if (cl->is_pre_loop ()) tty->print(" pre" ); 81.678 + if (cl->is_main_loop()) tty->print(" main"); 81.679 + if (cl->is_post_loop()) tty->print(" post"); 81.680 } 81.681 tty->cr(); 81.682 } 81.683 @@ -1392,8 +1455,8 @@ 81.684 // Dump loops by loop tree 81.685 void IdealLoopTree::dump( ) const { 81.686 dump_head(); 81.687 - if( _child ) _child->dump(); 81.688 - if( _next ) _next ->dump(); 81.689 + if (_child) _child->dump(); 81.690 + if (_next) _next ->dump(); 81.691 } 81.692 81.693 #endif 81.694 @@ -1439,19 +1502,19 @@ 81.695 } 81.696 81.697 // self (only loops that we can apply loop predication may use their predicates) 81.698 - if (loop->_head->is_Loop() && 81.699 - !loop->_irreducible && 81.700 + if (loop->_head->is_Loop() && 81.701 + !loop->_irreducible && 81.702 !loop->tail()->is_top()) { 81.703 - LoopNode *lpn = loop->_head->as_Loop(); 81.704 + LoopNode* lpn = loop->_head->as_Loop(); 81.705 Node* entry = lpn->in(LoopNode::EntryControl); 81.706 - ProjNode *predicate_proj = find_predicate_insertion_point(entry); 81.707 + Node* predicate_proj = find_predicate(entry); 81.708 if (predicate_proj != NULL ) { // right pattern that can be used by loop predication 81.709 - assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be"); 81.710 + assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be"); 81.711 useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one 81.712 } 81.713 } 81.714 81.715 - if ( loop->_next ) { // sibling 81.716 + if (loop->_next) { // sibling 81.717 collect_potentially_useful_predicates(loop->_next, useful_predicates); 81.718 } 81.719 } 81.720 @@ -1459,7 +1522,8 @@ 81.721 //------------------------eliminate_useless_predicates----------------------------- 81.722 // Eliminate all inserted predicates if they could not be used by loop predication. 81.723 void PhaseIdealLoop::eliminate_useless_predicates() { 81.724 - if (C->predicate_count() == 0) return; // no predicate left 81.725 + if (C->predicate_count() == 0) 81.726 + return; // no predicate left 81.727 81.728 Unique_Node_List useful_predicates; // to store useful predicates 81.729 if (C->has_loops()) { 81.730 @@ -1647,12 +1711,15 @@ 81.731 81.732 #ifndef PRODUCT 81.733 C->verify_graph_edges(); 81.734 - if( _verify_me ) { // Nested verify pass? 81.735 + if (_verify_me) { // Nested verify pass? 81.736 // Check to see if the verify mode is broken 81.737 assert(C->unique() == unique, "non-optimize mode made Nodes? ? ?"); 81.738 return; 81.739 } 81.740 - if( VerifyLoopOptimizations ) verify(); 81.741 + if(VerifyLoopOptimizations) verify(); 81.742 + if(TraceLoopOpts && C->has_loops()) { 81.743 + _ltree_root->dump(); 81.744 + } 81.745 #endif 81.746 81.747 if (ReassociateInvariants) {
82.1 --- a/src/share/vm/opto/loopnode.hpp Fri Mar 25 17:26:33 2011 -0700 82.2 +++ b/src/share/vm/opto/loopnode.hpp Fri Mar 25 18:04:45 2011 -0700 82.3 @@ -93,6 +93,7 @@ 82.4 in(1) != NULL && phase->type(in(1)) != Type::TOP && 82.5 in(2) != NULL && phase->type(in(2)) != Type::TOP; 82.6 } 82.7 + bool is_valid_counted_loop() const; 82.8 #ifndef PRODUCT 82.9 virtual void dump_spec(outputStream *st) const; 82.10 #endif 82.11 @@ -101,9 +102,8 @@ 82.12 //------------------------------Counted Loops---------------------------------- 82.13 // Counted loops are all trip-counted loops, with exactly 1 trip-counter exit 82.14 // path (and maybe some other exit paths). The trip-counter exit is always 82.15 -// last in the loop. The trip-counter does not have to stride by a constant, 82.16 -// but it does have to stride by a loop-invariant amount; the exit value is 82.17 -// also loop invariant. 82.18 +// last in the loop. The trip-counter have to stride by a constant; 82.19 +// the exit value is also loop invariant. 82.20 82.21 // CountedLoopNodes and CountedLoopEndNodes come in matched pairs. The 82.22 // CountedLoopNode has the incoming loop control and the loop-back-control 82.23 @@ -112,7 +112,7 @@ 82.24 // CountedLoopNode if there is control flow in the loop), the post-increment 82.25 // trip-counter value, and the limit. The trip-counter value is always of 82.26 // the form (Op old-trip-counter stride). The old-trip-counter is produced 82.27 -// by a Phi connected to the CountedLoopNode. The stride is loop invariant. 82.28 +// by a Phi connected to the CountedLoopNode. The stride is constant. 82.29 // The Op is any commutable opcode, including Add, Mul, Xor. The 82.30 // CountedLoopEndNode also takes in the loop-invariant limit value. 82.31 82.32 @@ -696,6 +696,9 @@ 82.33 // Is safept not required by an outer loop? 82.34 bool is_deleteable_safept(Node* sfpt); 82.35 82.36 + // Replace parallel induction variable (parallel to trip counter) 82.37 + void replace_parallel_iv(IdealLoopTree *loop); 82.38 + 82.39 // Perform verification that the graph is valid. 82.40 PhaseIdealLoop( PhaseIterGVN &igvn) : 82.41 PhaseTransform(Ideal_Loop), 82.42 @@ -751,7 +754,7 @@ 82.43 // Per-Node transform 82.44 virtual Node *transform( Node *a_node ) { return 0; } 82.45 82.46 - Node *is_counted_loop( Node *x, IdealLoopTree *loop ); 82.47 + bool is_counted_loop( Node *x, IdealLoopTree *loop ); 82.48 82.49 // Return a post-walked LoopNode 82.50 IdealLoopTree *get_loop( Node *n ) const { 82.51 @@ -815,16 +818,22 @@ 82.52 bool is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale, Node** p_offset, int depth = 0); 82.53 82.54 // Return true if proj is for "proj->[region->..]call_uct" 82.55 - bool is_uncommon_trap_proj(ProjNode* proj, bool must_reason_predicate = false); 82.56 + // Return true if proj is for "proj->[region->..]call_uct" 82.57 + static bool is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason); 82.58 // Return true for "if(test)-> proj -> ... 82.59 // | 82.60 // V 82.61 // other_proj->[region->..]call_uct" 82.62 - bool is_uncommon_trap_if_pattern(ProjNode* proj, bool must_reason_predicate = false); 82.63 + static bool is_uncommon_trap_if_pattern(ProjNode* proj, Deoptimization::DeoptReason reason); 82.64 // Create a new if above the uncommon_trap_if_pattern for the predicate to be promoted 82.65 - ProjNode* create_new_if_for_predicate(ProjNode* cont_proj); 82.66 - // Find a good location to insert a predicate 82.67 - ProjNode* find_predicate_insertion_point(Node* start_c); 82.68 + ProjNode* create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, 82.69 + Deoptimization::DeoptReason reason); 82.70 + void register_control(Node* n, IdealLoopTree *loop, Node* pred); 82.71 + 82.72 + // Find a good location to insert a predicate 82.73 + static ProjNode* find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason); 82.74 + // Find a predicate 82.75 + static Node* find_predicate(Node* entry); 82.76 // Construct a range check for a predicate if 82.77 BoolNode* rc_predicate(Node* ctrl, 82.78 int scale, Node* offset, 82.79 @@ -936,7 +945,7 @@ 82.80 Node *has_local_phi_input( Node *n ); 82.81 // Mark an IfNode as being dominated by a prior test, 82.82 // without actually altering the CFG (and hence IDOM info). 82.83 - void dominated_by( Node *prevdom, Node *iff ); 82.84 + void dominated_by( Node *prevdom, Node *iff, bool flip = false ); 82.85 82.86 // Split Node 'n' through merge point 82.87 Node *split_thru_region( Node *n, Node *region );
83.1 --- a/src/share/vm/opto/loopopts.cpp Fri Mar 25 17:26:33 2011 -0700 83.2 +++ b/src/share/vm/opto/loopopts.cpp Fri Mar 25 18:04:45 2011 -0700 83.3 @@ -42,13 +42,13 @@ 83.4 return NULL; 83.5 } 83.6 int wins = 0; 83.7 - assert( !n->is_CFG(), "" ); 83.8 - assert( region->is_Region(), "" ); 83.9 + assert(!n->is_CFG(), ""); 83.10 + assert(region->is_Region(), ""); 83.11 83.12 const Type* type = n->bottom_type(); 83.13 const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr(); 83.14 Node *phi; 83.15 - if( t_oop != NULL && t_oop->is_known_instance_field() ) { 83.16 + if (t_oop != NULL && t_oop->is_known_instance_field()) { 83.17 int iid = t_oop->instance_id(); 83.18 int index = C->get_alias_index(t_oop); 83.19 int offset = t_oop->offset(); 83.20 @@ -57,20 +57,20 @@ 83.21 phi = PhiNode::make_blank(region, n); 83.22 } 83.23 uint old_unique = C->unique(); 83.24 - for( uint i = 1; i < region->req(); i++ ) { 83.25 + for (uint i = 1; i < region->req(); i++) { 83.26 Node *x; 83.27 Node* the_clone = NULL; 83.28 - if( region->in(i) == C->top() ) { 83.29 + if (region->in(i) == C->top()) { 83.30 x = C->top(); // Dead path? Use a dead data op 83.31 } else { 83.32 x = n->clone(); // Else clone up the data op 83.33 the_clone = x; // Remember for possible deletion. 83.34 // Alter data node to use pre-phi inputs 83.35 - if( n->in(0) == region ) 83.36 + if (n->in(0) == region) 83.37 x->set_req( 0, region->in(i) ); 83.38 - for( uint j = 1; j < n->req(); j++ ) { 83.39 + for (uint j = 1; j < n->req(); j++) { 83.40 Node *in = n->in(j); 83.41 - if( in->is_Phi() && in->in(0) == region ) 83.42 + if (in->is_Phi() && in->in(0) == region) 83.43 x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone 83.44 } 83.45 } 83.46 @@ -85,7 +85,7 @@ 83.47 // happen if the singleton occurs on loop entry, as the elimination of 83.48 // the PhiNode may cause the resulting node to migrate back to a previous 83.49 // loop iteration. 83.50 - if( singleton && t == Type::TOP ) { 83.51 + if (singleton && t == Type::TOP) { 83.52 // Is_Loop() == false does not confirm the absence of a loop (e.g., an 83.53 // irreducible loop may not be indicated by an affirmative is_Loop()); 83.54 // therefore, the only top we can split thru a phi is on a backedge of 83.55 @@ -93,7 +93,7 @@ 83.56 singleton &= region->is_Loop() && (i != LoopNode::EntryControl); 83.57 } 83.58 83.59 - if( singleton ) { 83.60 + if (singleton) { 83.61 wins++; 83.62 x = ((PhaseGVN&)_igvn).makecon(t); 83.63 } else { 83.64 @@ -108,12 +108,12 @@ 83.65 // igvn->type(x) is set to x->Value() already. 83.66 x->raise_bottom_type(t); 83.67 Node *y = x->Identity(&_igvn); 83.68 - if( y != x ) { 83.69 + if (y != x) { 83.70 wins++; 83.71 x = y; 83.72 } else { 83.73 y = _igvn.hash_find(x); 83.74 - if( y ) { 83.75 + if (y) { 83.76 wins++; 83.77 x = y; 83.78 } else { 83.79 @@ -129,7 +129,7 @@ 83.80 phi->set_req( i, x ); 83.81 } 83.82 // Too few wins? 83.83 - if( wins <= policy ) { 83.84 + if (wins <= policy) { 83.85 _igvn.remove_dead_node(phi); 83.86 return NULL; 83.87 } 83.88 @@ -137,7 +137,7 @@ 83.89 // Record Phi 83.90 register_new_node( phi, region ); 83.91 83.92 - for( uint i2 = 1; i2 < phi->req(); i2++ ) { 83.93 + for (uint i2 = 1; i2 < phi->req(); i2++) { 83.94 Node *x = phi->in(i2); 83.95 // If we commoned up the cloned 'x' with another existing Node, 83.96 // the existing Node picks up a new use. We need to make the 83.97 @@ -145,24 +145,44 @@ 83.98 Node *old_ctrl; 83.99 IdealLoopTree *old_loop; 83.100 83.101 + if (x->is_Con()) { 83.102 + // Constant's control is always root. 83.103 + set_ctrl(x, C->root()); 83.104 + continue; 83.105 + } 83.106 // The occasional new node 83.107 - if( x->_idx >= old_unique ) { // Found a new, unplaced node? 83.108 - old_ctrl = x->is_Con() ? C->root() : NULL; 83.109 - old_loop = NULL; // Not in any prior loop 83.110 + if (x->_idx >= old_unique) { // Found a new, unplaced node? 83.111 + old_ctrl = NULL; 83.112 + old_loop = NULL; // Not in any prior loop 83.113 } else { 83.114 - old_ctrl = x->is_Con() ? C->root() : get_ctrl(x); 83.115 + old_ctrl = get_ctrl(x); 83.116 old_loop = get_loop(old_ctrl); // Get prior loop 83.117 } 83.118 // New late point must dominate new use 83.119 - Node *new_ctrl = dom_lca( old_ctrl, region->in(i2) ); 83.120 + Node *new_ctrl = dom_lca(old_ctrl, region->in(i2)); 83.121 + if (new_ctrl == old_ctrl) // Nothing is changed 83.122 + continue; 83.123 + 83.124 + IdealLoopTree *new_loop = get_loop(new_ctrl); 83.125 + 83.126 + // Don't move x into a loop if its uses are 83.127 + // outside of loop. Otherwise x will be cloned 83.128 + // for each use outside of this loop. 83.129 + IdealLoopTree *use_loop = get_loop(region); 83.130 + if (!new_loop->is_member(use_loop) && 83.131 + (old_loop == NULL || !new_loop->is_member(old_loop))) { 83.132 + // Take early control, later control will be recalculated 83.133 + // during next iteration of loop optimizations. 83.134 + new_ctrl = get_early_ctrl(x); 83.135 + new_loop = get_loop(new_ctrl); 83.136 + } 83.137 // Set new location 83.138 set_ctrl(x, new_ctrl); 83.139 - IdealLoopTree *new_loop = get_loop( new_ctrl ); 83.140 // If changing loop bodies, see if we need to collect into new body 83.141 - if( old_loop != new_loop ) { 83.142 - if( old_loop && !old_loop->_child ) 83.143 + if (old_loop != new_loop) { 83.144 + if (old_loop && !old_loop->_child) 83.145 old_loop->_body.yank(x); 83.146 - if( !new_loop->_child ) 83.147 + if (!new_loop->_child) 83.148 new_loop->_body.push(x); // Collect body info 83.149 } 83.150 } 83.151 @@ -174,9 +194,9 @@ 83.152 // Replace the dominated test with an obvious true or false. Place it on the 83.153 // IGVN worklist for later cleanup. Move control-dependent data Nodes on the 83.154 // live path up to the dominating control. 83.155 -void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) { 83.156 +void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip ) { 83.157 #ifndef PRODUCT 83.158 - if( VerifyLoopOptimizations && PrintOpto ) tty->print_cr("dominating test"); 83.159 + if (VerifyLoopOptimizations && PrintOpto) tty->print_cr("dominating test"); 83.160 #endif 83.161 83.162 83.163 @@ -185,6 +205,12 @@ 83.164 assert( iff->Opcode() == Op_If || iff->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added"); 83.165 int pop = prevdom->Opcode(); 83.166 assert( pop == Op_IfFalse || pop == Op_IfTrue, "" ); 83.167 + if (flip) { 83.168 + if (pop == Op_IfTrue) 83.169 + pop = Op_IfFalse; 83.170 + else 83.171 + pop = Op_IfTrue; 83.172 + } 83.173 // 'con' is set to true or false to kill the dominated test. 83.174 Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO); 83.175 set_ctrl(con, C->root()); // Constant gets a new use 83.176 @@ -197,7 +223,7 @@ 83.177 // I can assume this path reaches an infinite loop. In this case it's not 83.178 // important to optimize the data Nodes - either the whole compilation will 83.179 // be tossed or this path (and all data Nodes) will go dead. 83.180 - if( iff->outcnt() != 2 ) return; 83.181 + if (iff->outcnt() != 2) return; 83.182 83.183 // Make control-dependent data Nodes on the live path (path that will remain 83.184 // once the dominated IF is removed) become control-dependent on the 83.185 @@ -207,16 +233,16 @@ 83.186 83.187 for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { 83.188 Node* cd = dp->fast_out(i); // Control-dependent node 83.189 - if( cd->depends_only_on_test() ) { 83.190 - assert( cd->in(0) == dp, "" ); 83.191 - _igvn.hash_delete( cd ); 83.192 + if (cd->depends_only_on_test()) { 83.193 + assert(cd->in(0) == dp, ""); 83.194 + _igvn.hash_delete(cd); 83.195 cd->set_req(0, prevdom); 83.196 - set_early_ctrl( cd ); 83.197 + set_early_ctrl(cd); 83.198 _igvn._worklist.push(cd); 83.199 IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); 83.200 - if( old_loop != new_loop ) { 83.201 - if( !old_loop->_child ) old_loop->_body.yank(cd); 83.202 - if( !new_loop->_child ) new_loop->_body.push(cd); 83.203 + if (old_loop != new_loop) { 83.204 + if (!old_loop->_child) old_loop->_body.yank(cd); 83.205 + if (!new_loop->_child) new_loop->_body.push(cd); 83.206 } 83.207 --i; 83.208 --imax; 83.209 @@ -2338,6 +2364,11 @@ 83.210 } 83.211 83.212 #if !defined(PRODUCT) 83.213 + if (TraceLoopOpts) { 83.214 + tty->print("PartialPeel "); 83.215 + loop->dump_head(); 83.216 + } 83.217 + 83.218 if (TracePartialPeeling) { 83.219 tty->print_cr("before partial peel one iteration"); 83.220 Node_List wl; 83.221 @@ -2481,6 +2512,7 @@ 83.222 // Create new loop head for new phis and to hang 83.223 // the nodes being moved (sinked) from the peel region. 83.224 LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel); 83.225 + new_head->set_unswitch_count(head->unswitch_count()); // Preserve 83.226 _igvn.register_new_node_with_optimizer(new_head); 83.227 assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled"); 83.228 first_not_peeled->set_req(0, new_head); 83.229 @@ -2651,24 +2683,23 @@ 83.230 // prevent loop-fallout uses of the pre-incremented trip counter (which are 83.231 // then alive with the post-incremented trip counter forcing an extra 83.232 // register move) 83.233 -void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) { 83.234 +void PhaseIdealLoop::reorg_offsets(IdealLoopTree *loop) { 83.235 + // Perform it only for canonical counted loops. 83.236 + // Loop's shape could be messed up by iteration_split_impl. 83.237 + if (!loop->_head->is_CountedLoop()) 83.238 + return; 83.239 + if (!loop->_head->as_Loop()->is_valid_counted_loop()) 83.240 + return; 83.241 83.242 CountedLoopNode *cl = loop->_head->as_CountedLoop(); 83.243 CountedLoopEndNode *cle = cl->loopexit(); 83.244 - if( !cle ) return; // The occasional dead loop 83.245 - // Find loop exit control 83.246 Node *exit = cle->proj_out(false); 83.247 - assert( exit->Opcode() == Op_IfFalse, "" ); 83.248 + Node *phi = cl->phi(); 83.249 83.250 // Check for the special case of folks using the pre-incremented 83.251 // trip-counter on the fall-out path (forces the pre-incremented 83.252 // and post-incremented trip counter to be live at the same time). 83.253 // Fix this by adjusting to use the post-increment trip counter. 83.254 - Node *phi = cl->phi(); 83.255 - if( !phi ) return; // Dead infinite loop 83.256 - 83.257 - // Shape messed up, probably by iteration_split_impl 83.258 - if (phi->in(LoopNode::LoopBackControl) != cl->incr()) return; 83.259 83.260 bool progress = true; 83.261 while (progress) { 83.262 @@ -2677,21 +2708,19 @@ 83.263 Node* use = phi->fast_out(i); // User of trip-counter 83.264 if (!has_ctrl(use)) continue; 83.265 Node *u_ctrl = get_ctrl(use); 83.266 - if( use->is_Phi() ) { 83.267 + if (use->is_Phi()) { 83.268 u_ctrl = NULL; 83.269 - for( uint j = 1; j < use->req(); j++ ) 83.270 - if( use->in(j) == phi ) 83.271 - u_ctrl = dom_lca( u_ctrl, use->in(0)->in(j) ); 83.272 + for (uint j = 1; j < use->req(); j++) 83.273 + if (use->in(j) == phi) 83.274 + u_ctrl = dom_lca(u_ctrl, use->in(0)->in(j)); 83.275 } 83.276 IdealLoopTree *u_loop = get_loop(u_ctrl); 83.277 // Look for loop-invariant use 83.278 - if( u_loop == loop ) continue; 83.279 - if( loop->is_member( u_loop ) ) continue; 83.280 + if (u_loop == loop) continue; 83.281 + if (loop->is_member(u_loop)) continue; 83.282 // Check that use is live out the bottom. Assuming the trip-counter 83.283 // update is right at the bottom, uses of of the loop middle are ok. 83.284 - if( dom_lca( exit, u_ctrl ) != exit ) continue; 83.285 - // protect against stride not being a constant 83.286 - if( !cle->stride_is_con() ) continue; 83.287 + if (dom_lca(exit, u_ctrl) != exit) continue; 83.288 // Hit! Refactor use to use the post-incremented tripcounter. 83.289 // Compute a post-increment tripcounter. 83.290 Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() ); 83.291 @@ -2702,9 +2731,10 @@ 83.292 register_new_node( post, u_ctrl ); 83.293 _igvn.hash_delete(use); 83.294 _igvn._worklist.push(use); 83.295 - for( uint j = 1; j < use->req(); j++ ) 83.296 - if( use->in(j) == phi ) 83.297 + for (uint j = 1; j < use->req(); j++) { 83.298 + if (use->in(j) == phi) 83.299 use->set_req(j, post); 83.300 + } 83.301 // Since DU info changed, rerun loop 83.302 progress = true; 83.303 break;
84.1 --- a/src/share/vm/opto/memnode.cpp Fri Mar 25 17:26:33 2011 -0700 84.2 +++ b/src/share/vm/opto/memnode.cpp Fri Mar 25 18:04:45 2011 -0700 84.3 @@ -1573,9 +1573,9 @@ 84.4 return TypeInt::make(constant.as_int()); 84.5 } else if (constant.basic_type() == T_ARRAY) { 84.6 if (adr->bottom_type()->is_ptr_to_narrowoop()) { 84.7 - return TypeNarrowOop::make_from_constant(constant.as_object()); 84.8 + return TypeNarrowOop::make_from_constant(constant.as_object(), true); 84.9 } else { 84.10 - return TypeOopPtr::make_from_constant(constant.as_object()); 84.11 + return TypeOopPtr::make_from_constant(constant.as_object(), true); 84.12 } 84.13 } 84.14 }
85.1 --- a/src/share/vm/opto/parse.hpp Fri Mar 25 17:26:33 2011 -0700 85.2 +++ b/src/share/vm/opto/parse.hpp Fri Mar 25 18:04:45 2011 -0700 85.3 @@ -1,5 +1,5 @@ 85.4 /* 85.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 85.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 85.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 85.8 * 85.9 * This code is free software; you can redistribute it and/or modify it 85.10 @@ -136,6 +136,7 @@ 85.11 uint _count; // how many times executed? Currently only set by _goto's 85.12 bool _is_parsed; // has this block been parsed yet? 85.13 bool _is_handler; // is this block an exception handler? 85.14 + bool _has_merged_backedge; // does this block have merged backedge? 85.15 SafePointNode* _start_map; // all values flowing into this block 85.16 MethodLivenessResult _live_locals; // lazily initialized liveness bitmap 85.17 85.18 @@ -168,6 +169,18 @@ 85.19 // True after any predecessor flows control into this block 85.20 bool is_merged() const { return _start_map != NULL; } 85.21 85.22 +#ifdef ASSERT 85.23 + // True after backedge predecessor flows control into this block 85.24 + bool has_merged_backedge() const { return _has_merged_backedge; } 85.25 + void mark_merged_backedge(Block* pred) { 85.26 + assert(is_SEL_head(), "should be loop head"); 85.27 + if (pred != NULL && is_SEL_backedge(pred)) { 85.28 + assert(is_parsed(), "block should be parsed before merging backedges"); 85.29 + _has_merged_backedge = true; 85.30 + } 85.31 + } 85.32 +#endif 85.33 + 85.34 // True when all non-exception predecessors have been parsed. 85.35 bool is_ready() const { return preds_parsed() == pred_count(); } 85.36 85.37 @@ -441,11 +454,6 @@ 85.38 } 85.39 } 85.40 85.41 - // Return true if the parser should add a loop predicate 85.42 - bool should_add_predicate(int target_bci); 85.43 - // Insert a loop predicate into the graph 85.44 - void add_predicate(); 85.45 - 85.46 // Note: Intrinsic generation routines may be found in library_call.cpp. 85.47 85.48 // Helper function to setup Ideal Call nodes 85.49 @@ -483,8 +491,8 @@ 85.50 bool static_field_ok_in_clinit(ciField *field, ciMethod *method); 85.51 85.52 // common code for actually performing the load or store 85.53 - void do_get_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field); 85.54 - void do_put_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field); 85.55 + void do_get_xxx(Node* obj, ciField* field, bool is_field); 85.56 + void do_put_xxx(Node* obj, ciField* field, bool is_field); 85.57 85.58 // loading from a constant field or the constant pool 85.59 // returns false if push failed (non-perm field constants only, not ldcs)
86.1 --- a/src/share/vm/opto/parse1.cpp Fri Mar 25 17:26:33 2011 -0700 86.2 +++ b/src/share/vm/opto/parse1.cpp Fri Mar 25 18:04:45 2011 -0700 86.3 @@ -637,6 +637,25 @@ 86.4 // (Note that dead locals do not get phis built, ever.) 86.5 ensure_phis_everywhere(); 86.6 86.7 + if (block->is_SEL_head() && 86.8 + UseLoopPredicate) { 86.9 + // Add predicate to single entry (not irreducible) loop head. 86.10 + assert(!block->has_merged_backedge(), "only entry paths should be merged for now"); 86.11 + // Need correct bci for predicate. 86.12 + // It is fine to set it here since do_one_block() will set it anyway. 86.13 + set_parse_bci(block->start()); 86.14 + add_predicate(); 86.15 + // Add new region for back branches. 86.16 + int edges = block->pred_count() - block->preds_parsed() + 1; // +1 for original region 86.17 + RegionNode *r = new (C, edges+1) RegionNode(edges+1); 86.18 + _gvn.set_type(r, Type::CONTROL); 86.19 + record_for_igvn(r); 86.20 + r->init_req(edges, control()); 86.21 + set_control(r); 86.22 + // Add new phis. 86.23 + ensure_phis_everywhere(); 86.24 + } 86.25 + 86.26 // Leave behind an undisturbed copy of the map, for future merges. 86.27 set_map(clone_map()); 86.28 } 86.29 @@ -1113,7 +1132,7 @@ 86.30 _preds_parsed = 0; 86.31 _count = 0; 86.32 assert(pred_count() == 0 && preds_parsed() == 0, "sanity"); 86.33 - assert(!(is_merged() || is_parsed() || is_handler()), "sanity"); 86.34 + assert(!(is_merged() || is_parsed() || is_handler() || has_merged_backedge()), "sanity"); 86.35 assert(_live_locals.size() == 0, "sanity"); 86.36 86.37 // entry point has additional predecessor 86.38 @@ -1350,10 +1369,6 @@ 86.39 set_parse_bci(iter().cur_bci()); 86.40 86.41 if (bci() == block()->limit()) { 86.42 - // insert a predicate if it falls through to a loop head block 86.43 - if (should_add_predicate(bci())){ 86.44 - add_predicate(); 86.45 - } 86.46 // Do not walk into the next block until directed by do_all_blocks. 86.47 merge(bci()); 86.48 break; 86.49 @@ -1498,17 +1513,29 @@ 86.50 || target->is_handler() // These have unpredictable inputs. 86.51 || target->is_loop_head() // Known multiple inputs 86.52 || control()->is_Region()) { // We must hide this guy. 86.53 + 86.54 + int current_bci = bci(); 86.55 + set_parse_bci(target->start()); // Set target bci 86.56 + if (target->is_SEL_head()) { 86.57 + DEBUG_ONLY( target->mark_merged_backedge(block()); ) 86.58 + if (target->start() == 0) { 86.59 + // Add loop predicate for the special case when 86.60 + // there are backbranches to the method entry. 86.61 + add_predicate(); 86.62 + } 86.63 + } 86.64 // Add a Region to start the new basic block. Phis will be added 86.65 // later lazily. 86.66 int edges = target->pred_count(); 86.67 if (edges < pnum) edges = pnum; // might be a new path! 86.68 - Node *r = new (C, edges+1) RegionNode(edges+1); 86.69 + RegionNode *r = new (C, edges+1) RegionNode(edges+1); 86.70 gvn().set_type(r, Type::CONTROL); 86.71 record_for_igvn(r); 86.72 // zap all inputs to NULL for debugging (done in Node(uint) constructor) 86.73 // for (int j = 1; j < edges+1; j++) { r->init_req(j, NULL); } 86.74 r->init_req(pnum, control()); 86.75 set_control(r); 86.76 + set_parse_bci(current_bci); // Restore bci 86.77 } 86.78 86.79 // Convert the existing Parser mapping into a mapping at this bci. 86.80 @@ -1517,7 +1544,11 @@ 86.81 86.82 } else { // Prior mapping at this bci 86.83 if (TraceOptoParse) { tty->print(" with previous state"); } 86.84 - 86.85 +#ifdef ASSERT 86.86 + if (target->is_SEL_head()) { 86.87 + target->mark_merged_backedge(block()); 86.88 + } 86.89 +#endif 86.90 // We must not manufacture more phis if the target is already parsed. 86.91 bool nophi = target->is_parsed(); 86.92 86.93 @@ -2054,37 +2085,6 @@ 86.94 } 86.95 } 86.96 86.97 -//------------------------------should_add_predicate-------------------------- 86.98 -bool Parse::should_add_predicate(int target_bci) { 86.99 - if (!UseLoopPredicate) return false; 86.100 - Block* target = successor_for_bci(target_bci); 86.101 - if (target != NULL && 86.102 - target->is_loop_head() && 86.103 - block()->rpo() < target->rpo()) { 86.104 - return true; 86.105 - } 86.106 - return false; 86.107 -} 86.108 - 86.109 -//------------------------------add_predicate--------------------------------- 86.110 -void Parse::add_predicate() { 86.111 - assert(UseLoopPredicate,"use only for loop predicate"); 86.112 - Node *cont = _gvn.intcon(1); 86.113 - Node* opq = _gvn.transform(new (C, 2) Opaque1Node(C, cont)); 86.114 - Node *bol = _gvn.transform(new (C, 2) Conv2BNode(opq)); 86.115 - IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); 86.116 - Node* iffalse = _gvn.transform(new (C, 1) IfFalseNode(iff)); 86.117 - C->add_predicate_opaq(opq); 86.118 - { 86.119 - PreserveJVMState pjvms(this); 86.120 - set_control(iffalse); 86.121 - uncommon_trap(Deoptimization::Reason_predicate, 86.122 - Deoptimization::Action_maybe_recompile); 86.123 - } 86.124 - Node* iftrue = _gvn.transform(new (C, 1) IfTrueNode(iff)); 86.125 - set_control(iftrue); 86.126 -} 86.127 - 86.128 #ifndef PRODUCT 86.129 //------------------------show_parse_info-------------------------------------- 86.130 void Parse::show_parse_info() {
87.1 --- a/src/share/vm/opto/parse2.cpp Fri Mar 25 17:26:33 2011 -0700 87.2 +++ b/src/share/vm/opto/parse2.cpp Fri Mar 25 18:04:45 2011 -0700 87.3 @@ -293,11 +293,6 @@ 87.4 if (len < 1) { 87.5 // If this is a backward branch, add safepoint 87.6 maybe_add_safepoint(default_dest); 87.7 - if (should_add_predicate(default_dest)){ 87.8 - _sp += 1; // set original stack for use by uncommon_trap 87.9 - add_predicate(); 87.10 - _sp -= 1; 87.11 - } 87.12 merge(default_dest); 87.13 return; 87.14 } 87.15 @@ -344,11 +339,6 @@ 87.16 87.17 if (len < 1) { // If this is a backward branch, add safepoint 87.18 maybe_add_safepoint(default_dest); 87.19 - if (should_add_predicate(default_dest)){ 87.20 - _sp += 1; // set original stack for use by uncommon_trap 87.21 - add_predicate(); 87.22 - _sp -= 1; 87.23 - } 87.24 merge(default_dest); 87.25 return; 87.26 } 87.27 @@ -756,9 +746,6 @@ 87.28 push(_gvn.makecon(ret_addr)); 87.29 87.30 // Flow to the jsr. 87.31 - if (should_add_predicate(jsr_bci)){ 87.32 - add_predicate(); 87.33 - } 87.34 merge(jsr_bci); 87.35 } 87.36 87.37 @@ -1040,11 +1027,6 @@ 87.38 profile_taken_branch(target_bci); 87.39 adjust_map_after_if(btest, c, prob, branch_block, next_block); 87.40 if (!stopped()) { 87.41 - if (should_add_predicate(target_bci)){ // add a predicate if it branches to a loop 87.42 - int nargs = repush_if_args(); // set original stack for uncommon_trap 87.43 - add_predicate(); 87.44 - _sp -= nargs; 87.45 - } 87.46 merge(target_bci); 87.47 } 87.48 } 87.49 @@ -1168,11 +1150,6 @@ 87.50 profile_taken_branch(target_bci); 87.51 adjust_map_after_if(taken_btest, c, prob, branch_block, next_block); 87.52 if (!stopped()) { 87.53 - if (should_add_predicate(target_bci)){ // add a predicate if it branches to a loop 87.54 - int nargs = repush_if_args(); // set original stack for the uncommon_trap 87.55 - add_predicate(); 87.56 - _sp -= nargs; 87.57 - } 87.58 merge(target_bci); 87.59 } 87.60 } 87.61 @@ -2166,10 +2143,6 @@ 87.62 // Update method data 87.63 profile_taken_branch(target_bci); 87.64 87.65 - // Add loop predicate if it goes to a loop 87.66 - if (should_add_predicate(target_bci)){ 87.67 - add_predicate(); 87.68 - } 87.69 // Merge the current control into the target basic block 87.70 merge(target_bci); 87.71
88.1 --- a/src/share/vm/opto/parse3.cpp Fri Mar 25 17:26:33 2011 -0700 88.2 +++ b/src/share/vm/opto/parse3.cpp Fri Mar 25 18:04:45 2011 -0700 88.3 @@ -112,29 +112,31 @@ 88.4 // Compile-time detect of null-exception? 88.5 if (stopped()) return; 88.6 88.7 +#ifdef ASSERT 88.8 const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder()); 88.9 assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed"); 88.10 +#endif 88.11 88.12 if (is_get) { 88.13 --_sp; // pop receiver before getting 88.14 - do_get_xxx(tjp, obj, field, is_field); 88.15 + do_get_xxx(obj, field, is_field); 88.16 } else { 88.17 - do_put_xxx(tjp, obj, field, is_field); 88.18 + do_put_xxx(obj, field, is_field); 88.19 --_sp; // pop receiver after putting 88.20 } 88.21 } else { 88.22 - const TypeKlassPtr* tkp = TypeKlassPtr::make(field_holder); 88.23 - obj = _gvn.makecon(tkp); 88.24 + const TypeInstPtr* tip = TypeInstPtr::make(field_holder->java_mirror()); 88.25 + obj = _gvn.makecon(tip); 88.26 if (is_get) { 88.27 - do_get_xxx(tkp, obj, field, is_field); 88.28 + do_get_xxx(obj, field, is_field); 88.29 } else { 88.30 - do_put_xxx(tkp, obj, field, is_field); 88.31 + do_put_xxx(obj, field, is_field); 88.32 } 88.33 } 88.34 } 88.35 88.36 88.37 -void Parse::do_get_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) { 88.38 +void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { 88.39 // Does this field have a constant value? If so, just push the value. 88.40 if (field->is_constant()) { 88.41 if (field->is_static()) { 88.42 @@ -231,7 +233,7 @@ 88.43 } 88.44 } 88.45 88.46 -void Parse::do_put_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) { 88.47 +void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { 88.48 bool is_vol = field->is_volatile(); 88.49 // If reference is volatile, prevent following memory ops from 88.50 // floating down past the volatile write. Also prevents commoning
89.1 --- a/src/share/vm/opto/stringopts.cpp Fri Mar 25 17:26:33 2011 -0700 89.2 +++ b/src/share/vm/opto/stringopts.cpp Fri Mar 25 18:04:45 2011 -0700 89.3 @@ -910,7 +910,7 @@ 89.4 ciObject* con = field->constant_value().as_object(); 89.5 // Do not "join" in the previous type; it doesn't add value, 89.6 // and may yield a vacuous result if the field is of interface type. 89.7 - type = TypeOopPtr::make_from_constant(con)->isa_oopptr(); 89.8 + type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr(); 89.9 assert(type != NULL, "field singleton type must be consistent"); 89.10 } else { 89.11 type = TypeOopPtr::make_from_klass(field_klass->as_klass()); 89.12 @@ -969,6 +969,10 @@ 89.13 // for (int i=0; ; i++) 89.14 // if (x <= sizeTable[i]) 89.15 // return i+1; 89.16 + 89.17 + // Add loop predicate first. 89.18 + kit.add_predicate(); 89.19 + 89.20 RegionNode *loop = new (C, 3) RegionNode(3); 89.21 loop->init_req(1, kit.control()); 89.22 kit.gvn().set_type(loop, Type::CONTROL); 89.23 @@ -1086,6 +1090,9 @@ 89.24 // } 89.25 89.26 { 89.27 + // Add loop predicate first. 89.28 + kit.add_predicate(); 89.29 + 89.30 RegionNode *head = new (C, 3) RegionNode(3); 89.31 head->init_req(1, kit.control()); 89.32 kit.gvn().set_type(head, Type::CONTROL);
90.1 --- a/src/share/vm/opto/type.cpp Fri Mar 25 17:26:33 2011 -0700 90.2 +++ b/src/share/vm/opto/type.cpp Fri Mar 25 18:04:45 2011 -0700 90.3 @@ -32,6 +32,7 @@ 90.4 #include "memory/oopFactory.hpp" 90.5 #include "memory/resourceArea.hpp" 90.6 #include "oops/instanceKlass.hpp" 90.7 +#include "oops/instanceMirrorKlass.hpp" 90.8 #include "oops/klassKlass.hpp" 90.9 #include "oops/objArrayKlass.hpp" 90.10 #include "oops/typeArrayKlass.hpp" 90.11 @@ -2241,43 +2242,49 @@ 90.12 } else if (this->isa_aryptr()) { 90.13 _is_ptr_to_narrowoop = (klass()->is_obj_array_klass() && 90.14 _offset != arrayOopDesc::length_offset_in_bytes()); 90.15 - } else if (klass() == ciEnv::current()->Class_klass() && 90.16 - (_offset == java_lang_Class::klass_offset_in_bytes() || 90.17 - _offset == java_lang_Class::array_klass_offset_in_bytes())) { 90.18 - // Special hidden fields from the Class. 90.19 - assert(this->isa_instptr(), "must be an instance ptr."); 90.20 - _is_ptr_to_narrowoop = true; 90.21 } else if (klass()->is_instance_klass()) { 90.22 ciInstanceKlass* ik = klass()->as_instance_klass(); 90.23 ciField* field = NULL; 90.24 if (this->isa_klassptr()) { 90.25 - // Perm objects don't use compressed references, except for 90.26 - // static fields which are currently compressed. 90.27 - field = ik->get_field_by_offset(_offset, true); 90.28 - if (field != NULL) { 90.29 - BasicType basic_elem_type = field->layout_type(); 90.30 - _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT || 90.31 - basic_elem_type == T_ARRAY); 90.32 - } 90.33 + // Perm objects don't use compressed references 90.34 } else if (_offset == OffsetBot || _offset == OffsetTop) { 90.35 // unsafe access 90.36 _is_ptr_to_narrowoop = true; 90.37 } else { // exclude unsafe ops 90.38 assert(this->isa_instptr(), "must be an instance ptr."); 90.39 - // Field which contains a compressed oop references. 90.40 - field = ik->get_field_by_offset(_offset, false); 90.41 - if (field != NULL) { 90.42 + 90.43 + if (klass() == ciEnv::current()->Class_klass() && 90.44 + (_offset == java_lang_Class::klass_offset_in_bytes() || 90.45 + _offset == java_lang_Class::array_klass_offset_in_bytes())) { 90.46 + // Special hidden fields from the Class. 90.47 + assert(this->isa_instptr(), "must be an instance ptr."); 90.48 + _is_ptr_to_narrowoop = true; 90.49 + } else if (klass() == ciEnv::current()->Class_klass() && 90.50 + _offset >= instanceMirrorKlass::offset_of_static_fields()) { 90.51 + // Static fields 90.52 + assert(o != NULL, "must be constant"); 90.53 + ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass(); 90.54 + ciField* field = k->get_field_by_offset(_offset, true); 90.55 + assert(field != NULL, "missing field"); 90.56 BasicType basic_elem_type = field->layout_type(); 90.57 _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT || 90.58 basic_elem_type == T_ARRAY); 90.59 - } else if (klass()->equals(ciEnv::current()->Object_klass())) { 90.60 - // Compile::find_alias_type() cast exactness on all types to verify 90.61 - // that it does not affect alias type. 90.62 - _is_ptr_to_narrowoop = true; 90.63 } else { 90.64 - // Type for the copy start in LibraryCallKit::inline_native_clone(). 90.65 - assert(!klass_is_exact(), "only non-exact klass"); 90.66 - _is_ptr_to_narrowoop = true; 90.67 + // Instance fields which contains a compressed oop references. 90.68 + field = ik->get_field_by_offset(_offset, false); 90.69 + if (field != NULL) { 90.70 + BasicType basic_elem_type = field->layout_type(); 90.71 + _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT || 90.72 + basic_elem_type == T_ARRAY); 90.73 + } else if (klass()->equals(ciEnv::current()->Object_klass())) { 90.74 + // Compile::find_alias_type() cast exactness on all types to verify 90.75 + // that it does not affect alias type. 90.76 + _is_ptr_to_narrowoop = true; 90.77 + } else { 90.78 + // Type for the copy start in LibraryCallKit::inline_native_clone(). 90.79 + assert(!klass_is_exact(), "only non-exact klass"); 90.80 + _is_ptr_to_narrowoop = true; 90.81 + } 90.82 } 90.83 } 90.84 }
91.1 --- a/src/share/vm/opto/type.hpp Fri Mar 25 17:26:33 2011 -0700 91.2 +++ b/src/share/vm/opto/type.hpp Fri Mar 25 18:04:45 2011 -0700 91.3 @@ -988,8 +988,8 @@ 91.4 91.5 static const TypeNarrowOop *make( const TypePtr* type); 91.6 91.7 - static const TypeNarrowOop* make_from_constant(ciObject* con) { 91.8 - return make(TypeOopPtr::make_from_constant(con)); 91.9 + static const TypeNarrowOop* make_from_constant(ciObject* con, bool require_constant = false) { 91.10 + return make(TypeOopPtr::make_from_constant(con, require_constant)); 91.11 } 91.12 91.13 // returns the equivalent ptr type for this compressed pointer
92.1 --- a/src/share/vm/prims/jni.cpp Fri Mar 25 17:26:33 2011 -0700 92.2 +++ b/src/share/vm/prims/jni.cpp Fri Mar 25 18:04:45 2011 -0700 92.3 @@ -1,5 +1,5 @@ 92.4 /* 92.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 92.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 92.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 92.8 * 92.9 * This code is free software; you can redistribute it and/or modify it 92.10 @@ -1858,7 +1858,7 @@ 92.11 // Static field. The fieldID a JNIid specifying the field holder and the offset within the klassOop. 92.12 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); 92.13 assert(id->is_static_field_id(), "invalid static field id"); 92.14 - found = instanceKlass::cast(id->holder())->find_local_field_from_offset(id->offset(), true, &fd); 92.15 + found = id->find_local_field(&fd); 92.16 } else { 92.17 // Non-static field. The fieldID is really the offset of the field within the instanceOop. 92.18 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); 92.19 @@ -1906,9 +1906,7 @@ 92.20 JNIid* id = instanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset()); 92.21 debug_only(id->set_is_static_field_id();) 92.22 92.23 - debug_only(int first_offset = instanceKlass::cast(fd.field_holder())->offset_of_static_fields();) 92.24 - debug_only(int end_offset = first_offset + (instanceKlass::cast(fd.field_holder())->static_field_size() * wordSize);) 92.25 - assert(id->offset() >= first_offset && id->offset() < end_offset, "invalid static field offset"); 92.26 + debug_only(id->verify(fd.field_holder())); 92.27 92.28 ret = jfieldIDWorkaround::to_static_jfieldID(id); 92.29 return ret; 92.30 @@ -1928,7 +1926,7 @@ 92.31 if (JvmtiExport::should_post_field_access()) { 92.32 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); 92.33 } 92.34 - jobject ret = JNIHandles::make_local(id->holder()->obj_field(id->offset())); 92.35 + jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset())); 92.36 DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret); 92.37 return ret; 92.38 JNI_END 92.39 @@ -1950,7 +1948,7 @@ 92.40 if (JvmtiExport::should_post_field_access()) { \ 92.41 JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \ 92.42 } \ 92.43 - ret = id->holder()-> Fieldname##_field (id->offset()); \ 92.44 + ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \ 92.45 return ret;\ 92.46 JNI_END 92.47 92.48 @@ -1976,7 +1974,7 @@ 92.49 field_value.l = value; 92.50 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value); 92.51 } 92.52 - id->holder()->obj_field_put(id->offset(), JNIHandles::resolve(value)); 92.53 + id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value)); 92.54 DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return); 92.55 JNI_END 92.56 92.57 @@ -1999,7 +1997,7 @@ 92.58 field_value.unionType = value; \ 92.59 JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \ 92.60 } \ 92.61 - id->holder()-> Fieldname##_field_put (id->offset(), value); \ 92.62 + id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \ 92.63 DTRACE_PROBE(hotspot_jni, SetStatic##Result##Field__return);\ 92.64 JNI_END 92.65
93.1 --- a/src/share/vm/prims/jniCheck.cpp Fri Mar 25 17:26:33 2011 -0700 93.2 +++ b/src/share/vm/prims/jniCheck.cpp Fri Mar 25 18:04:45 2011 -0700 93.3 @@ -1,5 +1,5 @@ 93.4 /* 93.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 93.6 + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 93.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 93.8 * 93.9 * This code is free software; you can redistribute it and/or modify it 93.10 @@ -224,8 +224,7 @@ 93.11 ReportJNIFatalError(thr, fatal_wrong_static_field); 93.12 93.13 /* check for proper field type */ 93.14 - if (!instanceKlass::cast(f_oop)->find_local_field_from_offset( 93.15 - id->offset(), true, &fd)) 93.16 + if (!id->find_local_field(&fd)) 93.17 ReportJNIFatalError(thr, fatal_static_field_not_found); 93.18 if ((fd.field_type() != ftype) && 93.19 !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) {
94.1 --- a/src/share/vm/prims/jvm.cpp Fri Mar 25 17:26:33 2011 -0700 94.2 +++ b/src/share/vm/prims/jvm.cpp Fri Mar 25 18:04:45 2011 -0700 94.3 @@ -1808,7 +1808,7 @@ 94.4 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index"); 94.5 } 94.6 klassOop k = cp->klass_at(index, CHECK_NULL); 94.7 - return (jclass) JNIHandles::make_local(k->klass_part()->java_mirror()); 94.8 + return (jclass) JNIHandles::make_local(k->java_mirror()); 94.9 } 94.10 JVM_END 94.11 94.12 @@ -1824,7 +1824,7 @@ 94.13 } 94.14 klassOop k = constantPoolOopDesc::klass_at_if_loaded(cp, index); 94.15 if (k == NULL) return NULL; 94.16 - return (jclass) JNIHandles::make_local(k->klass_part()->java_mirror()); 94.17 + return (jclass) JNIHandles::make_local(k->java_mirror()); 94.18 } 94.19 JVM_END 94.20
95.1 --- a/src/share/vm/prims/jvmtiEnvBase.cpp Fri Mar 25 17:26:33 2011 -0700 95.2 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Fri Mar 25 18:04:45 2011 -0700 95.3 @@ -1,5 +1,5 @@ 95.4 /* 95.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 95.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 95.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 95.8 * 95.9 * This code is free software; you can redistribute it and/or modify it 95.10 @@ -616,9 +616,7 @@ 95.11 bool found = false; 95.12 if (jfieldIDWorkaround::is_static_jfieldID(field)) { 95.13 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(field); 95.14 - int offset = id->offset(); 95.15 - klassOop holder = id->holder(); 95.16 - found = instanceKlass::cast(holder)->find_local_field_from_offset(offset, true, fd); 95.17 + found = id->find_local_field(fd); 95.18 } else { 95.19 // Non-static field. The fieldID is really the offset of the field within the object. 95.20 int offset = jfieldIDWorkaround::from_instance_jfieldID(k, field);
96.1 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Mar 25 17:26:33 2011 -0700 96.2 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Mar 25 18:04:45 2011 -0700 96.3 @@ -3350,11 +3350,12 @@ 96.4 96.5 for (Klass *subk = ik->subklass(); subk != NULL; 96.6 subk = subk->next_sibling()) { 96.7 - klassOop sub = subk->as_klassOop(); 96.8 - instanceKlass *subik = (instanceKlass *)sub->klass_part(); 96.9 - 96.10 - // recursively do subclasses of the current subclass 96.11 - increment_class_counter(subik, THREAD); 96.12 + if (subk->oop_is_instance()) { 96.13 + // Only update instanceKlasses 96.14 + instanceKlass *subik = (instanceKlass*)subk; 96.15 + // recursively do subclasses of the current subclass 96.16 + increment_class_counter(subik, THREAD); 96.17 + } 96.18 } 96.19 } 96.20
97.1 --- a/src/share/vm/prims/jvmtiTagMap.cpp Fri Mar 25 17:26:33 2011 -0700 97.2 +++ b/src/share/vm/prims/jvmtiTagMap.cpp Fri Mar 25 18:04:45 2011 -0700 97.3 @@ -1,5 +1,5 @@ 97.4 /* 97.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 97.6 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 97.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 97.8 * 97.9 * This code is free software; you can redistribute it and/or modify it 97.10 @@ -27,6 +27,7 @@ 97.11 #include "classfile/systemDictionary.hpp" 97.12 #include "classfile/vmSymbols.hpp" 97.13 #include "jvmtifiles/jvmtiEnv.hpp" 97.14 +#include "oops/instanceMirrorKlass.hpp" 97.15 #include "oops/objArrayKlass.hpp" 97.16 #include "oops/oop.inline2.hpp" 97.17 #include "prims/jvmtiEventController.hpp" 97.18 @@ -2594,6 +2595,11 @@ 97.19 if (o->is_klass()) { 97.20 klassOop k = (klassOop)o; 97.21 o = Klass::cast(k)->java_mirror(); 97.22 + if (o == NULL) { 97.23 + // Classes without mirrors don't correspond to real Java 97.24 + // classes so just ignore them. 97.25 + return; 97.26 + } 97.27 } else { 97.28 97.29 // SystemDictionary::always_strong_oops_do reports the application 97.30 @@ -2834,10 +2840,10 @@ 97.31 97.32 // verify that a static oop field is in range 97.33 static inline bool verify_static_oop(instanceKlass* ik, 97.34 - klassOop k, int offset) { 97.35 - address obj_p = (address)k + offset; 97.36 - address start = (address)ik->start_of_static_fields(); 97.37 - address end = start + (ik->static_oop_field_size() * heapOopSize); 97.38 + oop mirror, int offset) { 97.39 + address obj_p = (address)mirror + offset; 97.40 + address start = (address)instanceMirrorKlass::start_of_static_fields(mirror); 97.41 + address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize); 97.42 assert(end >= start, "sanity check"); 97.43 97.44 if (obj_p >= start && obj_p < end) { 97.45 @@ -2938,8 +2944,8 @@ 97.46 ClassFieldDescriptor* field = field_map->field_at(i); 97.47 char type = field->field_type(); 97.48 if (!is_primitive_field_type(type)) { 97.49 - oop fld_o = k->obj_field(field->field_offset()); 97.50 - assert(verify_static_oop(ik, k, field->field_offset()), "sanity check"); 97.51 + oop fld_o = mirror->obj_field(field->field_offset()); 97.52 + assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check"); 97.53 if (fld_o != NULL) { 97.54 int slot = field->field_index(); 97.55 if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) { 97.56 @@ -2949,7 +2955,7 @@ 97.57 } 97.58 } else { 97.59 if (is_reporting_primitive_fields()) { 97.60 - address addr = (address)k + field->field_offset(); 97.61 + address addr = (address)mirror + field->field_offset(); 97.62 int slot = field->field_index(); 97.63 if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) { 97.64 delete field_map;
98.1 --- a/src/share/vm/prims/unsafe.cpp Fri Mar 25 17:26:33 2011 -0700 98.2 +++ b/src/share/vm/prims/unsafe.cpp Fri Mar 25 18:04:45 2011 -0700 98.3 @@ -688,7 +688,7 @@ 98.4 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); 98.5 } 98.6 98.7 - return JNIHandles::make_local(env, java_lang_Class::as_klassOop(mirror)); 98.8 + return JNIHandles::make_local(env, mirror); 98.9 UNSAFE_END 98.10 98.11 //@deprecated 98.12 @@ -706,7 +706,7 @@ 98.13 if (clazz == NULL) { 98.14 THROW_0(vmSymbols::java_lang_NullPointerException()); 98.15 } 98.16 - return JNIHandles::make_local(env, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz))); 98.17 + return JNIHandles::make_local(env, JNIHandles::resolve_non_null(clazz)); 98.18 UNSAFE_END 98.19 98.20 UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized(JNIEnv *env, jobject unsafe, jobject clazz))
99.1 --- a/src/share/vm/runtime/arguments.cpp Fri Mar 25 17:26:33 2011 -0700 99.2 +++ b/src/share/vm/runtime/arguments.cpp Fri Mar 25 18:04:45 2011 -0700 99.3 @@ -2819,22 +2819,38 @@ 99.4 } 99.5 99.6 void Arguments::set_shared_spaces_flags() { 99.7 + const bool must_share = DumpSharedSpaces || RequireSharedSpaces; 99.8 + const bool might_share = must_share || UseSharedSpaces; 99.9 + 99.10 + // The string table is part of the shared archive so the size must match. 99.11 + if (!FLAG_IS_DEFAULT(StringTableSize)) { 99.12 + // Disable sharing. 99.13 + if (must_share) { 99.14 + warning("disabling shared archive %s because of non-default " 99.15 + "StringTableSize", DumpSharedSpaces ? "creation" : "use"); 99.16 + } 99.17 + if (might_share) { 99.18 + FLAG_SET_DEFAULT(DumpSharedSpaces, false); 99.19 + FLAG_SET_DEFAULT(RequireSharedSpaces, false); 99.20 + FLAG_SET_DEFAULT(UseSharedSpaces, false); 99.21 + } 99.22 + return; 99.23 + } 99.24 + 99.25 // Check whether class data sharing settings conflict with GC, compressed oops 99.26 // or page size, and fix them up. Explicit sharing options override other 99.27 // settings. 99.28 const bool cannot_share = UseConcMarkSweepGC || CMSIncrementalMode || 99.29 UseG1GC || UseParNewGC || UseParallelGC || UseParallelOldGC || 99.30 UseCompressedOops || UseLargePages && FLAG_IS_CMDLINE(UseLargePages); 99.31 - const bool must_share = DumpSharedSpaces || RequireSharedSpaces; 99.32 - const bool might_share = must_share || UseSharedSpaces; 99.33 if (cannot_share) { 99.34 if (must_share) { 99.35 - warning("selecting serial gc and disabling large pages %s" 99.36 - "because of %s", "" LP64_ONLY("and compressed oops "), 99.37 - DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on"); 99.38 - force_serial_gc(); 99.39 - FLAG_SET_CMDLINE(bool, UseLargePages, false); 99.40 - LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedOops, false)); 99.41 + warning("selecting serial gc and disabling large pages %s" 99.42 + "because of %s", "" LP64_ONLY("and compressed oops "), 99.43 + DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on"); 99.44 + force_serial_gc(); 99.45 + FLAG_SET_CMDLINE(bool, UseLargePages, false); 99.46 + LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedOops, false)); 99.47 } else { 99.48 if (UseSharedSpaces && Verbose) { 99.49 warning("turning off use of shared archive because of " 99.50 @@ -2976,6 +2992,12 @@ 99.51 } 99.52 ScavengeRootsInCode = 1; 99.53 } 99.54 + if (!JavaObjectsInPerm && ScavengeRootsInCode == 0) { 99.55 + if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) { 99.56 + warning("forcing ScavengeRootsInCode non-zero because JavaObjectsInPerm is false"); 99.57 + } 99.58 + ScavengeRootsInCode = 1; 99.59 + } 99.60 99.61 if (PrintGCDetails) { 99.62 // Turn on -verbose:gc options as well
100.1 --- a/src/share/vm/runtime/globals.hpp Fri Mar 25 17:26:33 2011 -0700 100.2 +++ b/src/share/vm/runtime/globals.hpp Fri Mar 25 18:04:45 2011 -0700 100.3 @@ -851,7 +851,7 @@ 100.4 diagnostic(bool, TraceNMethodInstalls, false, \ 100.5 "Trace nmethod intallation") \ 100.6 \ 100.7 - diagnostic(intx, ScavengeRootsInCode, 0, \ 100.8 + diagnostic(intx, ScavengeRootsInCode, 1, \ 100.9 "0: do not allow scavengable oops in the code cache; " \ 100.10 "1: allow scavenging from the code cache; " \ 100.11 "2: emit as many constants as the compiler can see") \ 100.12 @@ -1221,6 +1221,11 @@ 100.13 "Decay time (in milliseconds) to re-enable bulk rebiasing of a " \ 100.14 "type after previous bulk rebias") \ 100.15 \ 100.16 + develop(bool, JavaObjectsInPerm, false, \ 100.17 + "controls whether Classes and interned Strings are allocated" \ 100.18 + "in perm. This purely intended to allow debugging issues" \ 100.19 + "in production.") \ 100.20 + \ 100.21 /* tracing */ \ 100.22 \ 100.23 notproduct(bool, TraceRuntimeCalls, false, \ 100.24 @@ -3751,6 +3756,9 @@ 100.25 diagnostic(bool, PrintDTraceDOF, false, \ 100.26 "Print the DTrace DOF passed to the system for JSDT probes") \ 100.27 \ 100.28 + product(uintx, StringTableSize, 1009, \ 100.29 + "Number of buckets in the interned String table") \ 100.30 + \ 100.31 product(bool, UseVMInterruptibleIO, false, \ 100.32 "(Unstable, Solaris-specific) Thread interrupt before or with " \ 100.33 "EINTR for I/O operations results in OS_INTRPT. The default value"\
101.1 --- a/src/share/vm/runtime/os.cpp Fri Mar 25 17:26:33 2011 -0700 101.2 +++ b/src/share/vm/runtime/os.cpp Fri Mar 25 18:04:45 2011 -0700 101.3 @@ -1079,11 +1079,6 @@ 101.4 "%/lib/jsse.jar:" 101.5 "%/lib/jce.jar:" 101.6 "%/lib/charsets.jar:" 101.7 - 101.8 - // ## TEMPORARY hack to keep the legacy launcher working when 101.9 - // ## only the boot module is installed (cf. j.l.ClassLoader) 101.10 - "%/lib/modules/jdk.boot.jar:" 101.11 - 101.12 "%/classes"; 101.13 char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep); 101.14 if (sysclasspath == NULL) return false;
102.1 --- a/src/share/vm/runtime/osThread.hpp Fri Mar 25 17:26:33 2011 -0700 102.2 +++ b/src/share/vm/runtime/osThread.hpp Fri Mar 25 18:04:45 2011 -0700 102.3 @@ -1,5 +1,5 @@ 102.4 /* 102.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 102.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 102.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 102.8 * 102.9 * This code is free software; you can redistribute it and/or modify it 102.10 @@ -65,7 +65,7 @@ 102.11 OSThreadStartFunc _start_proc; // Thread start routine 102.12 void* _start_parm; // Thread start routine parameter 102.13 volatile ThreadState _state; // Thread state *hint* 102.14 - jint _interrupted; // Thread.isInterrupted state 102.15 + volatile jint _interrupted; // Thread.isInterrupted state 102.16 102.17 // Note: _interrupted must be jint, so that Java intrinsics can access it. 102.18 // The value stored there must be either 0 or 1. It must be possible 102.19 @@ -89,7 +89,7 @@ 102.20 void* start_parm() const { return _start_parm; } 102.21 void set_start_parm(void* start_parm) { _start_parm = start_parm; } 102.22 102.23 - bool interrupted() const { return _interrupted != 0; } 102.24 + volatile bool interrupted() const { return _interrupted != 0; } 102.25 void set_interrupted(bool z) { _interrupted = z ? 1 : 0; } 102.26 102.27 // Printing
103.1 --- a/src/share/vm/runtime/reflection.cpp Fri Mar 25 17:26:33 2011 -0700 103.2 +++ b/src/share/vm/runtime/reflection.cpp Fri Mar 25 18:04:45 2011 -0700 103.3 @@ -1,5 +1,5 @@ 103.4 /* 103.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 103.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 103.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 103.8 * 103.9 * This code is free software; you can redistribute it and/or modify it 103.10 @@ -649,7 +649,7 @@ 103.11 if (TraceClassResolution) { 103.12 trace_class_resolution(k); 103.13 } 103.14 - return k->klass_part()->java_mirror(); 103.15 + return k->java_mirror(); 103.16 }; 103.17 } 103.18
104.1 --- a/src/share/vm/runtime/thread.cpp Fri Mar 25 17:26:33 2011 -0700 104.2 +++ b/src/share/vm/runtime/thread.cpp Fri Mar 25 18:04:45 2011 -0700 104.3 @@ -3166,7 +3166,7 @@ 104.4 fieldDescriptor fd; 104.5 // Possible we might not find this field; if so, don't break 104.6 if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) { 104.7 - k()->bool_field_put(fd.offset(), true); 104.8 + k()->java_mirror()->bool_field_put(fd.offset(), true); 104.9 } 104.10 } 104.11 104.12 @@ -3182,7 +3182,7 @@ 104.13 fieldDescriptor fd; 104.14 // Possible we might not find this field: if so, silently don't break 104.15 if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) { 104.16 - k()->bool_field_put(fd.offset(), true); 104.17 + k()->java_mirror()->bool_field_put(fd.offset(), true); 104.18 } 104.19 } 104.20 }
105.1 --- a/src/share/vm/runtime/vmStructs.cpp Fri Mar 25 17:26:33 2011 -0700 105.2 +++ b/src/share/vm/runtime/vmStructs.cpp Fri Mar 25 18:04:45 2011 -0700 105.3 @@ -269,7 +269,7 @@ 105.4 nonstatic_field(instanceKlass, _inner_classes, typeArrayOop) \ 105.5 nonstatic_field(instanceKlass, _nonstatic_field_size, int) \ 105.6 nonstatic_field(instanceKlass, _static_field_size, int) \ 105.7 - nonstatic_field(instanceKlass, _static_oop_field_size, int) \ 105.8 + nonstatic_field(instanceKlass, _static_oop_field_count, int) \ 105.9 nonstatic_field(instanceKlass, _nonstatic_oop_map_size, int) \ 105.10 nonstatic_field(instanceKlass, _is_marked_dependent, bool) \ 105.11 nonstatic_field(instanceKlass, _minor_version, u2) \ 105.12 @@ -840,7 +840,7 @@ 105.13 /* OSThread */ \ 105.14 /************/ \ 105.15 \ 105.16 - nonstatic_field(OSThread, _interrupted, jint) \ 105.17 + volatile_nonstatic_field(OSThread, _interrupted, jint) \ 105.18 \ 105.19 /************************/ \ 105.20 /* OopMap and OopMapSet */ \ 105.21 @@ -945,6 +945,15 @@ 105.22 static_field(Arguments, _num_jvm_args, int) \ 105.23 static_field(Arguments, _java_command, char*) \ 105.24 \ 105.25 + /*********************************/ \ 105.26 + /* java_lang_Class fields */ \ 105.27 + /*********************************/ \ 105.28 + \ 105.29 + static_field(java_lang_Class, klass_offset, int) \ 105.30 + static_field(java_lang_Class, resolved_constructor_offset, int) \ 105.31 + static_field(java_lang_Class, array_klass_offset, int) \ 105.32 + static_field(java_lang_Class, oop_size_offset, int) \ 105.33 + static_field(java_lang_Class, static_oop_field_count_offset, int) \ 105.34 \ 105.35 /************************/ \ 105.36 /* Miscellaneous fields */ \ 105.37 @@ -1414,6 +1423,7 @@ 105.38 declare_toplevel_type(intptr_t*) \ 105.39 declare_unsigned_integer_type(InvocationCounter) /* FIXME: wrong type (not integer) */ \ 105.40 declare_toplevel_type(JavaThread*) \ 105.41 + declare_toplevel_type(java_lang_Class) \ 105.42 declare_toplevel_type(jbyte*) \ 105.43 declare_toplevel_type(jbyte**) \ 105.44 declare_toplevel_type(jint*) \ 105.45 @@ -1543,12 +1553,6 @@ 105.46 \ 105.47 declare_constant(SymbolTable::symbol_table_size) \ 105.48 \ 105.49 - /***************/ \ 105.50 - /* StringTable */ \ 105.51 - /***************/ \ 105.52 - \ 105.53 - declare_constant(StringTable::string_table_size) \ 105.54 - \ 105.55 /********************/ \ 105.56 /* SystemDictionary */ \ 105.57 /********************/ \ 105.58 @@ -1700,15 +1704,6 @@ 105.59 \ 105.60 declare_constant(ConstantPoolCacheEntry::tosBits) \ 105.61 \ 105.62 - /*********************************/ \ 105.63 - /* java_lang_Class field offsets */ \ 105.64 - /*********************************/ \ 105.65 - \ 105.66 - declare_constant(java_lang_Class::hc_klass_offset) \ 105.67 - declare_constant(java_lang_Class::hc_array_klass_offset) \ 105.68 - declare_constant(java_lang_Class::hc_resolved_constructor_offset) \ 105.69 - declare_constant(java_lang_Class::hc_number_of_fake_oop_fields) \ 105.70 - \ 105.71 /***************************************/ \ 105.72 /* java_lang_Thread::ThreadStatus enum */ \ 105.73 /***************************************/ \
106.1 --- a/src/share/vm/services/heapDumper.cpp Fri Mar 25 17:26:33 2011 -0700 106.2 +++ b/src/share/vm/services/heapDumper.cpp Fri Mar 25 18:04:45 2011 -0700 106.3 @@ -832,7 +832,7 @@ 106.4 106.5 // value 106.6 int offset = fld.offset(); 106.7 - address addr = (address)k + offset; 106.8 + address addr = (address)ikh->java_mirror() + offset; 106.9 106.10 dump_field_value(writer, sig->byte_at(0), addr); 106.11 }
107.1 --- a/src/share/vm/shark/sharkNativeWrapper.cpp Fri Mar 25 17:26:33 2011 -0700 107.2 +++ b/src/share/vm/shark/sharkNativeWrapper.cpp Fri Mar 25 18:04:45 2011 -0700 107.3 @@ -101,7 +101,7 @@ 107.4 builder()->CreateStore( 107.5 builder()->CreateInlineOop( 107.6 JNIHandles::make_local( 107.7 - target()->method_holder()->klass_part()->java_mirror())), 107.8 + target()->method_holder()->java_mirror())), 107.9 oop_tmp_slot()); 107.10 107.11 param_types.push_back(box_type);
108.1 --- a/test/compiler/6987555/Test6987555.java Fri Mar 25 17:26:33 2011 -0700 108.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 108.3 @@ -1,177 +0,0 @@ 108.4 -/* 108.5 - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. 108.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 108.7 - * 108.8 - * This code is free software; you can redistribute it and/or modify it 108.9 - * under the terms of the GNU General Public License version 2 only, as 108.10 - * published by the Free Software Foundation. 108.11 - * 108.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 108.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 108.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 108.15 - * version 2 for more details (a copy is included in the LICENSE file that 108.16 - * accompanied this code). 108.17 - * 108.18 - * You should have received a copy of the GNU General Public License version 108.19 - * 2 along with this work; if not, write to the Free Software Foundation, 108.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 108.21 - * 108.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 108.23 - * or visit www.oracle.com if you need additional information or have any 108.24 - * questions. 108.25 - * 108.26 - */ 108.27 - 108.28 -/** 108.29 - * @test 108.30 - * @bug 6987555 108.31 - * @summary JSR 292 unboxing to a boolean value fails on big-endian SPARC 108.32 - * 108.33 - * @run main/othervm -Xint -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6987555 108.34 - */ 108.35 - 108.36 -import java.dyn.*; 108.37 - 108.38 -public class Test6987555 { 108.39 - private static final Class CLASS = Test6987555.class; 108.40 - private static final String NAME = "foo"; 108.41 - private static final boolean DEBUG = false; 108.42 - 108.43 - public static void main(String[] args) throws Throwable { 108.44 - testboolean(); 108.45 - testbyte(); 108.46 - testchar(); 108.47 - testshort(); 108.48 - testint(); 108.49 - } 108.50 - 108.51 - // boolean 108.52 - static void testboolean() throws Throwable { 108.53 - doboolean(false); 108.54 - doboolean(true); 108.55 - } 108.56 - static void doboolean(boolean x) throws Throwable { 108.57 - if (DEBUG) System.out.println("boolean=" + x); 108.58 - MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(boolean.class, boolean.class)); 108.59 - MethodHandle mh2 = mh1.asType(MethodType.methodType(boolean.class, Boolean.class)); 108.60 - boolean a = (boolean) mh1.invokeExact(x); 108.61 - boolean b = (boolean) mh2.invokeExact(Boolean.valueOf(x)); 108.62 - assert a == b : a + " != " + b; 108.63 - } 108.64 - 108.65 - // byte 108.66 - static void testbyte() throws Throwable { 108.67 - byte[] a = new byte[] { 108.68 - Byte.MIN_VALUE, 108.69 - Byte.MIN_VALUE + 1, 108.70 - -0x0F, 108.71 - -1, 108.72 - 0, 108.73 - 1, 108.74 - 0x0F, 108.75 - Byte.MAX_VALUE - 1, 108.76 - Byte.MAX_VALUE 108.77 - }; 108.78 - for (int i = 0; i < a.length; i++) { 108.79 - dobyte(a[i]); 108.80 - } 108.81 - } 108.82 - static void dobyte(byte x) throws Throwable { 108.83 - if (DEBUG) System.out.println("byte=" + x); 108.84 - MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(byte.class, byte.class)); 108.85 - MethodHandle mh2 = mh1.asType(MethodType.methodType(byte.class, Byte.class)); 108.86 - byte a = (byte) mh1.invokeExact(x); 108.87 - byte b = (byte) mh2.invokeExact(Byte.valueOf(x)); 108.88 - assert a == b : a + " != " + b; 108.89 - } 108.90 - 108.91 - // char 108.92 - static void testchar() throws Throwable { 108.93 - char[] a = new char[] { 108.94 - Character.MIN_VALUE, 108.95 - Character.MIN_VALUE + 1, 108.96 - 0x000F, 108.97 - 0x00FF, 108.98 - 0x0FFF, 108.99 - Character.MAX_VALUE - 1, 108.100 - Character.MAX_VALUE 108.101 - }; 108.102 - for (int i = 0; i < a.length; i++) { 108.103 - dochar(a[i]); 108.104 - } 108.105 - } 108.106 - static void dochar(char x) throws Throwable { 108.107 - if (DEBUG) System.out.println("char=" + x); 108.108 - MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(char.class, char.class)); 108.109 - MethodHandle mh2 = mh1.asType(MethodType.methodType(char.class, Character.class)); 108.110 - char a = (char) mh1.invokeExact(x); 108.111 - char b = (char) mh2.invokeExact(Character.valueOf(x)); 108.112 - assert a == b : a + " != " + b; 108.113 - } 108.114 - 108.115 - // short 108.116 - static void testshort() throws Throwable { 108.117 - short[] a = new short[] { 108.118 - Short.MIN_VALUE, 108.119 - Short.MIN_VALUE + 1, 108.120 - -0x0FFF, 108.121 - -0x00FF, 108.122 - -0x000F, 108.123 - -1, 108.124 - 0, 108.125 - 1, 108.126 - 0x000F, 108.127 - 0x00FF, 108.128 - 0x0FFF, 108.129 - Short.MAX_VALUE - 1, 108.130 - Short.MAX_VALUE 108.131 - }; 108.132 - for (int i = 0; i < a.length; i++) { 108.133 - doshort(a[i]); 108.134 - } 108.135 - } 108.136 - static void doshort(short x) throws Throwable { 108.137 - if (DEBUG) System.out.println("short=" + x); 108.138 - MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(short.class, short.class)); 108.139 - MethodHandle mh2 = mh1.asType(MethodType.methodType(short.class, Short.class)); 108.140 - short a = (short) mh1.invokeExact(x); 108.141 - short b = (short) mh2.invokeExact(Short.valueOf(x)); 108.142 - assert a == b : a + " != " + b; 108.143 - } 108.144 - 108.145 - // int 108.146 - static void testint() throws Throwable { 108.147 - int[] a = new int[] { 108.148 - Integer.MIN_VALUE, 108.149 - Integer.MIN_VALUE + 1, 108.150 - -0x00000FFF, 108.151 - -0x000000FF, 108.152 - -0x0000000F, 108.153 - -1, 108.154 - 0, 108.155 - 1, 108.156 - 0x0000000F, 108.157 - 0x000000FF, 108.158 - 0x00000FFF, 108.159 - Integer.MAX_VALUE - 1, 108.160 - Integer.MAX_VALUE 108.161 - }; 108.162 - for (int i = 0; i < a.length; i++) { 108.163 - doint(a[i]); 108.164 - } 108.165 - } 108.166 - static void doint(int x) throws Throwable { 108.167 - if (DEBUG) System.out.println("int=" + x); 108.168 - MethodHandle mh1 = MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(int.class, int.class)); 108.169 - MethodHandle mh2 = mh1.asType(MethodType.methodType(int.class, Integer.class)); 108.170 - int a = (int) mh1.invokeExact(x); 108.171 - int b = (int) mh2.invokeExact(Integer.valueOf(x)); 108.172 - assert a == b : a + " != " + b; 108.173 - } 108.174 - 108.175 - public static boolean foo(boolean i) { return i; } 108.176 - public static byte foo(byte i) { return i; } 108.177 - public static char foo(char i) { return i; } 108.178 - public static short foo(short i) { return i; } 108.179 - public static int foo(int i) { return i; } 108.180 -}
109.1 --- a/test/compiler/6991596/Test6991596.java Fri Mar 25 17:26:33 2011 -0700 109.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 109.3 @@ -1,465 +0,0 @@ 109.4 -/* 109.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 109.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 109.7 - * 109.8 - * This code is free software; you can redistribute it and/or modify it 109.9 - * under the terms of the GNU General Public License version 2 only, as 109.10 - * published by the Free Software Foundation. 109.11 - * 109.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 109.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 109.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 109.15 - * version 2 for more details (a copy is included in the LICENSE file that 109.16 - * accompanied this code). 109.17 - * 109.18 - * You should have received a copy of the GNU General Public License version 109.19 - * 2 along with this work; if not, write to the Free Software Foundation, 109.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 109.21 - * 109.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 109.23 - * or visit www.oracle.com if you need additional information or have any 109.24 - * questions. 109.25 - * 109.26 - */ 109.27 - 109.28 -/** 109.29 - * @test 109.30 - * @bug 6991596 109.31 - * @summary JSR 292 unimplemented adapter_opt_i2i and adapter_opt_l2i on SPARC 109.32 - * 109.33 - * @run main/othervm -ea -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles -XX:+EnableInvokeDynamic -XX:+UnlockDiagnosticVMOptions -XX:+VerifyMethodHandles Test6991596 109.34 - */ 109.35 - 109.36 -import java.dyn.*; 109.37 - 109.38 -public class Test6991596 { 109.39 - private static final Class CLASS = Test6991596.class; 109.40 - private static final String NAME = "foo"; 109.41 - private static final boolean DEBUG = System.getProperty("DEBUG", "false").equals("true"); 109.42 - 109.43 - public static void main(String[] args) throws Throwable { 109.44 - testboolean(); 109.45 - testbyte(); 109.46 - testchar(); 109.47 - testshort(); 109.48 - testint(); 109.49 - testlong(); 109.50 - } 109.51 - 109.52 - // Helpers to get various methods. 109.53 - static MethodHandle getmh1(Class ret, Class arg) throws NoAccessException { 109.54 - return MethodHandles.lookup().findStatic(CLASS, NAME, MethodType.methodType(ret, arg)); 109.55 - } 109.56 - static MethodHandle getmh2(MethodHandle mh1, Class ret, Class arg) { 109.57 - return MethodHandles.convertArguments(mh1, MethodType.methodType(ret, arg)); 109.58 - } 109.59 - static MethodHandle getmh3(MethodHandle mh1, Class ret, Class arg) { 109.60 - return MethodHandles.convertArguments(mh1, MethodType.methodType(ret, arg)); 109.61 - } 109.62 - 109.63 - // test adapter_opt_i2i 109.64 - static void testboolean() throws Throwable { 109.65 - boolean[] a = new boolean[] { 109.66 - true, 109.67 - false 109.68 - }; 109.69 - for (int i = 0; i < a.length; i++) { 109.70 - doboolean(a[i]); 109.71 - } 109.72 - } 109.73 - static void doboolean(boolean x) throws Throwable { 109.74 - if (DEBUG) System.out.println("boolean=" + x); 109.75 - 109.76 - // boolean 109.77 - { 109.78 - MethodHandle mh1 = getmh1( boolean.class, boolean.class); 109.79 - MethodHandle mh2 = getmh2(mh1, boolean.class, boolean.class); 109.80 - // TODO add this for all cases when the bugs are fixed. 109.81 - //MethodHandle mh3 = getmh3(mh1, boolean.class, boolean.class); 109.82 - boolean a = (boolean) mh1.invokeExact((boolean) x); 109.83 - boolean b = (boolean) mh2.invokeExact(x); 109.84 - //boolean c = mh3.<boolean>invokeExact((boolean) x); 109.85 - check(x, a, b); 109.86 - //check(x, c, x); 109.87 - } 109.88 - 109.89 - // byte 109.90 - { 109.91 - MethodHandle mh1 = getmh1( byte.class, byte.class ); 109.92 - MethodHandle mh2 = getmh2(mh1, byte.class, boolean.class); 109.93 - byte a = (byte) mh1.invokeExact((byte) (x ? 1 : 0)); 109.94 - byte b = (byte) mh2.invokeExact(x); 109.95 - check(x, a, b); 109.96 - } 109.97 - 109.98 - // char 109.99 - { 109.100 - MethodHandle mh1 = getmh1( char.class, char.class); 109.101 - MethodHandle mh2 = getmh2(mh1, char.class, boolean.class); 109.102 - char a = (char) mh1.invokeExact((char) (x ? 1 : 0)); 109.103 - char b = (char) mh2.invokeExact(x); 109.104 - check(x, a, b); 109.105 - } 109.106 - 109.107 - // short 109.108 - { 109.109 - MethodHandle mh1 = getmh1( short.class, short.class); 109.110 - MethodHandle mh2 = getmh2(mh1, short.class, boolean.class); 109.111 - short a = (short) mh1.invokeExact((short) (x ? 1 : 0)); 109.112 - short b = (short) mh2.invokeExact(x); 109.113 - check(x, a, b); 109.114 - } 109.115 - } 109.116 - 109.117 - static void testbyte() throws Throwable { 109.118 - byte[] a = new byte[] { 109.119 - Byte.MIN_VALUE, 109.120 - Byte.MIN_VALUE + 1, 109.121 - -0x0F, 109.122 - -1, 109.123 - 0, 109.124 - 1, 109.125 - 0x0F, 109.126 - Byte.MAX_VALUE - 1, 109.127 - Byte.MAX_VALUE 109.128 - }; 109.129 - for (int i = 0; i < a.length; i++) { 109.130 - dobyte(a[i]); 109.131 - } 109.132 - } 109.133 - static void dobyte(byte x) throws Throwable { 109.134 - if (DEBUG) System.out.println("byte=" + x); 109.135 - 109.136 - // boolean 109.137 - { 109.138 - MethodHandle mh1 = getmh1( boolean.class, boolean.class); 109.139 - MethodHandle mh2 = getmh2(mh1, boolean.class, byte.class); 109.140 - boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 109.141 - boolean b = (boolean) mh2.invokeExact(x); 109.142 - check(x, a, b); 109.143 - } 109.144 - 109.145 - // byte 109.146 - { 109.147 - MethodHandle mh1 = getmh1( byte.class, byte.class); 109.148 - MethodHandle mh2 = getmh2(mh1, byte.class, byte.class); 109.149 - byte a = (byte) mh1.invokeExact((byte) x); 109.150 - byte b = (byte) mh2.invokeExact(x); 109.151 - check(x, a, b); 109.152 - } 109.153 - 109.154 - // char 109.155 - { 109.156 - MethodHandle mh1 = getmh1( char.class, char.class); 109.157 - MethodHandle mh2 = getmh2(mh1, char.class, byte.class); 109.158 - char a = (char) mh1.invokeExact((char) x); 109.159 - char b = (char) mh2.invokeExact(x); 109.160 - check(x, a, b); 109.161 - } 109.162 - 109.163 - // short 109.164 - { 109.165 - MethodHandle mh1 = getmh1( short.class, short.class); 109.166 - MethodHandle mh2 = getmh2(mh1, short.class, byte.class); 109.167 - short a = (short) mh1.invokeExact((short) x); 109.168 - short b = (short) mh2.invokeExact(x); 109.169 - check(x, a, b); 109.170 - } 109.171 - } 109.172 - 109.173 - static void testchar() throws Throwable { 109.174 - char[] a = new char[] { 109.175 - Character.MIN_VALUE, 109.176 - Character.MIN_VALUE + 1, 109.177 - 0x000F, 109.178 - 0x00FF, 109.179 - 0x0FFF, 109.180 - Character.MAX_VALUE - 1, 109.181 - Character.MAX_VALUE 109.182 - }; 109.183 - for (int i = 0; i < a.length; i++) { 109.184 - dochar(a[i]); 109.185 - } 109.186 - } 109.187 - static void dochar(char x) throws Throwable { 109.188 - if (DEBUG) System.out.println("char=" + x); 109.189 - 109.190 - // boolean 109.191 - { 109.192 - MethodHandle mh1 = getmh1( boolean.class, boolean.class); 109.193 - MethodHandle mh2 = getmh2(mh1, boolean.class, char.class); 109.194 - boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 109.195 - boolean b = (boolean) mh2.invokeExact(x); 109.196 - check(x, a, b); 109.197 - } 109.198 - 109.199 - // byte 109.200 - { 109.201 - MethodHandle mh1 = getmh1( byte.class, byte.class); 109.202 - MethodHandle mh2 = getmh2(mh1, byte.class, char.class); 109.203 - byte a = (byte) mh1.invokeExact((byte) x); 109.204 - byte b = (byte) mh2.invokeExact(x); 109.205 - check(x, a, b); 109.206 - } 109.207 - 109.208 - // char 109.209 - { 109.210 - MethodHandle mh1 = getmh1( char.class, char.class); 109.211 - MethodHandle mh2 = getmh2(mh1, char.class, char.class); 109.212 - char a = (char) mh1.invokeExact((char) x); 109.213 - char b = (char) mh2.invokeExact(x); 109.214 - check(x, a, b); 109.215 - } 109.216 - 109.217 - // short 109.218 - { 109.219 - MethodHandle mh1 = getmh1( short.class, short.class); 109.220 - MethodHandle mh2 = getmh2(mh1, short.class, char.class); 109.221 - short a = (short) mh1.invokeExact((short) x); 109.222 - short b = (short) mh2.invokeExact(x); 109.223 - check(x, a, b); 109.224 - } 109.225 - } 109.226 - 109.227 - static void testshort() throws Throwable { 109.228 - short[] a = new short[] { 109.229 - Short.MIN_VALUE, 109.230 - Short.MIN_VALUE + 1, 109.231 - -0x0FFF, 109.232 - -0x00FF, 109.233 - -0x000F, 109.234 - -1, 109.235 - 0, 109.236 - 1, 109.237 - 0x000F, 109.238 - 0x00FF, 109.239 - 0x0FFF, 109.240 - Short.MAX_VALUE - 1, 109.241 - Short.MAX_VALUE 109.242 - }; 109.243 - for (int i = 0; i < a.length; i++) { 109.244 - doshort(a[i]); 109.245 - } 109.246 - } 109.247 - static void doshort(short x) throws Throwable { 109.248 - if (DEBUG) System.out.println("short=" + x); 109.249 - 109.250 - // boolean 109.251 - { 109.252 - MethodHandle mh1 = getmh1( boolean.class, boolean.class); 109.253 - MethodHandle mh2 = getmh2(mh1, boolean.class, short.class); 109.254 - boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 109.255 - boolean b = (boolean) mh2.invokeExact(x); 109.256 - check(x, a, b); 109.257 - } 109.258 - 109.259 - // byte 109.260 - { 109.261 - MethodHandle mh1 = getmh1( byte.class, byte.class); 109.262 - MethodHandle mh2 = getmh2(mh1, byte.class, short.class); 109.263 - byte a = (byte) mh1.invokeExact((byte) x); 109.264 - byte b = (byte) mh2.invokeExact(x); 109.265 - check(x, a, b); 109.266 - } 109.267 - 109.268 - // char 109.269 - { 109.270 - MethodHandle mh1 = getmh1( char.class, char.class); 109.271 - MethodHandle mh2 = getmh2(mh1, char.class, short.class); 109.272 - char a = (char) mh1.invokeExact((char) x); 109.273 - char b = (char) mh2.invokeExact(x); 109.274 - check(x, a, b); 109.275 - } 109.276 - 109.277 - // short 109.278 - { 109.279 - MethodHandle mh1 = getmh1( short.class, short.class); 109.280 - MethodHandle mh2 = getmh2(mh1, short.class, short.class); 109.281 - short a = (short) mh1.invokeExact((short) x); 109.282 - short b = (short) mh2.invokeExact(x); 109.283 - check(x, a, b); 109.284 - } 109.285 - } 109.286 - 109.287 - static void testint() throws Throwable { 109.288 - int[] a = new int[] { 109.289 - Integer.MIN_VALUE, 109.290 - Integer.MIN_VALUE + 1, 109.291 - -0x0FFFFFFF, 109.292 - -0x00FFFFFF, 109.293 - -0x000FFFFF, 109.294 - -0x0000FFFF, 109.295 - -0x00000FFF, 109.296 - -0x000000FF, 109.297 - -0x0000000F, 109.298 - -1, 109.299 - 0, 109.300 - 1, 109.301 - 0x0000000F, 109.302 - 0x000000FF, 109.303 - 0x00000FFF, 109.304 - 0x0000FFFF, 109.305 - 0x000FFFFF, 109.306 - 0x00FFFFFF, 109.307 - 0x0FFFFFFF, 109.308 - Integer.MAX_VALUE - 1, 109.309 - Integer.MAX_VALUE 109.310 - }; 109.311 - for (int i = 0; i < a.length; i++) { 109.312 - doint(a[i]); 109.313 - } 109.314 - } 109.315 - static void doint(int x) throws Throwable { 109.316 - if (DEBUG) System.out.println("int=" + x); 109.317 - 109.318 - // boolean 109.319 - { 109.320 - MethodHandle mh1 = getmh1( boolean.class, boolean.class); 109.321 - MethodHandle mh2 = getmh2(mh1, boolean.class, int.class); 109.322 - boolean a = (boolean) mh1.invokeExact((x & 1) == 1); 109.323 - boolean b = (boolean) mh2.invokeExact(x); 109.324 - check(x, a, b); 109.325 - } 109.326 - 109.327 - // byte 109.328 - { 109.329 - MethodHandle mh1 = getmh1( byte.class, byte.class); 109.330 - MethodHandle mh2 = getmh2(mh1, byte.class, int.class); 109.331 - byte a = (byte) mh1.invokeExact((byte) x); 109.332 - byte b = (byte) mh2.invokeExact(x); 109.333 - check(x, a, b); 109.334 - } 109.335 - 109.336 - // char 109.337 - { 109.338 - MethodHandle mh1 = getmh1( char.class, char.class); 109.339 - MethodHandle mh2 = getmh2(mh1, char.class, int.class); 109.340 - char a = (char) mh1.invokeExact((char) x); 109.341 - char b = (char) mh2.invokeExact(x); 109.342 - check(x, a, b); 109.343 - } 109.344 - 109.345 - // short 109.346 - { 109.347 - MethodHandle mh1 = getmh1( short.class, short.class); 109.348 - MethodHandle mh2 = getmh2(mh1, short.class, int.class); 109.349 - short a = (short) mh1.invokeExact((short) x); 109.350 - short b = (short) mh2.invokeExact(x); 109.351 - assert a == b : a + " != " + b; 109.352 - check(x, a, b); 109.353 - } 109.354 - 109.355 - // int 109.356 - { 109.357 - MethodHandle mh1 = getmh1( int.class, int.class); 109.358 - MethodHandle mh2 = getmh2(mh1, int.class, int.class); 109.359 - int a = (int) mh1.invokeExact((int) x); 109.360 - int b = (int) mh2.invokeExact(x); 109.361 - check(x, a, b); 109.362 - } 109.363 - } 109.364 - 109.365 - // test adapter_opt_l2i 109.366 - static void testlong() throws Throwable { 109.367 - long[] a = new long[] { 109.368 - Long.MIN_VALUE, 109.369 - Long.MIN_VALUE + 1, 109.370 - -0x000000000FFFFFFFL, 109.371 - -0x0000000000FFFFFFL, 109.372 - -0x00000000000FFFFFL, 109.373 - -0x000000000000FFFFL, 109.374 - -0x0000000000000FFFL, 109.375 - -0x00000000000000FFL, 109.376 - -0x000000000000000FL, 109.377 - -1L, 109.378 - 0L, 109.379 - 1L, 109.380 - 0x000000000000000FL, 109.381 - 0x00000000000000FFL, 109.382 - 0x0000000000000FFFL, 109.383 - 0x0000000000000FFFL, 109.384 - 0x000000000000FFFFL, 109.385 - 0x00000000000FFFFFL, 109.386 - 0x0000000000FFFFFFL, 109.387 - 0x000000000FFFFFFFL, 109.388 - Long.MAX_VALUE - 1, 109.389 - Long.MAX_VALUE 109.390 - }; 109.391 - for (int i = 0; i < a.length; i++) { 109.392 - dolong(a[i]); 109.393 - } 109.394 - } 109.395 - static void dolong(long x) throws Throwable { 109.396 - if (DEBUG) System.out.println("long=" + x); 109.397 - 109.398 - // boolean 109.399 - { 109.400 - MethodHandle mh1 = getmh1( boolean.class, boolean.class); 109.401 - MethodHandle mh2 = getmh2(mh1, boolean.class, long.class); 109.402 - boolean a = (boolean) mh1.invokeExact((x & 1L) == 1L); 109.403 - boolean b = (boolean) mh2.invokeExact(x); 109.404 - check(x, a, b); 109.405 - } 109.406 - 109.407 - // byte 109.408 - { 109.409 - MethodHandle mh1 = getmh1( byte.class, byte.class); 109.410 - MethodHandle mh2 = getmh2(mh1, byte.class, long.class); 109.411 - byte a = (byte) mh1.invokeExact((byte) x); 109.412 - byte b = (byte) mh2.invokeExact(x); 109.413 - check(x, a, b); 109.414 - } 109.415 - 109.416 - // char 109.417 - { 109.418 - MethodHandle mh1 = getmh1( char.class, char.class); 109.419 - MethodHandle mh2 = getmh2(mh1, char.class, long.class); 109.420 - char a = (char) mh1.invokeExact((char) x); 109.421 - char b = (char) mh2.invokeExact(x); 109.422 - check(x, a, b); 109.423 - } 109.424 - 109.425 - // short 109.426 - { 109.427 - MethodHandle mh1 = getmh1( short.class, short.class); 109.428 - MethodHandle mh2 = getmh2(mh1, short.class, long.class); 109.429 - short a = (short) mh1.invokeExact((short) x); 109.430 - short b = (short) mh2.invokeExact(x); 109.431 - check(x, a, b); 109.432 - } 109.433 - 109.434 - // int 109.435 - { 109.436 - MethodHandle mh1 = getmh1( int.class, int.class); 109.437 - MethodHandle mh2 = getmh2(mh1, int.class, long.class); 109.438 - int a = (int) mh1.invokeExact((int) x); 109.439 - int b = (int) mh2.invokeExact(x); 109.440 - check(x, a, b); 109.441 - } 109.442 - } 109.443 - 109.444 - static void check(boolean x, boolean e, boolean a) { p(z2h(x), z2h(e), z2h(a)); assert e == a : z2h(x) + ": " + z2h(e) + " != " + z2h(a); } 109.445 - static void check(boolean x, byte e, byte a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } 109.446 - static void check(boolean x, int e, int a) { p(z2h(x), i2h(e), i2h(a)); assert e == a : z2h(x) + ": " + i2h(e) + " != " + i2h(a); } 109.447 - 109.448 - static void check(int x, boolean e, boolean a) { p(i2h(x), z2h(e), z2h(a)); assert e == a : i2h(x) + ": " + z2h(e) + " != " + z2h(a); } 109.449 - static void check(int x, byte e, byte a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } 109.450 - static void check(int x, int e, int a) { p(i2h(x), i2h(e), i2h(a)); assert e == a : i2h(x) + ": " + i2h(e) + " != " + i2h(a); } 109.451 - 109.452 - static void check(long x, boolean e, boolean a) { p(l2h(x), z2h(e), z2h(a)); assert e == a : l2h(x) + ": " + z2h(e) + " != " + z2h(a); } 109.453 - static void check(long x, byte e, byte a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } 109.454 - static void check(long x, int e, int a) { p(l2h(x), i2h(e), i2h(a)); assert e == a : l2h(x) + ": " + i2h(e) + " != " + i2h(a); } 109.455 - 109.456 - static void p(String x, String e, String a) { if (DEBUG) System.out.println(x + ": expected: " + e + ", actual: " + a); } 109.457 - 109.458 - static String z2h(boolean x) { return x ? "1" : "0"; } 109.459 - static String i2h(int x) { return Integer.toHexString(x); } 109.460 - static String l2h(long x) { return Long.toHexString(x); } 109.461 - 109.462 - // to int 109.463 - public static boolean foo(boolean i) { return i; } 109.464 - public static byte foo(byte i) { return i; } 109.465 - public static char foo(char i) { return i; } 109.466 - public static short foo(short i) { return i; } 109.467 - public static int foo(int i) { return i; } 109.468 -}