001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.objectmodel;
014    
015    import org.jikesrvm.SizeConstants;
016    import org.jikesrvm.runtime.Memory;
017    
018    /**
019     * State for the field layout engine.  Subtypes of this are closely
020     * tied to field layout schemes, and are generally defined in same.
021     * <p>
022     * A FieldLayoutContext deals in an abstract offset space, where
023     * there is no header, and fields are laid out relative to 0.
024     * <p>
025     * This abstract superclass looks after the total object size and
026     * alignment.
027     */
028    public abstract class FieldLayoutContext implements SizeConstants {
029    
030      /* *****************************************************************
031       *                         Constants
032       */
033      protected static final int OBJECT_SIZE_ALIGN = BYTES_IN_ADDRESS;
034    
035      /* *****************************************************************
036      *                        Class fields
037      */
038    
039      /** Alignment requirements.  */
040      private byte alignment = BYTES_IN_INT;
041    
042      /** The size of the current object as laid out */
043      private int objectSize = 0;
044    
045      /** Return the offset of a new field of the given size */
046      abstract int nextOffset(int size, boolean isReference);
047    
048      /* *****************************************************************
049      *                        Initialization
050      */
051    
052      /**
053       * Constructor for a (the) top-level object.
054       *
055       * @param alignment
056       */
057      protected FieldLayoutContext(byte alignment) {
058        this.alignment = alignment;
059      }
060    
061      /**
062       * Constructor for an object with a superclass.  The superclass
063       * is used to initialize the layout.
064       *
065       * @param alignment
066       * @param superLayout
067       */
068      protected FieldLayoutContext(byte alignment, FieldLayoutContext superLayout) {
069        this.alignment = alignment;
070        if (superLayout != null) {
071          objectSize = superLayout.getObjectSize();
072        }
073      }
074    
075      /* *****************************************************************
076       *                  Instance methods
077       */
078    
079      /**
080       * Adjust alignment to the next highest value.  In Java, the only 2
081       * possibilities are int-aligned or long-aligned.
082       *
083       * @param fieldSize
084       */
085      protected void adjustAlignment(int fieldSize) {
086        alignment = (fieldSize == BYTES_IN_LONG) ? BYTES_IN_LONG : alignment;
087      }
088    
089      /**
090       * @return the current alignment value
091       */
092      int getAlignment() {
093        return alignment;
094      }
095    
096      /**
097       * @return The current size of the object (excluding header)
098       */
099      protected int getObjectSize() {
100        return objectSize;
101      }
102    
103      /**
104       * Set the current size of the object (excluding header)
105       */
106      protected void setObjectSize(int size) {
107        objectSize = size;
108      }
109    
110      /**
111       * Adjust the size of the object if necessary to accommodate a field.
112       *
113       * @param size The size occupied by data fields in the object.
114       */
115      protected void ensureObjectSize(int size) {
116        objectSize = size > objectSize ? Memory.alignUp(size, OBJECT_SIZE_ALIGN) : objectSize;
117      }
118    }