VmDefaultHeap heap = currentHeap;
Object result = null;
int oomCount = 0;
final Monitor m = heapMonitor;
// final Monitor m = null;
if (m != null) {
m.enter();
}
try {
if (gcActive) {
if ((heapFlags & TRACE_ALLOC) != 0) {
debug("Using GC Heap type ");
debug(vmClass.getName());
}
result = gcHeap.alloc(vmClass, alignedSize);
if (result == null) {
helper.die("Out of GC heap memory.");
}
} else {
while (result == null) {
// The current heap is full
if (heap == null) {
// Unsafe.debug("allocHeap in allocObject(");
// Unsafe.debug(alignedSize);
// Unsafe.debug(") ");
int newHeapSize = DEFAULT_HEAP_SIZE;
if (size > newHeapSize) {
// this is a BIG object, try to allocate a new
// heap
// only for it
newHeapSize = size;
}
if ((heap = allocHeap(Extent
.fromIntZeroExtend(newHeapSize), true)) == null) {
lowOnMemory = true;
// It was not possible to allocate another heap.
// First try to GC, if we've done that before
// in this allocation, then we're in real panic.
if (oomCount == 0) {
oomCount++;
if ((heapFlags & TRACE_OOM) != 0) {
debug("<oom/>");
}
gcThread.trigger(true);
heap = firstNormalHeap;
currentHeap = firstNormalHeap;
} else {
if ((heapFlags & TRACE_OOM) != 0) {
debug("Out of memory in allocObject(");
debug(size);
debug(")");
}
throw OOME;
// Unsafe.die();
}
} else {
// Unsafe.debug("AO.G");
// We successfully allocated a new heap, set it
// to current, so we'll use it for the following
// allocations.
currentHeap = heap;
}
}
result = heap.alloc(vmClass, alignedSize);
if (result == null) {
heap = (VmDefaultHeap) heap.getNext();
}
}
lowOnMemory = false;
allocatedSinceGcTrigger += alignedSize;
if ((allocatedSinceGcTrigger > triggerSize)
&& (gcThread != null)) {
if ((heapFlags & TRACE_TRIGGER) != 0) {
debug("<alloc:GC trigger/>");
}
allocatedSinceGcTrigger = 0;
gcThread.trigger(false);
}
}
vmClass.incInstanceCount();
// Allocated objects are initially black.
VmMagic.setObjectFlags(result, Word
.fromIntZeroExtend(ObjectFlags.GC_DEFAULT_COLOR));
} finally {
if (m != null) {
m.exit();
}
}
return result;
}