This field is costing us object size in both 32bit and uncompressed
64bit mode. Since the field only encodes 2 bits, move this storage
to StatementContextBase.copyHistory, saving 8/8/0/0 bytes.
JIRA: YANGTOOLS-1256
Change-Id: Ifeb2cefd0449a4d9112f31a4c511a63dc5b0fb10
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
private final @NonNull StatementContextBase<A, D, E> prototype;
private final @NonNull StatementContextBase<?, ?, ?> parent;
private final @NonNull StmtContext<A, D, E> originalCtx;
private final @NonNull StatementContextBase<A, D, E> prototype;
private final @NonNull StatementContextBase<?, ?, ?> parent;
private final @NonNull StmtContext<A, D, E> originalCtx;
- // TODO: consider encoding this in StatementContextBase fields, there should be plenty of room
- private final @NonNull CopyType childCopyType;
private final QNameModule targetModule;
private final A argument;
private final QNameModule targetModule;
private final A argument;
final StatementContextBase<?, ?, ?> parent) {
super(original);
this.parent = requireNonNull(parent);
final StatementContextBase<?, ?, ?> parent) {
super(original);
this.parent = requireNonNull(parent);
- this.childCopyType = original.childCopyType;
this.targetModule = original.targetModule;
this.prototype = original.prototype;
this.originalCtx = original.originalCtx;
this.targetModule = original.targetModule;
this.prototype = original.prototype;
this.originalCtx = original.originalCtx;
InferredStatementContext(final StatementContextBase<?, ?, ?> parent, final StatementContextBase<A, D, E> prototype,
final CopyType myCopyType, final CopyType childCopyType, final QNameModule targetModule) {
InferredStatementContext(final StatementContextBase<?, ?, ?> parent, final StatementContextBase<A, D, E> prototype,
final CopyType myCopyType, final CopyType childCopyType, final QNameModule targetModule) {
- super(prototype, myCopyType);
+ super(prototype, myCopyType, childCopyType);
this.parent = requireNonNull(parent);
this.prototype = requireNonNull(prototype);
this.argument = targetModule == null ? prototype.argument()
: prototype.definition().adaptArgumentValue(prototype, targetModule);
this.parent = requireNonNull(parent);
this.prototype = requireNonNull(prototype);
this.argument = targetModule == null ? prototype.argument()
: prototype.definition().adaptArgumentValue(prototype, targetModule);
- this.childCopyType = requireNonNull(childCopyType);
this.targetModule = targetModule;
this.originalCtx = prototype.getOriginalCtx().orElse(prototype);
this.targetModule = targetModule;
this.originalCtx = prototype.getOriginalCtx().orElse(prototype);
//
private EffectiveCopy effectiveCopy(final ReactorStmtCtx<?, ?, ?> stmt) {
//
private EffectiveCopy effectiveCopy(final ReactorStmtCtx<?, ?, ?> stmt) {
- final ReactorStmtCtx<?, ?, ?> effective = stmt.asEffectiveChildOf(this, childCopyType, targetModule);
+ final ReactorStmtCtx<?, ?, ?> effective = stmt.asEffectiveChildOf(this, childCopyType(), targetModule);
return effective == null ? null : new EffectiveCopy(stmt, effective);
}
return effective == null ? null : new EffectiveCopy(stmt, effective);
}
}
private Optional<? extends Mutable<?, ?, ?>> copySubstatement(final Mutable<?, ?, ?> substatement) {
}
private Optional<? extends Mutable<?, ?, ?>> copySubstatement(final Mutable<?, ?, ?> substatement) {
- return substatement.copyAsChildOf(this, childCopyType, targetModule);
+ return substatement.copyAsChildOf(this, childCopyType(), targetModule);
}
private void addMaterialized(final StmtContext<?, ?, ?> template, final Mutable<?, ?, ?> copy) {
}
private void addMaterialized(final StmtContext<?, ?, ?> template, final Mutable<?, ?, ?> copy) {
private static final Logger LOG = LoggerFactory.getLogger(StatementContextBase.class);
private static final Logger LOG = LoggerFactory.getLogger(StatementContextBase.class);
- //
- // {@link CopyHistory} encoded as a single byte. We still have 4 bits unused.
- //
+ // Bottom 4 bits, encoding a CopyHistory, aight?
+ private static final byte COPY_ORIGINAL = 0x00;
private static final byte COPY_LAST_TYPE_MASK = 0x03;
private static final byte COPY_ADDED_BY_USES = 0x04;
private static final byte COPY_ADDED_BY_AUGMENTATION = 0x08;
private static final byte COPY_LAST_TYPE_MASK = 0x03;
private static final byte COPY_ADDED_BY_USES = 0x04;
private static final byte COPY_ADDED_BY_AUGMENTATION = 0x08;
- private static final byte COPY_ORIGINAL = 0x00;
- private final byte copyHistory;
+ // Top four bits, of which we define the topmost two to 0. We use the bottom two to encode last CopyType, aight?
+ private static final int COPY_CHILD_TYPE_SHIFT = 4;
static {
final int copyTypes = CopyType.values().length;
static {
final int copyTypes = CopyType.values().length;
verify(copyTypes == COPY_LAST_TYPE_MASK + 1, "Unexpected %s CopyType values", copyTypes);
}
verify(copyTypes == COPY_LAST_TYPE_MASK + 1, "Unexpected %s CopyType values", copyTypes);
}
+ /**
+ * 8 bits worth of instance storage. This is treated as a constant bit field with following structure:
+ * <pre>
+ * <code>
+ * |7|6|5|4|3|2|1|0|
+ * |0 0|cct|a|u|lst|
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The four allocated fields are:
+ * <ul>
+ * <li>{@code lst}, encoding the four states corresponding to {@link CopyHistory#getLastOperation()}</li>
+ * <li>{@code u}, encoding {@link #isAddedByUses()}</li>
+ * <li>{@code a}, encoding {@link #isAugmenting()}</li>
+ * <li>{@code cct} encoding {@link #childCopyType()}</li>
+ * </ul>
+ * We still have two unused bits.
+ */
+ private final byte bitsAight;
+
// Note: this field can strictly be derived in InferredStatementContext, but it forms the basis of many of our
// operations, hence we want to keep it close by.
private final @NonNull StatementDefinitionContext<A, D, E> definition;
// Note: this field can strictly be derived in InferredStatementContext, but it forms the basis of many of our
// operations, hence we want to keep it close by.
private final @NonNull StatementDefinitionContext<A, D, E> definition;
// Copy constructor used by subclasses to implement reparent()
StatementContextBase(final StatementContextBase<A, D, E> original) {
super(original);
// Copy constructor used by subclasses to implement reparent()
StatementContextBase(final StatementContextBase<A, D, E> original) {
super(original);
- this.copyHistory = original.copyHistory;
+ this.bitsAight = original.bitsAight;
this.definition = original.definition;
this.executionOrder = original.executionOrder;
}
StatementContextBase(final StatementDefinitionContext<A, D, E> def) {
this.definition = requireNonNull(def);
this.definition = original.definition;
this.executionOrder = original.executionOrder;
}
StatementContextBase(final StatementDefinitionContext<A, D, E> def) {
this.definition = requireNonNull(def);
- this.copyHistory = COPY_ORIGINAL;
+ this.bitsAight = COPY_ORIGINAL;
}
StatementContextBase(final StatementDefinitionContext<A, D, E> def, final CopyType copyType) {
this.definition = requireNonNull(def);
}
StatementContextBase(final StatementDefinitionContext<A, D, E> def, final CopyType copyType) {
this.definition = requireNonNull(def);
- this.copyHistory = (byte) copyFlags(copyType);
+ this.bitsAight = (byte) copyFlags(copyType);
- StatementContextBase(final StatementContextBase<A, D, E> prototype, final CopyType copyType) {
+ StatementContextBase(final StatementContextBase<A, D, E> prototype, final CopyType copyType,
+ final CopyType childCopyType) {
this.definition = prototype.definition;
this.definition = prototype.definition;
- this.copyHistory = (byte) (copyFlags(copyType) | prototype.copyHistory & ~COPY_LAST_TYPE_MASK);
+ this.bitsAight = (byte) (copyFlags(copyType)
+ | prototype.bitsAight & ~COPY_LAST_TYPE_MASK | childCopyType.ordinal() << COPY_CHILD_TYPE_SHIFT);
}
private static int copyFlags(final CopyType copyType) {
}
private static int copyFlags(final CopyType copyType) {
@Override
public final boolean isAddedByUses() {
@Override
public final boolean isAddedByUses() {
- return (copyHistory & COPY_ADDED_BY_USES) != 0;
+ return (bitsAight & COPY_ADDED_BY_USES) != 0;
}
@Override
public final boolean isAugmenting() {
}
@Override
public final boolean isAugmenting() {
- return (copyHistory & COPY_ADDED_BY_AUGMENTATION) != 0;
+ return (bitsAight & COPY_ADDED_BY_AUGMENTATION) != 0;
}
@Override
public final CopyType getLastOperation() {
}
@Override
public final CopyType getLastOperation() {
- return CopyType.values()[copyHistory & COPY_LAST_TYPE_MASK];
+ return CopyType.values()[bitsAight & COPY_LAST_TYPE_MASK];
+ }
+
+ // This method exists only for space optimization of InferredStatementContext
+ final CopyType childCopyType() {
+ return CopyType.values()[bitsAight >> COPY_CHILD_TYPE_SHIFT & COPY_LAST_TYPE_MASK];