8179769: serviceability/sa/TestCpoolForInvokeDynamic.java failing after changes for JDK-8171392
authoriklam
Thu, 11 May 2017 16:17:31 -0700
changeset 46460 d25a320cd821
parent 46459 7d4e637d3f21
child 46461 7155d5ff2d07
8179769: serviceability/sa/TestCpoolForInvokeDynamic.java failing after changes for JDK-8171392 Summary: Updated SA Java code to match HotSpot C code. Reviewed-by: sspitsyn, coleenp
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
hotspot/src/share/vm/runtime/vmStructs.cpp
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Fri May 12 13:56:13 2017 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Thu May 11 16:17:31 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -121,14 +121,7 @@
     // decide based on the oop type.
     ConstantPool cpool = method().getConstants();
     int cpIndex = poolIndex();
-    ConstantPool.CPSlot oop = cpool.getSlotAt(cpIndex);
-    if (oop.isResolved()) {
-      return oop.getKlass();
-    } else if (oop.isUnresolved()) {
-      return oop.getSymbol();
-    } else {
-       throw new RuntimeException("should not reach here");
-    }
+    return cpool.getKlassNameAt(cpIndex);
   }
 
   public static BytecodeLoadConstant at(Method method, int bci) {
@@ -171,12 +164,12 @@
        // tag change from 'unresolved' to 'klass' does not happen atomically.
        // We just look at the object at the corresponding index and
        // decide based on the oop type.
-       ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
-       if (obj.isResolved()) {
-         Klass k = obj.getKlass();
+       ConstantTag tag = cpool.getTagAt(cpIndex);
+       if (tag.isKlass()) {
+         Klass k = cpool.getKlassAt(cpIndex);
          return "<Class " + k.getName().asString() + "@" + k.getAddress() + ">";
-       } else if (obj.isUnresolved()) {
-         Symbol sym = obj.getSymbol();
+       } else if (tag.isUnresolvedKlass()) {
+         Symbol sym = cpool.getKlassNameAt(cpIndex);
          return "<Class " + sym.asString() + ">";
        } else {
           throw new RuntimeException("should not reach here");
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java	Fri May 12 13:56:13 2017 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithKlass.java	Thu May 11 16:17:31 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,12 +37,7 @@
   }
 
   public Symbol getClassName() {
-    ConstantPool.CPSlot obj = method().getConstants().getSlotAt(index());
-    if (obj.isUnresolved()) {
-      return obj.getSymbol();
-    } else {
-      return obj.getKlass().getName();
-    }
+    return method().getConstants().getKlassNameAt(index());
   }
 
   public String toString() {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Fri May 12 13:56:13 2017 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Thu May 11 16:17:31 2017 -0700
@@ -35,30 +35,35 @@
 // as described in the class file
 
 public class ConstantPool extends Metadata implements ClassConstants {
-  public class CPSlot {
+  private class CPSlot {
     private Address ptr;
 
     CPSlot(Address ptr) {
       this.ptr = ptr;
     }
-    CPSlot(Symbol sym) {
-      this.ptr = sym.getAddress().orWithMask(1);
-    }
-
-    public boolean isResolved() {
-      return (ptr.minus(null) & 1) == 0;
-    }
-    public boolean isUnresolved() {
-      return (ptr.minus(null) & 1) == 1;
-    }
 
     public Symbol getSymbol() {
-      if (!isUnresolved()) throw new InternalError("not a symbol");
-        return Symbol.create(ptr.xorWithMask(1));
+      // (Lowest bit == 1) -> this is an pseudo string.
+      return Symbol.create(ptr.andWithMask(~1));
+    }
+  }
+  private class CPKlassSlot {
+    private int name_index;
+    private int resolved_klass_index;
+    private static final int temp_resolved_klass_index = 0xffff;
+
+    public CPKlassSlot(int n, int rk) {
+      name_index = n;
+      resolved_klass_index = rk;
+    }
+    public int getNameIndex() {
+      return name_index;
+    }
+    public int getResolvedKlassIndex() {
+      if (Assert.ASSERTS_ENABLED) {
+        Assert.that(resolved_klass_index != temp_resolved_klass_index, "constant pool merging was incomplete");
       }
-    public Klass getKlass() {
-      if (!isResolved()) throw new InternalError("not klass");
-      return (Klass)Metadata.instantiateWrapperFor(ptr);
+      return resolved_klass_index;
     }
   }
 
@@ -84,6 +89,7 @@
     cache       = type.getAddressField("_cache");
     poolHolder  = new MetadataField(type.getAddressField("_pool_holder"), 0);
     length      = new CIntField(type.getCIntegerField("_length"), 0);
+    resolved_klasses = type.getAddressField("_resolved_klasses");
     headerSize  = type.getSize();
     elementSize = 0;
     // fetch constants:
@@ -101,6 +107,7 @@
   private static AddressField tags;
   private static AddressField operands;
   private static AddressField cache;
+  private static AddressField resolved_klasses;
   private static MetadataField poolHolder;
   private static CIntField length; // number of elements in oop
 
@@ -122,6 +129,9 @@
   public Oop               getResolvedReferences() {
     return getCache().getResolvedReferences();
   }
+  public KlassArray        getResolvedKlasses() {
+    return new KlassArray(resolved_klasses.getValue(getAddress()));
+  }
 
   public U2Array referenceMap() {
     return getCache().referenceMap();
@@ -155,6 +165,16 @@
     return new CPSlot(getAddressAtRaw(index));
   }
 
+  public CPKlassSlot getKlassSlotAt(long index) {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(getTagAt(index).isUnresolvedKlass() || getTagAt(index).isKlass(), "Corrupted constant pool");
+    }
+    int value = getIntAt(index);
+    int name_index = extractHighShortFromInt(value);
+    int resolved_klass_index = extractLowShortFromInt(value);
+    return new CPKlassSlot(name_index, resolved_klass_index);
+  }
+
   public Address getAddressAtRaw(long index) {
     return getAddress().getAddressAt(indexOffset(index));
   }
@@ -305,16 +325,14 @@
   // returns null, if not resolved.
   public Klass getKlassAt(int which) {
     if( ! getTagAt(which).isKlass()) return null;
-    return (Klass)Metadata.instantiateWrapperFor(getAddressAtRaw(which));
+    int resolved_klass_index = getKlassSlotAt(which).getResolvedKlassIndex();
+    KlassArray resolved_klasses = getResolvedKlasses();
+    return resolved_klasses.getAt(resolved_klass_index);
   }
 
   public Symbol getKlassNameAt(int which) {
-    CPSlot entry = getSlotAt(which);
-    if (entry.isResolved()) {
-      return entry.getKlass().getName();
-    } else {
-      return entry.getSymbol();
-    }
+    int name_index = getKlassSlotAt(which).getNameIndex();
+    return getSymbolAt(name_index);
   }
 
   public Symbol getUnresolvedStringAt(int which) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Fri May 12 13:56:13 2017 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu May 11 16:17:31 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -516,15 +516,7 @@
           if (ioff != 0) {
              // only look at classes that are already loaded
              // since we are looking for the flags for our self.
-             ConstantPool.CPSlot classInfo = getConstants().getSlotAt(ioff);
-             Symbol name = null;
-             if (classInfo.isResolved()) {
-               name = classInfo.getKlass().getName();
-             } else if (classInfo.isUnresolved()) {
-               name = classInfo.getSymbol();
-             } else {
-                throw new RuntimeException("should not reach here");
-             }
+             Symbol name = getConstants().getKlassNameAt(ioff);
 
              if (name.equals(getName())) {
                 // This is really a member class
@@ -571,7 +563,6 @@
          // 'ioff' can be zero.
          // refer to JVM spec. section 4.7.5.
          if (ioff != 0) {
-            ConstantPool.CPSlot iclassInfo = getConstants().getSlotAt(ioff);
             Symbol innerName = getConstants().getKlassNameAt(ioff);
             Symbol myname = getName();
             int ooff = innerClassList.at(i +
@@ -592,15 +583,7 @@
                   }
                }
             } else {
-               ConstantPool.CPSlot oclassInfo = getConstants().getSlotAt(ooff);
-               Symbol outerName = null;
-               if (oclassInfo.isResolved()) {
-                 outerName = oclassInfo.getKlass().getName();
-               } else if (oclassInfo.isUnresolved()) {
-                 outerName = oclassInfo.getSymbol();
-               } else {
-                  throw new RuntimeException("should not reach here");
-               }
+               Symbol outerName = getConstants().getKlassNameAt(ooff);
 
                // include only if current class is outer class.
                if (outerName.equals(myname) && innerName.equals(sym)) {
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Fri May 12 13:56:13 2017 -0700
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu May 11 16:17:31 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -630,11 +630,12 @@
             buf.beginTag("ul");
             for (int exp = 0; exp < exceptions.length; exp++) {
                short cpIndex = (short) exceptions[exp].getClassCPIndex();
-               ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
-               if (obj.isUnresolved()) {
-                 buf.li((obj.getSymbol()).asString().replace('/', '.'));
+               ConstantTag tag = cpool.getTagAt(cpIndex);
+               if (tag.isUnresolvedKlass()) {
+                 buf.li(cpool.getKlassNameAt(cpIndex).asString().replace('/', '.'));
                } else {
-                 buf.li(genKlassLink((InstanceKlass)obj.getKlass()));
+                 Klass k = cpool.getKlassAt(cpIndex);
+                 buf.li(genKlassLink((InstanceKlass)k));
                }
             }
             buf.endTag("ul");
@@ -766,13 +767,14 @@
                   buf.cell(Integer.toString(exceptionTable[e].getEndPC()));
                   buf.cell(Integer.toString(exceptionTable[e].getHandlerPC()));
                   short cpIndex = (short) exceptionTable[e].getCatchTypeIndex();
-                  ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
-                  if (obj == null) {
-                     buf.cell("Any");
-                  } else if (obj.isUnresolved()) {
-                     buf.cell(obj.getSymbol().asString().replace('/', '.'));
+                  ConstantTag tag = cpIndex == 0? null : cpool.getTagAt(cpIndex);
+                  if (tag == null) {
+                    buf.cell("Any");
+                  } else if (tag.isUnresolvedKlass()) {
+                    buf.cell(cpool.getKlassNameAt(cpIndex).asString().replace('/', '.'));
                   } else {
-                    buf.cell(genKlassLink((InstanceKlass)obj.getKlass()));
+                    Klass k = cpool.getKlassAt(cpIndex);
+                    buf.cell(genKlassLink((InstanceKlass)k));
                   }
                   buf.endTag("tr");
                }
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Fri May 12 13:56:13 2017 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu May 11 16:17:31 2017 -0700
@@ -237,6 +237,7 @@
   nonstatic_field(ConstantPool,                _cache,                                        ConstantPoolCache*)                    \
   nonstatic_field(ConstantPool,                _pool_holder,                                  InstanceKlass*)                        \
   nonstatic_field(ConstantPool,                _operands,                                     Array<u2>*)                            \
+  nonstatic_field(ConstantPool,                _resolved_klasses,                             Array<Klass*>*)                        \
   nonstatic_field(ConstantPool,                _length,                                       int)                                   \
   nonstatic_field(ConstantPoolCache,           _resolved_references,                          jobject)                               \
   nonstatic_field(ConstantPoolCache,           _reference_map,                                Array<u2>*)                            \