Skip to content

Commit bd14274

Browse files
author
Roger Riggs
committed
8256480: Refactor ObjectInputStream field reader implementation
Reviewed-by: bchristi
1 parent 1c4c99e commit bd14274

File tree

1 file changed

+81
-129
lines changed

1 file changed

+81
-129
lines changed

src/java.base/share/classes/java/io/ObjectInputStream.java

Lines changed: 81 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -653,10 +653,12 @@ public void defaultReadObject()
653653
Object curObj = ctx.getObj();
654654
ObjectStreamClass curDesc = ctx.getDesc();
655655
bin.setBlockDataMode(false);
656-
FieldValues vals = defaultReadFields(curObj, curDesc);
656+
657+
// Read fields of the current descriptor into a new FieldValues
658+
FieldValues values = new FieldValues(curDesc, true);
657659
if (curObj != null) {
658-
defaultCheckFieldValues(curObj, curDesc, vals);
659-
defaultSetFieldValues(curObj, curDesc, vals);
660+
values.defaultCheckFieldValues(curObj);
661+
values.defaultSetFieldValues(curObj);
660662
}
661663
bin.setBlockDataMode(true);
662664
if (!curDesc.hasWriteObjectData()) {
@@ -696,8 +698,8 @@ public ObjectInputStream.GetField readFields()
696698
ctx.checkAndSetUsed();
697699
ObjectStreamClass curDesc = ctx.getDesc();
698700
bin.setBlockDataMode(false);
699-
GetFieldImpl getField = new GetFieldImpl(curDesc);
700-
getField.readFields();
701+
// Read fields of the current descriptor into a new FieldValues
702+
FieldValues values = new FieldValues(curDesc, false);
701703
bin.setBlockDataMode(true);
702704
if (!curDesc.hasWriteObjectData()) {
703705
/*
@@ -707,8 +709,7 @@ public ObjectInputStream.GetField readFields()
707709
*/
708710
defaultDataEnd = true;
709711
}
710-
711-
return getField;
712+
return values;
712713
}
713714

714715
/**
@@ -2322,14 +2323,13 @@ private Object readRecord(ObjectStreamClass desc) throws IOException {
23222323
if (slots.length != 1) {
23232324
// skip any superclass stream field values
23242325
for (int i = 0; i < slots.length-1; i++) {
2325-
ObjectStreamClass slotDesc = slots[i].desc;
23262326
if (slots[i].hasData) {
2327-
defaultReadFields(null, slotDesc);
2327+
new FieldValues(slots[i].desc, true);
23282328
}
23292329
}
23302330
}
23312331

2332-
FieldValues fieldValues = defaultReadFields(null, desc);
2332+
FieldValues fieldValues = new FieldValues(desc, true);
23332333

23342334
// get canonical record constructor adapted to take two arguments:
23352335
// - byte[] primValues
@@ -2388,7 +2388,8 @@ private void readSerialData(Object obj, ObjectStreamClass desc)
23882388

23892389
if (slots[i].hasData) {
23902390
if (obj == null || handles.lookupException(passHandle) != null) {
2391-
defaultReadFields(null, slotDesc); // skip field values
2391+
// Read fields of the current descriptor into a new FieldValues and discard
2392+
new FieldValues(slotDesc, true);
23922393
} else if (slotDesc.hasReadObjectMethod()) {
23932394
ThreadDeath t = null;
23942395
boolean reset = false;
@@ -2432,12 +2433,13 @@ private void readSerialData(Object obj, ObjectStreamClass desc)
24322433
*/
24332434
defaultDataEnd = false;
24342435
} else {
2435-
FieldValues vals = defaultReadFields(obj, slotDesc);
2436+
// Read fields of the current descriptor into a new FieldValues
2437+
FieldValues values = new FieldValues(slotDesc, true);
24362438
if (slotValues != null) {
2437-
slotValues[i] = vals;
2439+
slotValues[i] = values;
24382440
} else if (obj != null) {
2439-
defaultCheckFieldValues(obj, slotDesc, vals);
2440-
defaultSetFieldValues(obj, slotDesc, vals);
2441+
values.defaultCheckFieldValues(obj);
2442+
values.defaultSetFieldValues(obj);
24412443
}
24422444
}
24432445

@@ -2461,11 +2463,11 @@ private void readSerialData(Object obj, ObjectStreamClass desc)
24612463
// before assigning.
24622464
for (int i = 0; i < slots.length; i++) {
24632465
if (slotValues[i] != null)
2464-
defaultCheckFieldValues(obj, slots[i].desc, slotValues[i]);
2466+
slotValues[i].defaultCheckFieldValues(obj);
24652467
}
24662468
for (int i = 0; i < slots.length; i++) {
24672469
if (slotValues[i] != null)
2468-
defaultSetFieldValues(obj, slots[i].desc, slotValues[i]);
2470+
slotValues[i].defaultSetFieldValues(obj);
24692471
}
24702472
}
24712473
}
@@ -2499,76 +2501,6 @@ private void skipCustomData() throws IOException {
24992501
}
25002502
}
25012503

