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