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