BytesOTE* __fastcall ObjectMemory::shallowCopy(BytesOTE* ote) { ASSERT(ote->isBytes()); // Copying byte objects is simple and fast VariantByteObject& bytes = *ote->m_location; BehaviorOTE* classPointer = ote->m_oteClass; MWORD objectSize = ote->sizeOf(); OTE* copyPointer; // Allocate an uninitialized object ... VariantByteObject* pLocation = static_cast<VariantByteObject*>(allocObject(objectSize, copyPointer)); ASSERT((objectSize > MaxSizeOfPoolObject && copyPointer->heapSpace() == OTEFlags::NormalSpace) || copyPointer->heapSpace() == OTEFlags::PoolSpace); ASSERT(copyPointer->getSize() == objectSize); // This set does not want to copy over the immutability bit - i.e. even if the original was immutable, the // copy will never be. copyPointer->setSize(ote->getSize()); copyPointer->m_dwFlags = (copyPointer->m_dwFlags & ~OTEFlags::WeakMask) | (ote->m_dwFlags & OTEFlags::WeakMask); ASSERT(copyPointer->isBytes()); copyPointer->m_oteClass = classPointer; classPointer->countUp(); // Copy the entire object over the other one, including any null terminator and object header memcpy(pLocation, &bytes, objectSize); return reinterpret_cast<BytesOTE*>(copyPointer); }
// N.B. Like the other instantiate methods in ObjectMemory, this method for instantiating // objects in virtual space (used for allocating Processes, for example), does not adjust // the ref. count of the class, because this is often unecessary, and does not adjust the // sizes to allow for fixed fields - callers must do this VirtualOTE* ObjectMemory::newVirtualObject(BehaviorOTE* classPointer, MWORD initialSize, MWORD maxSize) { #ifdef _DEBUG { ASSERT(isBehavior(Oop(classPointer))); Behavior& behavior = *classPointer->m_location; ASSERT(behavior.isIndexable()); } #endif // Trim the sizes to acceptable bounds if (initialSize <= dwOopsPerPage) initialSize = dwOopsPerPage; else initialSize = _ROUND2(initialSize, dwOopsPerPage); if (maxSize < initialSize) maxSize = initialSize; else maxSize = _ROUND2(maxSize, dwOopsPerPage); // We have to allow for the virtual allocation overhead. The allocation function will add in // space for this. The maximum size should include this, the initial size should not initialSize -= sizeof(VirtualObjectHeader)/sizeof(MWORD); unsigned byteSize = initialSize*sizeof(MWORD); VariantObject* pLocation = reinterpret_cast<VariantObject*>(AllocateVirtualSpace(maxSize * sizeof(MWORD), byteSize)); if (pLocation) { // No need to alter ref. count of process class, as it is sticky // Fill space with nils for initial values const Oop nil = Oop(Pointers.Nil); const unsigned loopEnd = initialSize; for (unsigned i = 0; i < loopEnd; i++) pLocation->m_fields[i] = nil; OTE* ote = ObjectMemory::allocateOop(static_cast<POBJECT>(pLocation)); ote->setSize(byteSize); ote->m_oteClass = classPointer; classPointer->countUp(); ote->m_flags = m_spaceOTEBits[OTEFlags::VirtualSpace]; ASSERT(ote->isPointers()); return reinterpret_cast<VirtualOTE*>(ote); } return nullptr; }