Skip to content

Commit 547cc29

Browse files
authored
Merge pull request #22677 from keithc-ca/bitfields
Expand DDR support for bitfields
2 parents 8aad305 + 54d5d99 commit 547cc29

File tree

3 files changed

+131
-21
lines changed

3 files changed

+131
-21
lines changed

debugtools/DDR_VM/src/com/ibm/j9ddr/BytecodeGenerator.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Map;
2929
import java.util.Set;
3030
import java.util.TreeMap;
31+
import java.util.regex.Matcher;
3132
import java.util.regex.Pattern;
3233

3334
import com.ibm.j9ddr.StructureReader.ConstantDescriptor;
@@ -2727,6 +2728,34 @@ static PrimitiveAccessor forSize(int size) {
27272728

27282729
final class StructureHelper extends HelperBase {
27292730

2731+
private static final Pattern BaseTypePattern = Pattern.compile(".+?(\\d+)");
2732+
2733+
private static int getCellSize(String type) {
2734+
int size = 0;
2735+
Matcher macher = BaseTypePattern.matcher(type);
2736+
if (macher.matches()) {
2737+
try {
2738+
size = Integer.parseInt(macher.group(1));
2739+
} catch (NumberFormatException e) {
2740+
// ignore
2741+
}
2742+
}
2743+
2744+
switch (size) {
2745+
default:
2746+
// Assume 32 for backwards compatibility.
2747+
size = 32;
2748+
break;
2749+
case 8:
2750+
case 16:
2751+
case 32:
2752+
case 64:
2753+
break;
2754+
}
2755+
2756+
return size;
2757+
}
2758+
27302759
static byte[] getClassBytes(StructureDescriptor structure, String className) {
27312760
StructureHelper helper = new StructureHelper(structure, className);
27322761

@@ -2893,8 +2922,9 @@ private Map<String, Integer> getFieldMap() {
28932922
*/
28942923
bitFieldBitCount = Math.max(bitFieldBitCount, fieldOffset * Byte.SIZE);
28952924

2896-
if (bitSize > (StructureReader.BIT_FIELD_CELL_SIZE
2897-
- (bitFieldBitCount % StructureReader.BIT_FIELD_CELL_SIZE))) {
2925+
int cellSize = getCellSize(type.substring(0, colonIndex));
2926+
2927+
if (bitSize > (cellSize - (bitFieldBitCount % cellSize))) {
28982928
throw new InternalError(
28992929
String.format("Bitfield %s->%s must not span cells", structure.getName(), fieldName));
29002930
}

debugtools/DDR_VM/src/com/ibm/j9ddr/StructureReader.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ public final class StructureReader {
6767
public static final Class<?>[] STRUCTURE_CONSTRUCTOR_SIGNATURE = new Class<?>[] { Long.TYPE };
6868
public static final byte BIT_FIELD_FORMAT_LITTLE_ENDIAN = 1;
6969
public static final byte BIT_FIELD_FORMAT_BIG_ENDIAN = 2;
70+
71+
/*
72+
* This value is not used in current code (and should not be, because
73+
* bitfields don't necessarily have the same base type size), but is
74+
* retained for use by IBM Java 8 build for backward compatibility.
75+
*/
7076
public static final int BIT_FIELD_CELL_SIZE = 32;
7177

7278
private static final Pattern MULTI_LINE_COMMENT_PATTERN = Pattern.compile(Pattern.quote("/*") + ".*?" + Pattern.quote("*/") , Pattern.DOTALL);

debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/pointer/StructurePointer.java

Lines changed: 93 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,15 @@
3535
import com.ibm.j9ddr.StructureReader;
3636
import com.ibm.j9ddr.util.RuntimeTypeResolutionUtils;
3737
import com.ibm.j9ddr.vm29.j9.DataType;
38+
import com.ibm.j9ddr.vm29.types.I8;
39+
import com.ibm.j9ddr.vm29.types.I16;
3840
import com.ibm.j9ddr.vm29.types.I32;
41+
import com.ibm.j9ddr.vm29.types.I64;
3942
import com.ibm.j9ddr.vm29.types.Scalar;
43+
import com.ibm.j9ddr.vm29.types.U8;
44+
import com.ibm.j9ddr.vm29.types.U16;
4045
import com.ibm.j9ddr.vm29.types.U32;
46+
import com.ibm.j9ddr.vm29.types.U64;
4147

4248
/**
4349
* Root of the hierarchy for VM C structures.
@@ -58,33 +64,101 @@ public DataType at(Scalar count) {
5864
throw new UnsupportedOperationException("StructurePointers are implicitly dereferenced. Use add(Scalar count) instead.");
5965
}
6066

61-
protected int getStartingBit(int s, int b) {
67+
protected final I8 getI8Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
68+
long cellOffset = getCellOffset(bitOffset, 8);
69+
long cell = getByteAtOffset(cellOffset);
70+
long field = getBitfield(cell, bitOffset, bitWidth, 8, true);
71+
72+
return new I8(field);
73+
}
74+
75+
protected final I16 getI16Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
76+
long cellOffset = getCellOffset(bitOffset, 16);
77+
long cell = getShortAtOffset(cellOffset);
78+
long field = getBitfield(cell, bitOffset, bitWidth, 16, true);
79+
80+
return new I16(field);
81+
}
82+
83+
protected final I32 getI32Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
84+
long cellOffset = getCellOffset(bitOffset, 32);
85+
long cell = getIntAtOffset(cellOffset);
86+
long field = getBitfield(cell, bitOffset, bitWidth, 32, true);
87+
88+
return new I32(field);
89+
}
90+
91+
protected final I64 getI64Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
92+
long cellOffset = getCellOffset(bitOffset, 64);
93+
long cell = getLongAtOffset(cellOffset);
94+
long field = getBitfield(cell, bitOffset, bitWidth, 64, true);
95+
96+
return new I64(field);
97+
}
98+
99+
protected final U8 getU8Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
100+
long cellOffset = getCellOffset(bitOffset, 8);
101+
long cell = getByteAtOffset(cellOffset);
102+
long field = getBitfield(cell, bitOffset, bitWidth, 8, false);
103+
104+
return new U8(field);
105+
}
106+
107+
protected final U16 getU16Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
108+
long cellOffset = getCellOffset(bitOffset, 16);
109+
long cell = getShortAtOffset(cellOffset);
110+
long field = getBitfield(cell, bitOffset, bitWidth, 16, false);
111+
112+
return new U16(field);
113+
}
114+
115+
protected final U32 getU32Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
116+
long cellOffset = getCellOffset(bitOffset, 32);
117+
long cell = getIntAtOffset(cellOffset);
118+
long field = getBitfield(cell, bitOffset, bitWidth, 32, false);
119+
120+
return new U32(field);
121+
}
122+
123+
protected final U64 getU64Bitfield(int bitOffset, int bitWidth) throws CorruptDataException {
124+
long cellOffset = getCellOffset(bitOffset, 64);
125+
long cell = getLongAtOffset(cellOffset);
126+
long field = getBitfield(cell, bitOffset, bitWidth, 64, false);
127+
128+
return new U64(field);
129+
}
130+
131+
private static long getCellOffset(int bitOffset, int cellSize) {
132+
long cellIndex = bitOffset / cellSize;
133+
134+
return cellIndex * (cellSize / Byte.SIZE);
135+
}
136+
137+
private static long getBitfield(long cell, int bitOffset, int bitWidth, int cellSize, boolean isSigned) {
138+
int leftShift;
139+
62140
switch (BITFIELD_FORMAT) {
63141
case StructureReader.BIT_FIELD_FORMAT_LITTLE_ENDIAN:
64-
return b + (s % StructureReader.BIT_FIELD_CELL_SIZE);
142+
leftShift = Long.SIZE - bitWidth - (bitOffset % cellSize);
143+
break;
65144
case StructureReader.BIT_FIELD_FORMAT_BIG_ENDIAN:
66-
return 32 - (s % StructureReader.BIT_FIELD_CELL_SIZE);
145+
leftShift = Long.SIZE - cellSize + (bitOffset % cellSize);
146+
break;
67147
default:
68148
throw new IllegalArgumentException("Unsupported bitfield format");
69149
}
70-
}
71150

72-
protected U32 getU32Bitfield(int s, int b) throws CorruptDataException {
73-
int cell = s/StructureReader.BIT_FIELD_CELL_SIZE;
74-
U32 cellValue = new U32(getIntAtOffset(cell * StructureReader.BIT_FIELD_CELL_SIZE / 8));
75-
int n = getStartingBit(s, b);
76-
U32 returnValue = cellValue.leftShift(StructureReader.BIT_FIELD_CELL_SIZE - n);
77-
returnValue = returnValue.rightShift(StructureReader.BIT_FIELD_CELL_SIZE - b);
78-
return returnValue;
79-
}
151+
// Shift left so the most significant bit becomes the sign bit.
152+
long leftAligned = cell << leftShift;
80153

81-
protected I32 getI32Bitfield(int s, int b) throws CorruptDataException {
82-
int cell = s/StructureReader.BIT_FIELD_CELL_SIZE;
83-
I32 cellValue = new I32(getIntAtOffset(cell * StructureReader.BIT_FIELD_CELL_SIZE / 8));
84-
int n = getStartingBit(s, b);
85-
I32 returnValue = cellValue.leftShift(StructureReader.BIT_FIELD_CELL_SIZE - n);
86-
returnValue = returnValue.rightShift(StructureReader.BIT_FIELD_CELL_SIZE - b);
87-
return returnValue;
154+
// The number of uninteresting bits in leftAligned.
155+
int rightShift = Long.SIZE - bitWidth;
156+
157+
if (isSigned) {
158+
return leftAligned >> rightShift;
159+
} else {
160+
return leftAligned >>> rightShift;
161+
}
88162
}
89163

90164
public StructurePointer getAsRuntimeType()

0 commit comments

Comments
 (0)