8074022: Serialization should issue a freeze action after reconstituting a graph that contains objects with final fields
Reviewed-by: dholmes, plevart, psandoz
This commit is contained in:
parent
90a23fca14
commit
dc378de91b
@ -40,6 +40,7 @@ import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import static java.io.ObjectStreamClass.processQueue;
|
||||
import sun.misc.Unsafe;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
@ -375,6 +376,7 @@ public class ObjectInputStream
|
||||
}
|
||||
if (depth == 0) {
|
||||
vlist.doCallbacks();
|
||||
freeze();
|
||||
}
|
||||
return obj;
|
||||
} finally {
|
||||
@ -465,6 +467,7 @@ public class ObjectInputStream
|
||||
}
|
||||
if (depth == 0) {
|
||||
vlist.doCallbacks();
|
||||
freeze();
|
||||
}
|
||||
return obj;
|
||||
} finally {
|
||||
@ -2357,6 +2360,26 @@ public class ObjectInputStream
|
||||
}
|
||||
}
|
||||
|
||||
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||
|
||||
/**
|
||||
* Performs a "freeze" action, required to adhere to final field semantics.
|
||||
*
|
||||
* <p> This method can be called unconditionally before returning the graph,
|
||||
* from the topmost readObject call, since it is expected that the
|
||||
* additional cost of the freeze action is negligible compared to
|
||||
* reconstituting even the most simple graph.
|
||||
*
|
||||
* <p> Nested calls to readObject do not issue freeze actions because the
|
||||
* sub-graph returned from a nested call is not guaranteed to be fully
|
||||
* initialized yet (possible cycles).
|
||||
*/
|
||||
private void freeze() {
|
||||
// Issue a StoreStore|StoreLoad fence, which is at least sufficient
|
||||
// to provide final-freeze semantics.
|
||||
UNSAFE.storeFence();
|
||||
}
|
||||
|
||||
/**
|
||||
* Input stream with two modes: in default mode, inputs data written in the
|
||||
* same format as DataOutputStream; in "block data" mode, inputs data
|
||||
|
@ -3740,8 +3740,8 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
throw new ExceptionInInitializerError(ex);
|
||||
}
|
||||
}
|
||||
static void setIntCompactVolatile(BigDecimal bd, long val) {
|
||||
unsafe.putLongVolatile(bd, intCompactOffset, val);
|
||||
static void setIntCompact(BigDecimal bd, long val) {
|
||||
unsafe.putLong(bd, intCompactOffset, val);
|
||||
}
|
||||
|
||||
static void setIntValVolatile(BigDecimal bd, BigInteger val) {
|
||||
@ -3765,7 +3765,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
throw new java.io.StreamCorruptedException(message);
|
||||
// [all values of scale are now allowed]
|
||||
}
|
||||
UnsafeHolder.setIntCompactVolatile(this, compactValFor(intVal));
|
||||
UnsafeHolder.setIntCompact(this, compactValFor(intVal));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4368,11 +4368,11 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
}
|
||||
|
||||
static void putSign(BigInteger bi, int sign) {
|
||||
unsafe.putIntVolatile(bi, signumOffset, sign);
|
||||
unsafe.putInt(bi, signumOffset, sign);
|
||||
}
|
||||
|
||||
static void putMag(BigInteger bi, int[] magnitude) {
|
||||
unsafe.putObjectVolatile(bi, magOffset, magnitude);
|
||||
unsafe.putObject(bi, magOffset, magnitude);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user