2502-
/*package-private*/ class FieldValues {
2503-
final byte[] primValues;
2504-
final Object[] objValues;
2505-
2506-
FieldValues(byte[] primValues, Object[] objValues) {
2507-
this.primValues = primValues;
2508-
this.objValues = objValues;
2509-
}
2510-
}
2511-
2512-
/**
2513-
* Reads in values of serializable fields declared by given class
2514-
* descriptor. Expects that passHandle is set to obj's handle before this
2515-
* method is called.
2516-
*/
2517-
private FieldValues defaultReadFields(Object obj, ObjectStreamClass desc)
2518-
throws IOException
2519-
{
2520-
Class<?> cl = desc.forClass();
2521-
if (cl != null && obj != null && !cl.isInstance(obj)) {
2522-
throw new ClassCastException();
2523-
}
2524-
2525-
byte[] primVals = null;
2526-
int primDataSize = desc.getPrimDataSize();
2527-
if (primDataSize > 0) {
2528-
primVals = new byte[primDataSize];
2529-
bin.readFully(primVals, 0, primDataSize, false);
2530-
}
2531-
2532-
Object[] objVals = null;
2533-
int numObjFields = desc.getNumObjFields();
2534-
if (numObjFields > 0) {
2535-
int objHandle = passHandle;
2536-
ObjectStreamField[] fields = desc.getFields(false);
2537-
objVals = new Object[numObjFields];
2538-
int numPrimFields = fields.length - objVals.length;
2539-
for (int i = 0; i < objVals.length; i++) {
2540-
ObjectStreamField f = fields[numPrimFields + i];
2541-
objVals[i] = readObject0(Object.class, f.isUnshared());
2542-
if (f.getField() != null) {
2543-
handles.markDependency(objHandle, passHandle);
2544-
}
2545-
}
2546-
passHandle = objHandle;
2547-
}
2548-
2549-
return new FieldValues(primVals, objVals);
2550-
}
2551-
2552-
/** Throws ClassCastException if any value is not assignable. */
2553-
private void defaultCheckFieldValues(Object obj, ObjectStreamClass desc,
2554-
FieldValues values) {
2555-
Object[] objectValues = values.objValues;
2556-
if (objectValues != null)
2557-
desc.checkObjFieldValueTypes(obj, objectValues);
2558-
}
2559-
2560-
/** Sets field values in obj. */
2561-
private void defaultSetFieldValues(Object obj, ObjectStreamClass desc,
2562-
FieldValues values) {
2563-
byte[] primValues = values.primValues;
2564-
Object[] objectValues = values.objValues;
2565-
2566-
if (primValues != null)
2567-
desc.setPrimFieldValues(obj, primValues);
2568-
if (objectValues != null)
2569-
desc.setObjFieldValues(obj, objectValues);
2570-
}
2571-
25722504
/**
25732505
* Reads in and returns IOException that caused serialization to abort.
25742506
* All stream state is discarded prior to reading in fatal exception. Sets
@@ -2608,103 +2540,123 @@ private static ClassLoader latestUserDefinedLoader() {
26082540
/**
26092541
* Default GetField implementation.
26102542
*/
2611-
private class GetFieldImpl extends GetField {
2543+
private final class FieldValues extends GetField {
26122544

26132545
/** class descriptor describing serializable fields */
26142546
private final ObjectStreamClass desc;
26152547
/** primitive field values */
2616-
private final byte[] primVals;
2548+
final byte[] primValues;
26172549
/** object field values */
2618-
private final Object[] objVals;
2550+
final Object[] objValues;
26192551
/** object field value handles */
26202552
private final int[] objHandles;
26212553

26222554
/**
2623-
* Creates GetFieldImpl object for reading fields defined in given
2555+
* Creates FieldValues object for reading fields defined in given
26242556
* class descriptor.
2557+
* @param desc the ObjectStreamClass to read
2558+
* @param recordDependencies if true, record the dependencies
2559+
* from current PassHandle and the object's read.
26252560
*/
2626-
GetFieldImpl(ObjectStreamClass desc) {
2561+
FieldValues(ObjectStreamClass desc, boolean recordDependencies) throws IOException {
26272562
this.desc = desc;
2628-
primVals = new byte[desc.getPrimDataSize()];
2629-
objVals = new Object[desc.getNumObjFields()];
2630-
objHandles = new int[objVals.length];
2563+
2564+
int primDataSize = desc.getPrimDataSize();
2565+
primValues = (primDataSize > 0) ? new byte[primDataSize] : null;
2566+
if (primDataSize > 0) {
2567+
bin.readFully(primValues, 0, primDataSize, false);
2568+
}
2569+
2570+
int numObjFields = desc.getNumObjFields();
2571+
objValues = (numObjFields > 0) ? new Object[numObjFields] : null;
2572+
objHandles = (numObjFields > 0) ? new int[numObjFields] : null;
2573+
if (numObjFields > 0) {
2574+
int objHandle = passHandle;
2575+
ObjectStreamField[] fields = desc.getFields(false);
2576+
int numPrimFields = fields.length - objValues.length;
2577+
for (int i = 0; i < objValues.length; i++) {
2578+
ObjectStreamField f = fields[numPrimFields + i];
2579+
objValues[i] = readObject0(Object.class, f.isUnshared());
2580+
objHandles[i] = passHandle;
2581+
if (recordDependencies && f.getField() != null) {
2582+
handles.markDependency(objHandle, passHandle);
2583+
}
2584+
}
2585+
passHandle = objHandle;
2586+
}
26312587
}
26322588

26332589
public ObjectStreamClass getObjectStreamClass() {
26342590
return desc;
26352591
}
26362592

2637-
public boolean defaulted(String name) throws IOException {
2593+
public boolean defaulted(String name) {
26382594
return (getFieldOffset(name, null) < 0);
26392595
}
26402596

2641-
public boolean get(String name, boolean val) throws IOException {
2597+
public boolean get(String name, boolean val) {
26422598
int off = getFieldOffset(name, Boolean.TYPE);
2643-
return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
2599+
return (off >= 0) ? Bits.getBoolean(primValues, off) : val;
26442600
}
26452601

2646-
public byte get(String name, byte val) throws IOException {
2602+
public byte get(String name, byte val) {
26472603
int off = getFieldOffset(name, Byte.TYPE);
2648-
return (off >= 0) ? primVals[off] : val;
2604+
return (off >= 0) ? primValues[off] : val;
26492605
}
26502606

2651-
public char get(String name, char val) throws IOException {
2607+
public char get(String name, char val) {
26522608
int off = getFieldOffset(name, Character.TYPE);
2653-
return (off >= 0) ? Bits.getChar(primVals, off) : val;
2609+
return (off >= 0) ? Bits.getChar(primValues, off) : val;
26542610
}
26552611

2656-
public short get(String name, short val) throws IOException {
2612+
public short get(String name, short val) {
26572613
int off = getFieldOffset(name, Short.TYPE);
2658-
return (off >= 0) ? Bits.getShort(primVals, off) : val;
2614+
return (off >= 0) ? Bits.getShort(primValues, off) : val;
26592615
}
26602616

2661-
public int get(String name, int val) throws IOException {
2617+
public int get(String name, int val) {
26622618
int off = getFieldOffset(name, Integer.TYPE);
2663-
return (off >= 0) ? Bits.getInt(primVals, off) : val;
2619+
return (off >= 0) ? Bits.getInt(primValues, off) : val;
26642620
}
26652621

2666-
public float get(String name, float val) throws IOException {
2622+
public float get(String name, float val) {
26672623
int off = getFieldOffset(name, Float.TYPE);
2668-
return (off >= 0) ? Bits.getFloat(primVals, off) : val;
2624+
return (off >= 0) ? Bits.getFloat(primValues, off) : val;
26692625
}
26702626

2671-
public long get(String name, long val) throws IOException {
2627+
public long get(String name, long val) {
26722628
int off = getFieldOffset(name, Long.TYPE);
2673-
return (off >= 0) ? Bits.getLong(primVals, off) : val;
2629+
return (off >= 0) ? Bits.getLong(primValues, off) : val;
26742630
}
26752631

2676-
public double get(String name, double val) throws IOException {
2632+
public double get(String name, double val) {
26772633
int off = getFieldOffset(name, Double.TYPE);
2678-
return (off >= 0) ? Bits.getDouble(primVals, off) : val;
2634+
return (off >= 0) ? Bits.getDouble(primValues, off) : val;
26792635
}
26802636

2681-
public Object get(String name, Object val) throws IOException {
2637+
public Object get(String name, Object val) {
26822638
int off = getFieldOffset(name, Object.class);
26832639
if (off >= 0) {
26842640
int objHandle = objHandles[off];
26852641
handles.markDependency(passHandle, objHandle);
26862642
return (handles.lookupException(objHandle) == null) ?
2687-
objVals[off] : null;
2643+
objValues[off] : null;
26882644
} else {
26892645
return val;
26902646
}
26912647
}
26922648

2693-
/**
2694-
* Reads primitive and object field values from stream.
2695-
*/
2696-
void readFields() throws IOException {
2697-
bin.readFully(primVals, 0, primVals.length, false);
2698-
2699-
int oldHandle = passHandle;
2700-
ObjectStreamField[] fields = desc.getFields(false);
2701-
int numPrimFields = fields.length - objVals.length;
2702-
for (int i = 0; i < objVals.length; i++) {
2703-
objVals[i] =
2704-
readObject0(Object.class, fields[numPrimFields + i].isUnshared());
2705-
objHandles[i] = passHandle;
2706-
}
2707-
passHandle = oldHandle;
2649+
/** Throws ClassCastException if any value is not assignable. */
2650+
void defaultCheckFieldValues(Object obj) {
2651+
if (objValues != null)
2652+
desc.checkObjFieldValueTypes(obj, objValues);
2653+
}
2654+
2655+
private void defaultSetFieldValues(Object obj) {
2656+
if (primValues != null)
2657+
desc.setPrimFieldValues(obj, primValues);
2658+
if (objValues != null)
2659+
desc.setObjFieldValues(obj, objValues);
27082660
}
27092661

27102662
/**

0 commit comments

Comments
 (0)