示例#1
0
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);
}
示例#2
0
// 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;
}