RFR: 5043030 (reflect) unnecessary object creation in reflection

Andrej Golovnin andrej.golovnin at gmail.com
Thu May 29 10:12:06 UTC 2014


Hi all,

as requested here are the diffs again as they were stripped last time.

Best regards,
Andrej Golovnin



On Wed, May 28, 2014 at 11:44 PM, Andrej Golovnin <andrej.golovnin at gmail.com
> wrote:

> Hi Joe,
>
> I have prepared a patch for the issue JDK-5043030.
> The patch consists of two parts: one for jdk and one for hotspot.
> You can find the webrevs here:
>
> JDK-patch: https://db.tt/7DYph0OH
> Hotspot-patch: https://db.tt/hHsN0yn4
>
> The JDK-patch has two tests to verify the changes.
>
> Please review it and I hope you can sponsor it.
>
> Best regards,
> Andrej Golovnin
>
>
-------------- next part --------------
diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp
--- a/src/share/vm/prims/jvm.cpp
+++ b/src/share/vm/prims/jvm.cpp
@@ -3995,15 +3995,6 @@
     objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));
     oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL);
     jobject res = JNIHandles::make_local(env, result);
-    if (JvmtiExport::should_post_vm_object_alloc()) {
-      oop ret_type = java_lang_reflect_Method::return_type(method_handle());
-      assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!");
-      if (java_lang_Class::is_primitive(ret_type)) {
-        // Only for primitive type vm allocates memory for java object.
-        // See box() method.
-        JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);
-      }
-    }
     return res;
   } else {
     THROW_0(vmSymbols::java_lang_StackOverflowError());
diff --git a/src/share/vm/runtime/reflection.cpp b/src/share/vm/runtime/reflection.cpp
--- a/src/share/vm/runtime/reflection.cpp
+++ b/src/share/vm/runtime/reflection.cpp
@@ -89,7 +89,63 @@
     // regular objects are not boxed
     return (oop) value->l;
   }
-  oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
+  JavaCallArguments args;
+  Klass* wrapper_klass;
+  Symbol* valueOf_signature;
+  switch (type) {
+    case T_BOOLEAN:
+      args.push_int(value->z);
+      wrapper_klass = SystemDictionary::Boolean_klass();
+      valueOf_signature = vmSymbols::Boolean_valueOf_signature();
+      break;
+    case T_CHAR:
+      args.push_int(value->c);
+      wrapper_klass = SystemDictionary::Character_klass();
+      valueOf_signature = vmSymbols::Character_valueOf_signature();
+      break;
+    case T_BYTE:
+      args.push_int(value->b);
+      wrapper_klass = SystemDictionary::Byte_klass();
+      valueOf_signature = vmSymbols::Byte_valueOf_signature();
+      break;
+    case T_SHORT:
+      args.push_int(value->s);
+      wrapper_klass = SystemDictionary::Short_klass();
+      valueOf_signature = vmSymbols::Short_valueOf_signature();
+      break;
+    case T_INT:
+      args.push_int(value->i);
+      wrapper_klass = SystemDictionary::Integer_klass();
+      valueOf_signature = vmSymbols::Integer_valueOf_signature();
+      break;
+    case T_LONG:
+      args.push_long(value->j);
+      wrapper_klass = SystemDictionary::Long_klass();
+      valueOf_signature = vmSymbols::Long_valueOf_signature();
+      break;
+    case T_FLOAT:
+      args.push_float(value->f);
+      wrapper_klass = SystemDictionary::Float_klass();
+      valueOf_signature = vmSymbols::Float_valueOf_signature();
+      break;
+    case T_DOUBLE:
+      args.push_double(value->d);
+      wrapper_klass = SystemDictionary::Double_klass();
+      valueOf_signature = vmSymbols::Double_valueOf_signature();
+      break;
+    default:
+      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch");
+  }
+  instanceKlassHandle klass_handle(THREAD, wrapper_klass);
+  JavaValue boxed_value(T_OBJECT);
+  JavaCalls::call_static(&boxed_value,
+                         klass_handle,
+                         vmSymbols::valueOf_name(),
+                         valueOf_signature,
+                         &args,
+                         THREAD);
+  
+  oop result = (oop) boxed_value.get_jobject();
   if (result == NULL) {
     THROW_(vmSymbols::java_lang_IllegalArgumentException(), result);
   }
