aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/java/lang
diff options
context:
space:
mode:
authorasaha <none@none>2014-12-17 12:50:15 -0800
committerasaha <none@none>2014-12-17 12:50:15 -0800
commitade4b6063b819e5ca021151c2c1fa7a04ffeae4c (patch)
treeee897640dcb54dcb68c45492eb4a796524ef7e20 /src/share/classes/java/lang
parent6fc7ab73925e66f64d0672506d562e7e972a3e16 (diff)
parentd47c11d9888f5b6645de45b2156b9ebab232ceac (diff)
downloadjdk8u_jdk-ade4b6063b819e5ca021151c2c1fa7a04ffeae4c.tar.gz
Merge
Diffstat (limited to 'src/share/classes/java/lang')
-rw-r--r--src/share/classes/java/lang/Class.java2
-rw-r--r--src/share/classes/java/lang/System.java5
-rw-r--r--src/share/classes/java/lang/invoke/LambdaForm.java2
-rw-r--r--src/share/classes/java/lang/invoke/LambdaFormBuffer.java15
-rw-r--r--src/share/classes/java/lang/invoke/LambdaFormEditor.java52
-rw-r--r--src/share/classes/java/lang/invoke/MethodHandles.java2
-rw-r--r--src/share/classes/java/lang/invoke/MethodTypeForm.java43
-rw-r--r--src/share/classes/java/lang/reflect/AccessibleObject.java7
8 files changed, 83 insertions, 45 deletions
diff --git a/src/share/classes/java/lang/Class.java b/src/share/classes/java/lang/Class.java
index 43c8c0e8ec..4c35cbce11 100644
--- a/src/share/classes/java/lang/Class.java
+++ b/src/share/classes/java/lang/Class.java
@@ -689,6 +689,8 @@ public final class Class<T> implements java.io.Serializable,
ClassLoader getClassLoader0() { return classLoader; }
// Initialized in JVM not by private constructor
+ // This field is filtered from reflection access, i.e. getDeclaredField
+ // will throw NoSuchFieldException
private final ClassLoader classLoader;
/**
diff --git a/src/share/classes/java/lang/System.java b/src/share/classes/java/lang/System.java
index 69d1d0fe1e..b2747fa7a4 100644
--- a/src/share/classes/java/lang/System.java
+++ b/src/share/classes/java/lang/System.java
@@ -584,7 +584,10 @@ public final class System {
* <tr><td><code>java.compiler</code></td>
* <td>Name of JIT compiler to use</td></tr>
* <tr><td><code>java.ext.dirs</code></td>
- * <td>Path of extension directory or directories</td></tr>
+ * <td>Path of extension directory or directories
+ * <b>Deprecated.</b> <i>This property, and the mechanism
+ * which implements it, may be removed in a future
+ * release.</i> </td></tr>
* <tr><td><code>os.name</code></td>
* <td>Operating system name</td></tr>
* <tr><td><code>os.arch</code></td>
diff --git a/src/share/classes/java/lang/invoke/LambdaForm.java b/src/share/classes/java/lang/invoke/LambdaForm.java
index e1791719c0..2129f8618b 100644
--- a/src/share/classes/java/lang/invoke/LambdaForm.java
+++ b/src/share/classes/java/lang/invoke/LambdaForm.java
@@ -125,7 +125,7 @@ class LambdaForm {
MemberName vmentry; // low-level behavior, or null if not yet prepared
private boolean isCompiled;
- Object transformCache; // managed by LambdaFormEditor
+ volatile Object transformCache; // managed by LambdaFormEditor
public static final int VOID_RESULT = -1, LAST_RESULT = -2;
diff --git a/src/share/classes/java/lang/invoke/LambdaFormBuffer.java b/src/share/classes/java/lang/invoke/LambdaFormBuffer.java
index 872a2a5992..cdc88be325 100644
--- a/src/share/classes/java/lang/invoke/LambdaFormBuffer.java
+++ b/src/share/classes/java/lang/invoke/LambdaFormBuffer.java
@@ -46,19 +46,16 @@ final class LambdaFormBuffer {
private static final int F_TRANS = 0x10, F_OWNED = 0x03;
LambdaFormBuffer(LambdaForm lf) {
- this(lf.arity, lf.names, lf.result);
+ this.arity = lf.arity;
+ setNames(lf.names);
+ int result = lf.result;
+ if (result == LAST_RESULT) result = length - 1;
+ if (result >= 0 && lf.names[result].type != V_TYPE)
+ resultName = lf.names[result];
debugName = lf.debugName;
assert(lf.nameRefsAreLegal());
}
- private LambdaFormBuffer(int arity, Name[] names, int result) {
- this.arity = arity;
- setNames(names);
- if (result == LAST_RESULT) result = length - 1;
- if (result >= 0 && names[result].type != V_TYPE)
- resultName = names[result];
- }
-
private LambdaForm lambdaForm() {
assert(!inTrans()); // need endEdit call to tidy things up
return new LambdaForm(debugName, arity, nameArray(), resultIndex());
diff --git a/src/share/classes/java/lang/invoke/LambdaFormEditor.java b/src/share/classes/java/lang/invoke/LambdaFormEditor.java
index 1c29d73b4c..1c23e94995 100644
--- a/src/share/classes/java/lang/invoke/LambdaFormEditor.java
+++ b/src/share/classes/java/lang/invoke/LambdaFormEditor.java
@@ -25,6 +25,7 @@
package java.lang.invoke;
+import java.lang.ref.SoftReference;
import java.util.Arrays;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.BasicType.*;
@@ -58,10 +59,9 @@ class LambdaFormEditor {
* The sequence is unterminated, ending with an indefinite number of zero bytes.
* Sequences that are simple (short enough and with small enough values) pack into a 64-bit long.
*/
- private static final class Transform {
+ private static final class Transform extends SoftReference<LambdaForm> {
final long packedBytes;
final byte[] fullBytes;
- final LambdaForm result; // result of transform, or null, if there is none available
private enum Kind {
NO_KIND, // necessary because ordinal must be greater than zero
@@ -140,9 +140,9 @@ class LambdaFormEditor {
Kind kind() { return Kind.values()[byteAt(0)]; }
private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) {
+ super(result);
this.packedBytes = packedBytes;
this.fullBytes = fullBytes;
- this.result = result;
}
private Transform(long packedBytes) {
this(packedBytes, null, null);
@@ -243,6 +243,7 @@ class LambdaFormEditor {
buf.append("unpacked");
buf.append(Arrays.toString(fullBytes));
}
+ LambdaForm result = get();
if (result != null) {
buf.append(" result=");
buf.append(result);
@@ -253,7 +254,7 @@ class LambdaFormEditor {
/** Find a previously cached transform equivalent to the given one, and return its result. */
private LambdaForm getInCache(Transform key) {
- assert(key.result == null);
+ assert(key.get() == null);
// The transformCache is one of null, Transform, Transform[], or ConcurrentHashMap.
Object c = lambdaForm.transformCache;
Transform k = null;
@@ -276,7 +277,7 @@ class LambdaFormEditor {
}
}
assert(k == null || key.equals(k));
- return k == null ? null : k.result;
+ return (k != null) ? k.get() : null;
}
/** Arbitrary but reasonable limits on Transform[] size for cache. */
@@ -293,7 +294,17 @@ class LambdaFormEditor {
@SuppressWarnings("unchecked")
ConcurrentHashMap<Transform,Transform> m = (ConcurrentHashMap<Transform,Transform>) c;
Transform k = m.putIfAbsent(key, key);
- return k != null ? k.result : form;
+ if (k == null) return form;
+ LambdaForm result = k.get();
+ if (result != null) {
+ return result;
+ } else {
+ if (m.replace(key, k, key)) {
+ return form;
+ } else {
+ continue;
+ }
+ }
}
assert(pass == 0);
synchronized (lambdaForm) {
@@ -308,17 +319,27 @@ class LambdaFormEditor {
if (c instanceof Transform) {
Transform k = (Transform)c;
if (k.equals(key)) {
- return k.result;
+ LambdaForm result = k.get();
+ if (result == null) {
+ lambdaForm.transformCache = key;
+ return form;
+ } else {
+ return result;
+ }
+ } else if (k.get() == null) { // overwrite stale entry
+ lambdaForm.transformCache = key;
+ return form;
}
// expand one-element cache to small array
ta = new Transform[MIN_CACHE_ARRAY_SIZE];
ta[0] = k;
- lambdaForm.transformCache = c = ta;
+ lambdaForm.transformCache = ta;
} else {
// it is already expanded
ta = (Transform[])c;
}
int len = ta.length;
+ int stale = -1;
int i;
for (i = 0; i < len; i++) {
Transform k = ta[i];
@@ -326,10 +347,18 @@ class LambdaFormEditor {
break;
}
if (k.equals(key)) {
- return k.result;
+ LambdaForm result = k.get();
+ if (result == null) {
+ ta[i] = key;
+ return form;
+ } else {
+ return result;
+ }
+ } else if (stale < 0 && k.get() == null) {
+ stale = i; // remember 1st stale entry index
}
}
- if (i < len) {
+ if (i < len || stale >= 0) {
// just fall through to cache update
} else if (len < MAX_CACHE_ARRAY_SIZE) {
len = Math.min(len * 2, MAX_CACHE_ARRAY_SIZE);
@@ -344,7 +373,8 @@ class LambdaFormEditor {
// The second iteration will update for this query, concurrently.
continue;
}
- ta[i] = key;
+ int idx = (stale >= 0) ? stale : i;
+ ta[idx] = key;
return form;
}
}
diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java
index 3c60a8c3c9..8511890481 100644
--- a/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -2029,7 +2029,7 @@ return invoker;
MethodType oldType = target.type();
if (oldType == newType) return target;
if (oldType.explicitCastEquivalentToAsType(newType)) {
- return target.asType(newType);
+ return target.asFixedArity().asType(newType);
}
return MethodHandleImpl.makePairwiseConvert(target, newType, false);
}
diff --git a/src/share/classes/java/lang/invoke/MethodTypeForm.java b/src/share/classes/java/lang/invoke/MethodTypeForm.java
index 6733e29ef9..bcf16dba9d 100644
--- a/src/share/classes/java/lang/invoke/MethodTypeForm.java
+++ b/src/share/classes/java/lang/invoke/MethodTypeForm.java
@@ -26,9 +26,8 @@
package java.lang.invoke;
import sun.invoke.util.Wrapper;
+import java.lang.ref.SoftReference;
import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
- import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
/**
* Shared information for a group of method types, which differ
@@ -51,7 +50,7 @@ final class MethodTypeForm {
final MethodType basicType; // the canonical erasure, with primitives simplified
// Cached adapter information:
- @Stable final MethodHandle[] methodHandles;
+ @Stable final SoftReference<MethodHandle>[] methodHandles;
// Indexes into methodHandles:
static final int
MH_BASIC_INV = 0, // cached instance of MH.invokeBasic
@@ -60,7 +59,7 @@ final class MethodTypeForm {
MH_LIMIT = 3;
// Cached lambda form information, for basic types only:
- final @Stable LambdaForm[] lambdaForms;
+ final @Stable SoftReference<LambdaForm>[] lambdaForms;
// Indexes into lambdaForms:
static final int
LF_INVVIRTUAL = 0, // DMH invokeVirtual
@@ -108,26 +107,40 @@ final class MethodTypeForm {
public MethodHandle cachedMethodHandle(int which) {
assert(assertIsBasicType());
- return methodHandles[which];
+ SoftReference<MethodHandle> entry = methodHandles[which];
+ return (entry != null) ? entry.get() : null;
}
synchronized public MethodHandle setCachedMethodHandle(int which, MethodHandle mh) {
// Simulate a CAS, to avoid racy duplication of results.
- MethodHandle prev = methodHandles[which];
- if (prev != null) return prev;
- return methodHandles[which] = mh;
+ SoftReference<MethodHandle> entry = methodHandles[which];
+ if (entry != null) {
+ MethodHandle prev = entry.get();
+ if (prev != null) {
+ return prev;
+ }
+ }
+ methodHandles[which] = new SoftReference<>(mh);
+ return mh;
}
public LambdaForm cachedLambdaForm(int which) {
assert(assertIsBasicType());
- return lambdaForms[which];
+ SoftReference<LambdaForm> entry = lambdaForms[which];
+ return (entry != null) ? entry.get() : null;
}
synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
// Simulate a CAS, to avoid racy duplication of results.
- LambdaForm prev = lambdaForms[which];
- if (prev != null) return prev;
- return lambdaForms[which] = form;
+ SoftReference<LambdaForm> entry = lambdaForms[which];
+ if (entry != null) {
+ LambdaForm prev = entry.get();
+ if (prev != null) {
+ return prev;
+ }
+ }
+ lambdaForms[which] = new SoftReference<>(form);
+ return form;
}
/**
@@ -135,6 +148,7 @@ final class MethodTypeForm {
* This MTF will stand for that type and all un-erased variations.
* Eagerly compute some basic properties of the type, common to all variations.
*/
+ @SuppressWarnings({"rawtypes", "unchecked"})
protected MethodTypeForm(MethodType erasedType) {
this.erasedType = erasedType;
@@ -234,8 +248,8 @@ final class MethodTypeForm {
// Initialize caches, but only for basic types
assert(basicType == erasedType);
- this.lambdaForms = new LambdaForm[LF_LIMIT];
- this.methodHandles = new MethodHandle[MH_LIMIT];
+ this.lambdaForms = new SoftReference[LF_LIMIT];
+ this.methodHandles = new SoftReference[MH_LIMIT];
}
private static long pack(int a, int b, int c, int d) {
@@ -409,5 +423,4 @@ final class MethodTypeForm {
public String toString() {
return "Form"+erasedType;
}
-
}
diff --git a/src/share/classes/java/lang/reflect/AccessibleObject.java b/src/share/classes/java/lang/reflect/AccessibleObject.java
index 0bf5e0eea4..45e051c454 100644
--- a/src/share/classes/java/lang/reflect/AccessibleObject.java
+++ b/src/share/classes/java/lang/reflect/AccessibleObject.java
@@ -140,13 +140,6 @@ public class AccessibleObject implements AnnotatedElement {
throw new SecurityException("Cannot make a java.lang.Class" +
" constructor accessible");
}
- } else if (obj instanceof Field && flag == true) {
- Field f = (Field)obj;
- if (f.getDeclaringClass() == Class.class &&
- f.getName().equals("classLoader")) {
- throw new SecurityException("Cannot make java.lang.Class.classLoader" +
- " accessible");
- }
}
obj.override = flag;
}