001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Xiao-Feng Li
019: */package org.apache.harmony.drlvm.gc_gen;
020:
021: import org.apache.harmony.drlvm.VMHelper;
022: import org.vmmagic.unboxed.*;
023: import org.vmmagic.pragma.*;
024:
025: public class GCHelper {
026:
027: static {
028: if (VMHelper.COMPRESSED_REFS_MODE) {
029: System.loadLibrary("gc_gen");
030: } else {
031: System.loadLibrary("gc_gen_uncomp");
032: }
033: helperCallback();
034: }
035:
036: public static final int TLS_GC_OFFSET = TLSGCOffset();
037: public static final int PREFETCH_DISTANCE = getPrefetchDist();
038: public static final int ZEROING_SIZE = getZeroingSize();
039: public static final int PREFETCH_STRIDE = getPrefetchStride();
040:
041: public static final int TLA_FREE_OFFSET = getTlaFreeOffset();
042: public static final int TLA_CEILING_OFFSET = getTlaCeilingOffset();
043: public static final int TLA_END_OFFSET = getTlaEndOffset();
044:
045: public static final int LARGE_OBJECT_SIZE = getLargeObjectSize();
046: public static final boolean PREFETCH_ENABLED = isPrefetchEnabled();
047:
048: @Inline
049: private static Address alloc(int objSize, int allocationHandle) {
050:
051: if (objSize > LARGE_OBJECT_SIZE) {
052: return VMHelper.newResolvedUsingAllocHandleAndSize(objSize,
053: allocationHandle);
054: }
055:
056: Address TLS_BASE = VMHelper.getTlsBaseAddress();
057:
058: Address allocator_addr = TLS_BASE.plus(TLS_GC_OFFSET);
059: Address allocator = allocator_addr.loadAddress();
060: Address free_addr = allocator.plus(TLA_FREE_OFFSET);
061: Address free = free_addr.loadAddress();
062: Address ceiling_addr = allocator.plus(TLA_CEILING_OFFSET);
063: Address ceiling = ceiling_addr.loadAddress();
064:
065: Address new_free = free.plus(objSize);
066:
067: if (new_free.LE(ceiling)) {
068: free_addr.store(new_free);
069: free.store(allocationHandle);
070: return free;
071: } else if (PREFETCH_ENABLED) {
072: Address end = allocator.plus(TLA_END_OFFSET).loadAddress();
073: if (new_free.LE(end)) {
074: // do prefetch from new_free to new_free + PREFETCH_DISTANCE + ZEROING_SIZE
075: VMHelper.prefetch(new_free, PREFETCH_DISTANCE
076: + ZEROING_SIZE, PREFETCH_STRIDE);
077:
078: Address new_ceiling = new_free.plus(ZEROING_SIZE);
079: // align ceiling to 64 bytes
080: int remainder = new_ceiling.toInt() & 63;
081: new_ceiling = new_ceiling.minus(remainder);
082: if (!new_ceiling.LE(end)) {
083: new_ceiling = end;
084: }
085:
086: VMHelper.memset0(ceiling, new_ceiling.diff(ceiling)
087: .toInt());
088:
089: ceiling_addr.store(new_ceiling);
090: free_addr.store(new_free);
091: free.store(allocationHandle);
092: return free;
093: }
094: }
095:
096: return VMHelper.newResolvedUsingAllocHandleAndSize(objSize,
097: allocationHandle);
098: }
099:
100: @Inline
101: public static Address alloc(Address classHandle) {
102: int objSize = VMHelper.getTypeSize(classHandle);
103: int allocationHandle = VMHelper
104: .getAllocationHandle(classHandle);
105: return alloc(objSize, allocationHandle);
106: }
107:
108: private static final int ARRAY_LEN_OFFSET = 8;
109: private static final int GC_OBJECT_ALIGNMENT = getGCObjectAlignment();
110:
111: @Inline
112: public static Address allocArray(Address elemClassHandle,
113: int arrayLen) {
114: Address arrayClassHandle = VMHelper
115: .getArrayClass(elemClassHandle);
116: int allocationHandle = VMHelper
117: .getAllocationHandle(arrayClassHandle);
118: if (arrayLen >= 0) {
119: int elemSize = VMHelper.getArrayElemSize(arrayClassHandle);
120: int firstElementOffset = ARRAY_LEN_OFFSET
121: + (elemSize == 8 ? 8 : 4);
122: int size = firstElementOffset + elemSize * arrayLen;
123: size = (((size + (GC_OBJECT_ALIGNMENT - 1)) & (~(GC_OBJECT_ALIGNMENT - 1))));
124:
125: Address arrayAddress = alloc(size, allocationHandle); //never null!
126: arrayAddress.store(arrayLen, Offset
127: .fromIntZeroExtend(ARRAY_LEN_OFFSET));
128: return arrayAddress;
129: }
130: return VMHelper.newVectorUsingAllocHandle(arrayLen,
131: allocationHandle);
132: }
133:
134: /** NOS (nursery object space) is higher in address than other spaces.
135: The boundary currently is produced in GC initialization. It can
136: be a constant in future.
137: */
138:
139: public static Address NOS_BOUNDARY = Address
140: .fromLong(getNosBoundary());
141: public static boolean GEN_MODE = getGenMode();
142:
143: @Inline
144: public static void write_barrier_slot_rem(Address p_target,
145: Address p_objSlot, Address p_objBase) {
146:
147: /* If the slot is in NOS or the target is not in NOS, we simply return*/
148: if (p_objSlot.GE(NOS_BOUNDARY) || p_target.LT(NOS_BOUNDARY)
149: || !GEN_MODE) {
150: p_objSlot.store(p_target);
151: return;
152: }
153: Address p_obj_info = p_objBase.plus(4);
154: int obj_info = p_obj_info.loadInt();
155: if ((obj_info & 0x80) != 0) {
156: p_objSlot.store(p_target);
157: return;
158: }
159:
160: VMHelper.writeBarrier(p_objBase, p_objSlot, p_target);
161: }
162:
163: private static native boolean isPrefetchEnabled();
164:
165: private static native int getLargeObjectSize();
166:
167: private static native int getTlaFreeOffset();
168:
169: private static native int getTlaCeilingOffset();
170:
171: private static native int getTlaEndOffset();
172:
173: private static native int getGCObjectAlignment();
174:
175: private static native int getPrefetchDist();
176:
177: private static native int getZeroingSize();
178:
179: private static native int getPrefetchStride();
180:
181: private static native int helperCallback();
182:
183: private static native boolean getGenMode();
184:
185: private static native long getNosBoundary();
186:
187: private static native int TLSGCOffset();
188: }
|