Remove InferredStatementContext.childCopyType 24/95224/12
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 18 Feb 2021 08:18:41 +0000 (09:18 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 28 Aug 2021 14:06:47 +0000 (16:06 +0200)
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>
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/InferredStatementContext.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java

index 8c2c3db91512708aa24a7e826d16bd12718c1fc1..3d012f30b54d7fa9457b6b388096b8afd283ffd2 100644 (file)
@@ -87,8 +87,6 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
     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;
 
@@ -107,7 +105,6 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
             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;
@@ -118,12 +115,11 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
 
     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.childCopyType = requireNonNull(childCopyType);
         this.targetModule = targetModule;
         this.originalCtx = prototype.getOriginalCtx().orElse(prototype);
 
@@ -538,7 +534,7 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
     //
 
     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);
     }
 
@@ -561,7 +557,7 @@ final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extend
     }
 
     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) {
index d3fd8206efcd9651136509f27ae1f6ab18dc4666..b54ce1c26c4acc0fe0365b3115a27a6aec390719 100644 (file)
@@ -96,15 +96,14 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
 
     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_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;
@@ -112,6 +111,27 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         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;
@@ -130,24 +150,26 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     // 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.copyHistory = COPY_ORIGINAL;
+        this.bitsAight = COPY_ORIGINAL;
     }
 
     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.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) {
@@ -197,17 +219,22 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
 
     @Override
     public final boolean isAddedByUses() {
-        return (copyHistory & COPY_ADDED_BY_USES) != 0;
+        return (bitsAight & COPY_ADDED_BY_USES) != 0;
     }
 
     @Override
     public final boolean isAugmenting() {
-        return (copyHistory & COPY_ADDED_BY_AUGMENTATION) != 0;
+        return (bitsAight & COPY_ADDED_BY_AUGMENTATION) != 0;
     }
 
     @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];
     }
 
     //