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.osr;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.SizeConstants;
017 import org.jikesrvm.mm.mminterface.Barriers;
018 import org.jikesrvm.runtime.Magic;
019 import org.vmmagic.pragma.Inline;
020 import org.vmmagic.pragma.Interruptible;
021 import org.vmmagic.pragma.Uninterruptible;
022 import org.vmmagic.unboxed.Offset;
023
024 /**
025 * ObjectHolder helps the specialized prologue to load reference
026 * get around of GC problem
027 */
028
029 @Uninterruptible
030 public class ObjectHolder implements SizeConstants {
031
032 // initialize pool size
033 private static final int POOLSIZE = 8;
034
035 private static Object[][] refs;
036
037 @Interruptible
038 public static void boot() {
039 refs = new Object[POOLSIZE][];
040
041 // exercise the method to avoid lazy compilation in the future
042 Object[] objs = new Object[1];
043 int p = handinRefs(objs);
044 getRefAt(p, 0);
045 cleanRefs(p);
046
047 if (VM.TraceOnStackReplacement) {
048 VM.sysWriteln("ObjectHolder booted...");
049 }
050 }
051
052 /**
053 * The VM scope descriptor extractor can hand in an object here
054 */
055 @Interruptible
056 public static int handinRefs(Object[] objs) {
057 int n = refs.length;
058 for (int i = 0; i < n; i++) {
059 if (refs[i] == null) {
060 refs[i] = objs;
061 return i;
062 }
063 }
064 // grow the array
065 Object[][] newRefs = new Object[2 * n][];
066 System.arraycopy(refs, 0, newRefs, 0, n);
067 newRefs[n] = objs;
068 refs = newRefs;
069
070 return n;
071 }
072
073 /**
074 * Get the object handed in before, only called by specialized code.
075 */
076 @Inline
077 public static Object getRefAt(int h, int i) {
078
079 if (VM.TraceOnStackReplacement) {
080 VM.sysWriteln("ObjectHolder getRefAt");
081 }
082 Object obj = refs[h][i];
083 return obj;
084 }
085
086 /**
087 * Clean objects. This method is called by specialized bytecode prologue
088 * Uses magic because it must be uninterruptible
089 */
090 @Inline
091 public static void cleanRefs(int h) {
092 if (VM.TraceOnStackReplacement) {
093 VM.sysWriteln("ObjectHolder cleanRefs");
094 }
095 /* refs[h] = null; */
096 if (Barriers.NEEDS_OBJECT_ASTORE_BARRIER) {
097 Barriers.objectArrayWrite(refs, h, null);
098 } else {
099 Magic.setObjectAtOffset(refs, Offset.fromIntSignExtend(h << LOG_BYTES_IN_ADDRESS), null);
100 }
101 }
102 }