ST::Object* ObjectMemory::AllocObj(OTE * ote, MWORD allocSize) { ST::Object* pObj; if (allocSize <= MaxSmallObjectSize) { // Allocate from one of the memory pools pObj = static_cast<POBJECT>(allocSmallChunk(allocSize)); ote->m_flags.m_space = OTEFlags::PoolSpace; } else { // Normal space and other spaces allocated from heap (may not be too many) pObj = static_cast<POBJECT>(allocChunk(allocSize)); ote->m_flags.m_space = OTEFlags::NormalSpace; } ote->m_location = pObj; return pObj; }
inline POBJECT ObjectMemory::allocObject(MWORD objectSize, OTE*& ote) { // Callers are expected to round requests to DWORD granularity if (objectSize > MaxSmallObjectSize) return allocLargeObject(objectSize, ote); // Smallblock heap already has space for object size at start of obj which includes // heap overhead,etc, and is rounded to a paragraph size // Why not alloc. four bytes less, overwrite this size with our object size, and then // move back the object body pointer by four. On delete need to reapply the object // size back into the object? - No wouldn't work because of the way heap accesses // adjoining objects when freeing! POBJECT pObj = static_cast<POBJECT>(allocSmallChunk(objectSize)); ote = allocateOop(pObj); ote->setSize(objectSize); ASSERT(ote->heapSpace() == OTEFlags::PoolSpace); return pObj; }
POBJECT ObjectMemory::basicResize(POTE ote, MWORD byteSize, int extra) { ASSERT(!isIntegerObject(ote)); POBJECT pObject; /* #ifdef _DEBUG TRACESTREAM << "Resizing "; Interpreter::printObject(Oop(ote), TRACESTREAM); TRACESTREAM << " (" << ote->m_location << ") from size " << ObjectMemory::sizeOf(ote) << " to size " << byteSize << "\n"; #endif */ switch(ote->heapSpace()) { case OTEFlags::NormalSpace: { // TRACE("Resizing normal object...\n"); pObject = ote->m_location; pObject = reallocChunk(pObject, byteSize+extra); if (pObject) { ote->m_location = pObject; ote->setSize(byteSize); } break; } case OTEFlags::VirtualSpace: // TRACE("Resizing virtual object...\n"); pObject = resizeVirtual(ote, byteSize+extra); break; case OTEFlags::PoolSpace: { #if defined(_DEBUG) if (abs(Interpreter::executionTrace) > 0) checkPools(); #endif // May be able to do some quicker resizing here if size is still in same pool? if ((byteSize+extra) > MaxSmallObjectSize) { pObject = allocChunk(byteSize+extra); ote->m_flags.m_space = OTEFlags::NormalSpace; } else pObject = allocSmallChunk(byteSize+extra); POBJECT pOldObject = ote->m_location; MWORD oldSize = ote->getSize(); memcpy(pObject, pOldObject, min(oldSize, byteSize)); freeSmallChunk(pOldObject, ote->sizeOf()); ote->m_location = pObject; ote->setSize(byteSize); break; } default: // Not resizeable return NULL; } #if defined(_DEBUG) if (abs(Interpreter::executionTrace) > 0) checkPools(); // TRACESTREAM << "After Resize: "; // Interpreter::printObject(Oop(ote), TRACESTREAM); // TRACESTREAM << "\n"; #endif return pObject; }