/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.osr; import static org.jikesrvm.runtime.UnboxedSizeConstants.LOG_BYTES_IN_ADDRESS; import org.jikesrvm.VM; import org.jikesrvm.mm.mminterface.Barriers; import org.jikesrvm.runtime.Magic; import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.Offset; /** * ObjectHolder helps the specialized prologue to load reference * get around of GC problem.<p> * TODO this class needs better comments. */ @Uninterruptible public class ObjectHolder { // initialize pool size private static final int POOLSIZE = 8; private static Object[][] refs; @Interruptible public static void boot() { refs = new Object[POOLSIZE][]; // exercise the method to avoid lazy compilation in the future Object[] objs = new Object[1]; int p = handinRefs(objs); getRefAt(p, 0); cleanRefs(p); if (VM.TraceOnStackReplacement) { VM.sysWriteln("ObjectHolder booted..."); } } /* * TODO add better documentation and turn this into a JavaDoc comment. * * The VM scope descriptor extractor can hand in an object here */ @Interruptible public static int handinRefs(Object[] objs) { int n = refs.length; for (int i = 0; i < n; i++) { if (refs[i] == null) { refs[i] = objs; return i; } } // grow the array Object[][] newRefs = new Object[2 * n][]; System.arraycopy(refs, 0, newRefs, 0, n); newRefs[n] = objs; refs = newRefs; return n; } /* * TODO add better documentation and turn this into a JavaDoc comment. * * Get the object handed in before, only called by specialized code. */ @Entrypoint @Inline public static Object getRefAt(int h, int i) { if (VM.TraceOnStackReplacement) { VM.sysWriteln("ObjectHolder getRefAt"); } Object obj = refs[h][i]; return obj; } /* * TODO add better documentation and turn this into a JavaDoc comment. * * Clean objects. This method is called by specialized bytecode prologue * Uses magic because it must be uninterruptible */ @Entrypoint @Inline public static void cleanRefs(int h) { if (VM.TraceOnStackReplacement) { VM.sysWriteln("ObjectHolder cleanRefs"); } /* refs[h] = null; */ if (Barriers.NEEDS_OBJECT_ASTORE_BARRIER) { Barriers.objectArrayWrite(refs, h, null); } else { Magic.setObjectAtOffset(refs, Offset.fromIntSignExtend(h << LOG_BYTES_IN_ADDRESS), null); } } }