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.classloader.RVMClass;
017    
018    public class FieldLayoutUnpacked extends FieldLayout implements SizeConstants {
019    
020      private static class LayoutContext extends FieldLayoutContext {
021        private static final int NO_HOLE = -1;
022        int intHole = NO_HOLE;
023    
024        LayoutContext(byte alignment) {
025          super(alignment);
026        }
027    
028        LayoutContext(byte alignment, LayoutContext superLayout) {
029          super(alignment, superLayout);
030          if (superLayout != null) {
031            intHole = superLayout.intHole;
032          }
033        }
034    
035        /** Return the next available offset for a given size */
036        @Override
037        int nextOffset(int size, boolean isReference) {
038          int objectSize = getObjectSize();
039          if (size == FieldLayoutUnpacked.BYTES_IN_DOUBLE) {
040            adjustAlignment(FieldLayoutUnpacked.BYTES_IN_DOUBLE);
041            if ((objectSize & 0x7) == 0) {
042              ensureObjectSize(objectSize + FieldLayoutUnpacked.BYTES_IN_DOUBLE);
043              return objectSize;
044            } else {
045              ensureObjectSize(objectSize + FieldLayoutUnpacked.BYTES_IN_DOUBLE + FieldLayoutUnpacked.BYTES_IN_INT);
046              intHole = objectSize;
047              return objectSize + FieldLayoutUnpacked.BYTES_IN_INT;
048            }
049          } else if (intHole >= 0) {
050            int result = intHole;
051            intHole = NO_HOLE;
052            return result;
053          } else {
054            ensureObjectSize(objectSize + FieldLayoutUnpacked.BYTES_IN_INT);
055            return objectSize;
056          }
057        }
058      }
059    
060      public FieldLayoutUnpacked(boolean largeFieldsFirst, boolean clusterReferenceFields) {
061        super(largeFieldsFirst, clusterReferenceFields);
062      }
063    
064      /**
065       * @param klass the class to layout
066       * @return The layout context
067       */
068      @Override
069      protected FieldLayoutContext getLayoutContext(RVMClass klass) {
070        return new LayoutContext((byte) klass.getAlignment(), (LayoutContext) klass.getFieldLayoutContext());
071      }
072    }