-------------- next part --------------
diff --git a/src/share/classes/sun/reflect/AccessorGenerator.java b/src/share/classes/sun/reflect/AccessorGenerator.java
--- a/src/share/classes/sun/reflect/AccessorGenerator.java
+++ b/src/share/classes/sun/reflect/AccessorGenerator.java
@@ -69,33 +69,34 @@
     protected short codeIdx;
     protected short exceptionsIdx;
     // Boxing
+    protected short valueOfIdx;
     protected short booleanIdx;
-    protected short booleanCtorIdx;
+    protected short booleanBoxIdx;
     protected short booleanUnboxIdx;
     protected short byteIdx;
-    protected short byteCtorIdx;
+    protected short byteBoxIdx;
     protected short byteUnboxIdx;
     protected short characterIdx;
-    protected short characterCtorIdx;
+    protected short characterBoxIdx;
     protected short characterUnboxIdx;
     protected short doubleIdx;
-    protected short doubleCtorIdx;
+    protected short doubleBoxIdx;
     protected short doubleUnboxIdx;
     protected short floatIdx;
-    protected short floatCtorIdx;
+    protected short floatBoxIdx;
     protected short floatUnboxIdx;
     protected short integerIdx;
-    protected short integerCtorIdx;
+    protected short integerBoxIdx;
     protected short integerUnboxIdx;
     protected short longIdx;
-    protected short longCtorIdx;
+    protected short longBoxIdx;
     protected short longUnboxIdx;
     protected short shortIdx;
-    protected short shortCtorIdx;
+    protected short shortBoxIdx;
     protected short shortUnboxIdx;
 
     protected final short NUM_COMMON_CPOOL_ENTRIES = (short) 30;
