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 */
013package org.jikesrvm.objectmodel;
014
015import static org.jikesrvm.runtime.JavaSizeConstants.BYTES_IN_INT;
016import static org.jikesrvm.runtime.JavaSizeConstants.BYTES_IN_LONG;
017import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS;
018
019import org.jikesrvm.runtime.Memory;
020
021/**
022 * State for the field layout engine.  Subtypes of this are closely
023 * tied to field layout schemes, and are generally defined in same.
024 * <p>
025 * A FieldLayoutContext deals in an abstract offset space, where
026 * there is no header, and fields are laid out relative to 0.
027 * <p>
028 * This abstract superclass looks after the total object size and
029 * alignment.
030 */
031public abstract class FieldLayoutContext {
032
033  /* *****************************************************************
034   *                         Constants
035   */
036  protected static final int OBJECT_SIZE_ALIGN = BYTES_IN_ADDRESS;
037
038  /* *****************************************************************
039  *                        Class fields
040  */
041
042  /** Alignment requirements.  */
043  private byte alignment = BYTES_IN_INT;
044
045  /** The size of the current object as laid out */
046  private int objectSize = 0;
047
048  /**
049   *
050   * @param size the field's size in bytes
051   * @param isReference whether the field is a reference field
052   * @return the offset of a new field of the given size
053   */
054  abstract int nextOffset(int size, boolean isReference);
055
056  /* *****************************************************************
057  *                        Initialization
058  */
059
060  /**
061   * @param alignment the alignment to use for this context
062   */
063  protected FieldLayoutContext(byte alignment) {
064    this.alignment = alignment;
065  }
066
067  /**
068   * Constructor for an object with a superclass.  The superclass
069   * is used to initialize the layout.
070   *
071   * @param alignment the alignment to use for this context
072   * @param superLayout the super class' layout
073   */
074  protected FieldLayoutContext(byte alignment, FieldLayoutContext superLayout) {
075    this.alignment = alignment;
076    if (superLayout != null) {
077      objectSize = superLayout.getObjectSize();
078    }
079  }
080
081  /* *****************************************************************
082   *                  Instance methods
083   */
084
085  /**
086   * Adjust alignment to the next highest value.  In Java, the only 2
087   * possibilities are int-aligned or long-aligned.
088   *
089   * @param fieldSize the size of the field in bytes
090   */
091  protected void adjustAlignment(int fieldSize) {
092    alignment = (fieldSize == BYTES_IN_LONG) ? BYTES_IN_LONG : alignment;
093  }
094
095  /**
096   * @return the current alignment value
097   */
098  int getAlignment() {
099    return alignment;
100  }
101
102  /**
103   * @return The current size of the object (excluding header)
104   */
105  protected int getObjectSize() {
106    return objectSize;
107  }
108
109  /**
110   * Set the current size of the object (excluding header)
111   *
112   * @param size the object's size, excluding the header
113   */
114  protected void setObjectSize(int size) {
115    objectSize = size;
116  }
117
118  /**
119   * Adjust the size of the object if necessary to accommodate a field.
120   *
121   * @param size The size occupied by data fields in the object.
122   */
123  protected void ensureObjectSize(int size) {
124    objectSize = size > objectSize ? Memory.alignUp(size, OBJECT_SIZE_ALIGN) : objectSize;
125  }
126}