-    protected final short NUM_BOXING_CPOOL_ENTRIES = (short) 72;
+    protected final short NUM_BOXING_CPOOL_ENTRIES = (short) 73;
 
     // Requires that superClass has been set up
     protected void emitCommonConstantPoolEntries() {
@@ -181,9 +182,10 @@
     /** Constant pool entries required to be able to box/unbox primitive
         types. Note that we don't emit these if we don't need them. */
     protected void emitBoxingContantPoolEntries() {
+        //  *  [UTF-8] "valueOf"
         //  *  [UTF-8] "java/lang/Boolean"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(Z)V"
+        //  *  [UTF-8] "(Z)Ljava/lang/Boolean;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "booleanValue"
@@ -192,7 +194,7 @@
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "java/lang/Byte"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(B)V"
+        //  *  [UTF-8] "(B)Ljava/lang/Byte;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "byteValue"
@@ -201,7 +203,7 @@
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "java/lang/Character"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(C)V"
+        //  *  [UTF-8] "(C)Ljava/lang/Character;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "charValue"
@@ -210,7 +212,7 @@
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "java/lang/Double"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(D)V"
+        //  *  [UTF-8] "(D)Ljava/lang/Double;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "doubleValue"
@@ -219,7 +221,7 @@
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "java/lang/Float"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(F)V"
+        //  *  [UTF-8] "(F)Ljava/lang/Float;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "floatValue"
@@ -228,7 +230,7 @@
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "java/lang/Integer"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(I)V"
+        //  *  [UTF-8] "(I)Ljava/lang/Integer;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "intValue"
@@ -237,7 +239,7 @@
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "java/lang/Long"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(J)V"
+        //  *  [UTF-8] "(J)Ljava/lang/Long;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "longValue"
@@ -246,21 +248,26 @@
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "java/lang/Short"
         //  *  [CONSTANT_Class_info] for above
-        //  *  [UTF-8] "(S)V"
+        //  *  [UTF-8] "(S)Ljava/lang/Short;"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
         //  *  [UTF-8] "shortValue"
         //  *  [UTF-8] "()S"
         //  *  [CONSTANT_NameAndType_info] for above
         //  *  [CONSTANT_Methodref_info] for above
+
+        // valueOf-method name
+        asm.emitConstantPoolUTF8("valueOf");
+        valueOfIdx = asm.cpi();
+
         // Boolean
         asm.emitConstantPoolUTF8("java/lang/Boolean");
         asm.emitConstantPoolClass(asm.cpi());
         booleanIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(Z)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(Z)Ljava/lang/Boolean;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        booleanCtorIdx = asm.cpi();
+        booleanBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("booleanValue");
         asm.emitConstantPoolUTF8("()Z");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -271,10 +278,10 @@
         asm.emitConstantPoolUTF8("java/lang/Byte");
         asm.emitConstantPoolClass(asm.cpi());
         byteIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(B)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(B)Ljava/lang/Byte;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        byteCtorIdx = asm.cpi();
+        byteBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("byteValue");
         asm.emitConstantPoolUTF8("()B");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -285,10 +292,10 @@
         asm.emitConstantPoolUTF8("java/lang/Character");
         asm.emitConstantPoolClass(asm.cpi());
         characterIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(C)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(C)Ljava/lang/Character;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        characterCtorIdx = asm.cpi();
+        characterBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("charValue");
         asm.emitConstantPoolUTF8("()C");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -299,10 +306,10 @@
         asm.emitConstantPoolUTF8("java/lang/Double");
         asm.emitConstantPoolClass(asm.cpi());
         doubleIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(D)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(D)Ljava/lang/Double;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        doubleCtorIdx = asm.cpi();
+        doubleBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("doubleValue");
         asm.emitConstantPoolUTF8("()D");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -313,10 +320,10 @@
         asm.emitConstantPoolUTF8("java/lang/Float");
         asm.emitConstantPoolClass(asm.cpi());
         floatIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(F)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(F)Ljava/lang/Float;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        floatCtorIdx = asm.cpi();
+        floatBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("floatValue");
         asm.emitConstantPoolUTF8("()F");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -327,10 +334,10 @@
         asm.emitConstantPoolUTF8("java/lang/Integer");
         asm.emitConstantPoolClass(asm.cpi());
         integerIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(I)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(I)Ljava/lang/Integer;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        integerCtorIdx = asm.cpi();
+        integerBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("intValue");
         asm.emitConstantPoolUTF8("()I");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -341,10 +348,10 @@
         asm.emitConstantPoolUTF8("java/lang/Long");
         asm.emitConstantPoolClass(asm.cpi());
         longIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(J)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(J)Ljava/lang/Long;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        longCtorIdx = asm.cpi();
+        longBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("longValue");
         asm.emitConstantPoolUTF8("()J");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -355,10 +362,10 @@
         asm.emitConstantPoolUTF8("java/lang/Short");
         asm.emitConstantPoolClass(asm.cpi());
         shortIdx = asm.cpi();
-        asm.emitConstantPoolUTF8("(S)V");
-        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
+        asm.emitConstantPoolUTF8("(S)Ljava/lang/Short;");
+        asm.emitConstantPoolNameAndType(valueOfIdx, asm.cpi());
         asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
-        shortCtorIdx = asm.cpi();
+        shortBoxIdx = asm.cpi();
         asm.emitConstantPoolUTF8("shortValue");
         asm.emitConstantPoolUTF8("()S");
         asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
@@ -515,23 +522,23 @@
         throw new InternalError("Should have found primitive type");
     }
 
-    protected short ctorIndexForPrimitiveType(Class<?> type) {
+    protected short boxingMethodForPrimitiveType(Class<?> type) {
         if (type == Boolean.TYPE) {
-            return booleanCtorIdx;
+            return booleanBoxIdx;
         } else if (type == Byte.TYPE) {
-            return byteCtorIdx;
+            return byteBoxIdx;
         } else if (type == Character.TYPE) {
-            return characterCtorIdx;
+            return characterBoxIdx;
         } else if (type == Double.TYPE) {
-            return doubleCtorIdx;
+            return doubleBoxIdx;
         } else if (type == Float.TYPE) {
-            return floatCtorIdx;
+            return floatBoxIdx;
         } else if (type == Integer.TYPE) {
-            return integerCtorIdx;
+            return integerBoxIdx;
         } else if (type == Long.TYPE) {
-            return longCtorIdx;
+            return longBoxIdx;
         } else if (type == Short.TYPE) {
-            return shortCtorIdx;
+            return shortBoxIdx;
         }
         throw new InternalError("Should have found primitive type");
     }
diff --git a/src/share/classes/sun/reflect/MethodAccessorGenerator.java b/src/share/classes/sun/reflect/MethodAccessorGenerator.java
--- a/src/share/classes/sun/reflect/MethodAccessorGenerator.java
+++ b/src/share/classes/sun/reflect/MethodAccessorGenerator.java
@@ -660,9 +660,9 @@
         if (!isConstructor) {
             // Box return value if necessary
             if (isPrimitive(returnType)) {
-                cb.opc_invokespecial(ctorIndexForPrimitiveType(returnType),
-                                     typeSizeInStackSlots(returnType),
-                                     0);
+                cb.opc_invokestatic(boxingMethodForPrimitiveType(returnType),
+                                    typeSizeInStackSlots(returnType),
+                                    0);
             } else if (returnType == Void.TYPE) {
                 cb.opc_aconst_null();
             }
diff --git a/src/share/classes/sun/reflect/UnsafeBooleanFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeBooleanFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeBooleanFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeBooleanFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Boolean(getBoolean(obj));
+        return Boolean.valueOf(getBoolean(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeByteFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeByteFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeByteFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeByteFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Byte(getByte(obj));
+        return Byte.valueOf(getByte(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeCharacterFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeCharacterFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeCharacterFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeCharacterFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Character(getChar(obj));
+        return Character.valueOf(getChar(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeDoubleFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeDoubleFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeDoubleFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeDoubleFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Double(getDouble(obj));
+        return Double.valueOf(getDouble(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeFloatFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeFloatFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeFloatFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeFloatFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Float(getFloat(obj));
+        return Float.valueOf(getFloat(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeIntegerFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeIntegerFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeIntegerFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeIntegerFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Integer(getInt(obj));
+        return Integer.valueOf(getInt(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeLongFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeLongFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeLongFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeLongFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Long(getLong(obj));
+        return Long.valueOf(getLong(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedBooleanFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedBooleanFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedBooleanFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedBooleanFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Boolean(getBoolean(obj));
+        return Boolean.valueOf(getBoolean(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedByteFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedByteFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedByteFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedByteFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Byte(getByte(obj));
+        return Byte.valueOf(getByte(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedCharacterFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedCharacterFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedCharacterFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedCharacterFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Character(getChar(obj));
+        return Character.valueOf(getChar(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedDoubleFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedDoubleFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedDoubleFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedDoubleFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Double(getDouble(obj));
+        return Double.valueOf(getDouble(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedFloatFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedFloatFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedFloatFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedFloatFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Float(getFloat(obj));
+        return Float.valueOf(getFloat(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedIntegerFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedIntegerFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedIntegerFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedIntegerFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Integer(getInt(obj));
+        return Integer.valueOf(getInt(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedLongFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedLongFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedLongFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedLongFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Long(getLong(obj));
+        return Long.valueOf(getLong(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedShortFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedShortFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedShortFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedShortFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Short(getShort(obj));
+        return Short.valueOf(getShort(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticBooleanFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticBooleanFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticBooleanFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticBooleanFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Boolean(getBoolean(obj));
+        return Boolean.valueOf(getBoolean(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticByteFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticByteFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticByteFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticByteFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Byte(getByte(obj));
+        return Byte.valueOf(getByte(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticCharacterFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticCharacterFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticCharacterFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticCharacterFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Character(getChar(obj));
+        return Character.valueOf(getChar(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticDoubleFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticDoubleFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticDoubleFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticDoubleFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Double(getDouble(obj));
+        return Double.valueOf(getDouble(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticFloatFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticFloatFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticFloatFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticFloatFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Float(getFloat(obj));
+        return Float.valueOf(getFloat(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticIntegerFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticIntegerFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticIntegerFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticIntegerFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Integer(getInt(obj));
+        return Integer.valueOf(getInt(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticLongFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticLongFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticLongFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticLongFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Long(getLong(obj));
+        return Long.valueOf(getLong(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeQualifiedStaticShortFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeQualifiedStaticShortFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeQualifiedStaticShortFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeQualifiedStaticShortFieldAccessorImpl.java
@@ -35,7 +35,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Short(getShort(obj));
+        return Short.valueOf(getShort(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeShortFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeShortFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeShortFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeShortFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Short(getShort(obj));
+        return Short.valueOf(getShort(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticBooleanFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticBooleanFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticBooleanFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticBooleanFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Boolean(getBoolean(obj));
+        return Boolean.valueOf(getBoolean(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticByteFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticByteFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticByteFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticByteFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Byte(getByte(obj));
+        return Byte.valueOf(getByte(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticCharacterFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticCharacterFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticCharacterFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticCharacterFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Character(getChar(obj));
+        return Character.valueOf(getChar(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticDoubleFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticDoubleFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticDoubleFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticDoubleFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Double(getDouble(obj));
+        return Double.valueOf(getDouble(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticFloatFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticFloatFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticFloatFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticFloatFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Float(getFloat(obj));
+        return Float.valueOf(getFloat(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticIntegerFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticIntegerFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticIntegerFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticIntegerFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Integer(getInt(obj));
+        return Integer.valueOf(getInt(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticLongFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticLongFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticLongFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticLongFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Long(getLong(obj));
+        return Long.valueOf(getLong(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/src/share/classes/sun/reflect/UnsafeStaticShortFieldAccessorImpl.java b/src/share/classes/sun/reflect/UnsafeStaticShortFieldAccessorImpl.java
--- a/src/share/classes/sun/reflect/UnsafeStaticShortFieldAccessorImpl.java
+++ b/src/share/classes/sun/reflect/UnsafeStaticShortFieldAccessorImpl.java
@@ -33,7 +33,7 @@
     }
 
     public Object get(Object obj) throws IllegalArgumentException {
-        return new Short(getShort(obj));
+        return Short.valueOf(getShort(obj));
     }
 
     public boolean getBoolean(Object obj) throws IllegalArgumentException {
diff --git a/test/java/lang/reflect/Field/TestFieldReflectValueOf.java b/test/java/lang/reflect/Field/TestFieldReflectValueOf.java
new file mode 100644
--- /dev/null
+++ b/test/java/lang/reflect/Field/TestFieldReflectValueOf.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5043030
+ * @summary The language requires caching wrapper instances for well defined
+ *          ranges, e.g. Integers in the range -128 to 127.
+ * @author Andrej Golovnin
+ */
+
+import java.lang.reflect.Field;
+
+public class TestFieldReflectValueOf {
+
+    @SuppressWarnings("unused")
+    private static boolean booleanStaticField;
+    @SuppressWarnings("unused")
+    private static byte byteStaticField;
+    @SuppressWarnings("unused")
+    private static char charStaticField;
+    @SuppressWarnings("unused")
+    private static int intStaticField;
+    @SuppressWarnings("unused")
+    private static long longStaticField;
+    @SuppressWarnings("unused")
+    private static short shortStaticField;
+
+    @SuppressWarnings("unused")
+    private static volatile boolean booleanStaticVolatileField;
+    @SuppressWarnings("unused")
+    private static volatile byte byteStaticVolatileField;
+    @SuppressWarnings("unused")
+    private static volatile char charStaticVolatileField;
+    @SuppressWarnings("unused")
+    private static volatile int intStaticVolatileField;
+    @SuppressWarnings("unused")
+    private static volatile long longStaticVolatileField;
+    @SuppressWarnings("unused")
+    private static volatile short shortStaticVolatileField;
+
+    @SuppressWarnings("unused")
+    private boolean booleanField;
+    @SuppressWarnings("unused")
+    private byte byteField;
+    @SuppressWarnings("unused")
+    private char charField;
+    @SuppressWarnings("unused")
+    private int intField;
+    @SuppressWarnings("unused")
+    private long longField;
+    @SuppressWarnings("unused")
+    private short shortField;
+
+    @SuppressWarnings("unused")
+    private volatile boolean booleanVolatileField;
+    @SuppressWarnings("unused")
+    private volatile byte byteVolatileField;
+    @SuppressWarnings("unused")
+    private volatile char charVolatileField;
+    @SuppressWarnings("unused")
+    private volatile int intVolatileField;
+    @SuppressWarnings("unused")
+    private volatile long longVolatileField;
+    @SuppressWarnings("unused")
+    private volatile short shortVolatileField;
+
+    public static void main(String[] args) {
+        testUnsafeStaticFieldAccessors();
+        testUnsafeQualifiedStaticFieldAccessors();
+        testUnsafeFieldAccessors();
+        testUnsafeQualifiedFieldAccessors();
+    }
+
+    private static void testUnsafeStaticFieldAccessors() {
+        testFieldAccessors(true, false);
+    }
+
+    private static void testUnsafeQualifiedStaticFieldAccessors() {
+        testFieldAccessors(true, true);
+    }
+
+    private static void testUnsafeFieldAccessors() {
+        testFieldAccessors(false, false);
+    }
+
+    private static void testUnsafeQualifiedFieldAccessors() {
+        testFieldAccessors(false, true);
+    }
+
+    private static void testFieldAccessors(boolean checkStatic,
+        boolean checkVolatile)
+    {
+        // Boolean#valueOf test
+        testField(Boolean.TYPE, Boolean.FALSE, checkStatic, checkVolatile);
+        testField(Boolean.TYPE, Boolean.TRUE, checkStatic, checkVolatile);
+
+        // Byte#valueOf test
+        for (int b = Byte.MIN_VALUE; b < (Byte.MAX_VALUE + 1); b++) {
+            testField(Byte.TYPE, Byte.valueOf((byte) b), checkStatic, checkVolatile);
+        }
+
+        // Character#valueOf test
+        for (char c = '\u0000'; c <= '\u007F'; c++) {
+            testField(Character.TYPE, Character.valueOf(c), checkStatic, checkVolatile);
+        }
+
+        // Integer#valueOf test
+        for (int i = -128; i <= 127; i++) {
+            testField(Integer.TYPE, Integer.valueOf(i), checkStatic, checkVolatile);
+        }
+
+        // Long#valueOf test
+        for (long l = -128L; l <= 127L; l++) {
+            testField(Long.TYPE, Long.valueOf(l), checkStatic, checkVolatile);
+        }
+
+        // Short#valueOf test
+        for (short s = -128; s <= 127; s++) {
+            testField(Short.TYPE, Short.valueOf(s), checkStatic, checkVolatile);
+        }
+    }
+
+    private static void testField(Class<?> primType, Object wrappedValue,
+        boolean checkStatic, boolean checkVolatile)
+    {
+        String fieldName = primType.getName();
+        if (checkStatic) {
+            fieldName += "Static";
+        }
+        if (checkVolatile) {
+            fieldName += "Volatile";
+        }
+        fieldName += "Field";
+        try {
+            Field field = TestFieldReflectValueOf.class.getDeclaredField(fieldName);
+            field.setAccessible(true);
+            TestFieldReflectValueOf obj = new TestFieldReflectValueOf();
+            field.set(obj, wrappedValue);
+            Object result = field.get(obj);
+            if (result != wrappedValue) {
+                throw new RuntimeException("Value " + wrappedValue
+                    + " is not cached for type " + primType);
+            }
+        } catch (  NoSuchFieldException | SecurityException
+                 | IllegalAccessException | IllegalArgumentException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/test/java/lang/reflect/Method/invoke/TestMethodReflectValueOf.java b/test/java/lang/reflect/Method/invoke/TestMethodReflectValueOf.java
new file mode 100644
--- /dev/null
+++ b/test/java/lang/reflect/Method/invoke/TestMethodReflectValueOf.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5043030
+ * @summary The language requires caching wrapper instances for well defined
+ *          ranges, e.g. Integers in the range -128 to 127.
+ * @author Andrej Golovnin
+ * @run main/othervm -Dsun.reflect.noInflation=true TestMethodReflectValueOf
+ * @run main/othervm -Dsun.reflect.noInflation=false -Dsun.reflect.inflationThreshold=500 TestMethodReflectValueOf
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+
+public class TestMethodReflectValueOf {
+
+    public static void main(String[] args) {
+        // Boolean#valueOf test
+        testMethod(Boolean.TYPE, Boolean.FALSE);
+        testMethod(Boolean.TYPE, Boolean.TRUE);
+
+        // Byte#valueOf test
+        for (int b = Byte.MIN_VALUE; b < (Byte.MAX_VALUE + 1); b++) {
+            testMethod(Byte.TYPE, Byte.valueOf((byte) b));
+        }
+
+        // Character#valueOf test
+        for (char c = '\u0000'; c <= '\u007F'; c++) {
+            testMethod(Character.TYPE, Character.valueOf(c));
+        }
+
+        // Integer#valueOf test
+        for (int i = -128; i <= 127; i++) {
+            testMethod(Integer.TYPE, Integer.valueOf(i));
+        }
+
+        // Long#valueOf test
+        for (long l = -128L; l <= 127L; l++) {
+            testMethod(Long.TYPE, Long.valueOf(l));
+        }
+
+        // Short#valueOf test
+        for (short s = -128; s <= 127; s++) {
+            testMethod(Short.TYPE, Short.valueOf(s));
+        }
+    }
+
+    public static void testMethod(Class<?> primType, Object wrappedValue) {
+        String methodName = primType.getName() + "Method";
+        try {
+            Method method = TestMethodReflectValueOf.class.getMethod(methodName, primType);
+            Object result = method.invoke(new TestMethodReflectValueOf(), wrappedValue);
+            if (result != wrappedValue) {
+                throw new RuntimeException("Value " + wrappedValue
+                    + " is not cached for type " + primType);
+            }
+        } catch (  NoSuchMethodException | SecurityException
+                 | IllegalAccessException | IllegalArgumentException
+                 | InvocationTargetException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public int intMethod(int value) {
+        return value;
+    }
+
+    public long longMethod(long value) {
+        return value;
+    }
+
+    public short shortMethod(short value) {
+        return value;
+    }
+
+    public byte byteMethod(byte value) {
+        return value;
+    }
+
+    public char charMethod(char value) {
+        return value;
+    }
+
+    public boolean booleanMethod(boolean value) {
+        return value;
+    }
+
+}


More information about the core-libs-dev mailing list