Loading...
libkern/c++/OSArray.cpp xnu-12377.101.15 xnu-6153.81.5
--- xnu/xnu-12377.101.15/libkern/c++/OSArray.cpp
+++ xnu/xnu-6153.81.5/libkern/c++/OSArray.cpp
@@ -29,20 +29,15 @@
 /* IOArray.cpp converted to C++ by gvdl on Fri 1998-10-30 */
 
 
-#define IOKIT_ENABLE_SHARED_PTR
-
 #include <libkern/c++/OSArray.h>
 #include <libkern/c++/OSDictionary.h>
+#include <libkern/c++/OSSerialize.h>
 #include <libkern/c++/OSLib.h>
-#include <libkern/c++/OSSerialize.h>
-#include <libkern/c++/OSSharedPtr.h>
 #include <libkern/OSDebug.h>
-#include <os/cpp_util.h>
 
 #define super OSCollection
 
-OSDefineMetaClassAndStructorsWithZone(OSArray, OSCollection,
-    (zone_create_flags_t) (ZC_CACHING | ZC_ZFREE_CLEARMEM))
+OSDefineMetaClassAndStructors(OSArray, OSCollection)
 OSMetaClassDefineReservedUnused(OSArray, 0);
 OSMetaClassDefineReservedUnused(OSArray, 1);
 OSMetaClassDefineReservedUnused(OSArray, 2);
@@ -52,19 +47,26 @@
 OSMetaClassDefineReservedUnused(OSArray, 6);
 OSMetaClassDefineReservedUnused(OSArray, 7);
 
+
+#define EXT_CAST(obj) \
+    reinterpret_cast<OSObject *>(const_cast<OSMetaClassBase *>(obj))
+
 bool
 OSArray::initWithCapacity(unsigned int inCapacity)
 {
+	unsigned int size;
+
 	if (!super::init()) {
 		return false;
 	}
 
 	// integer overflow check
-	if (inCapacity > (UINT_MAX / sizeof(*array))) {
-		return false;
-	}
-
-	array = kallocp_type_container(ArrayPtrType, &inCapacity, Z_WAITOK_ZERO);
+	if (inCapacity > (UINT_MAX / sizeof(const OSMetaClassBase*))) {
+		return false;
+	}
+
+	size = sizeof(const OSMetaClassBase *) * inCapacity;
+	array = (const OSMetaClassBase **) kalloc_container(size);
 	if (!array) {
 		return false;
 	}
@@ -72,7 +74,9 @@
 	count = 0;
 	capacity = inCapacity;
 	capacityIncrement = (inCapacity)? inCapacity : 16;
-	OSCONTAINER_ACCUMSIZE(sizeof(*array) * inCapacity);
+
+	bzero(array, size);
+	OSCONTAINER_ACCUMSIZE(size);
 
 	return true;
 }
@@ -103,7 +107,8 @@
 			return false;
 		}
 
-		array[count++].reset(newObject, OSRetain);
+		array[count++] = newObject;
+		newObject->taggedRetain(OSTypeID(OSCollection));
 	}
 
 	return true;
@@ -121,40 +126,43 @@
 	           anArray->count, theCapacity);
 }
 
-OSSharedPtr<OSArray>
+OSArray *
 OSArray::withCapacity(unsigned int capacity)
 {
-	OSSharedPtr<OSArray> me = OSMakeShared<OSArray>();
+	OSArray *me = new OSArray;
 
 	if (me && !me->initWithCapacity(capacity)) {
-		return nullptr;
+		me->release();
+		return NULL;
 	}
 
 	return me;
 }
 
-OSSharedPtr<OSArray>
+OSArray *
 OSArray::withObjects(const OSObject *objects[],
     unsigned int count,
     unsigned int capacity)
 {
-	OSSharedPtr<OSArray> me = OSMakeShared<OSArray>();
+	OSArray *me = new OSArray;
 
 	if (me && !me->initWithObjects(objects, count, capacity)) {
-		return nullptr;
+		me->release();
+		return NULL;
 	}
 
 	return me;
 }
 
-OSSharedPtr<OSArray>
+OSArray *
 OSArray::withArray(const OSArray *array,
     unsigned int capacity)
 {
-	OSSharedPtr<OSArray> me = OSMakeShared<OSArray>();
+	OSArray *me = new OSArray;
 
 	if (me && !me->initWithArray(array, capacity)) {
-		return nullptr;
+		me->release();
+		return NULL;
 	}
 
 	return me;
@@ -169,9 +177,8 @@
 	flushCollection();
 
 	if (array) {
-		os::destroy(array, array + capacity);
-		kfree_type(ArrayPtrType, capacity, array);
-		OSCONTAINER_ACCUMSIZE( -(sizeof(*array) * capacity));
+		kfree(array, sizeof(const OSMetaClassBase *) * capacity);
+		OSCONTAINER_ACCUMSIZE( -(sizeof(const OSMetaClassBase *) * capacity));
 	}
 
 	super::free();
@@ -204,8 +211,9 @@
 unsigned int
 OSArray::ensureCapacity(unsigned int newCapacity)
 {
-	ArraySharedPtrType *newArray;
-	unsigned int        finalCapacity;
+	const OSMetaClassBase **newArray;
+	unsigned int finalCapacity;
+	vm_size_t    oldSize, newSize;
 
 	if (newCapacity <= capacity) {
 		return capacity;
@@ -216,14 +224,24 @@
 	    * capacityIncrement;
 
 	// integer overflow check
-	if (finalCapacity < newCapacity) {
+	if ((finalCapacity < newCapacity) || (finalCapacity > (UINT_MAX / sizeof(const OSMetaClassBase*)))) {
 		return capacity;
 	}
 
-	newArray = kreallocp_type_container(ArrayPtrType, array,
-	    capacity, &finalCapacity, Z_WAITOK_ZERO);
+	newSize = sizeof(const OSMetaClassBase *) * finalCapacity;
+
+	newArray = (const OSMetaClassBase **) kallocp_container(&newSize);
 	if (newArray) {
-		OSCONTAINER_ACCUMSIZE(sizeof(*array) * (finalCapacity - capacity));
+		// use all of the actual allocation size
+		finalCapacity = newSize / sizeof(const OSMetaClassBase *);
+
+		oldSize = sizeof(const OSMetaClassBase *) * capacity;
+
+		OSCONTAINER_ACCUMSIZE(((size_t)newSize) - ((size_t)oldSize));
+
+		bcopy(array, newArray, oldSize);
+		bzero(&newArray[capacity], newSize - oldSize);
+		kfree(array, oldSize);
 		array = newArray;
 		capacity = finalCapacity;
 	}
@@ -238,19 +256,13 @@
 
 	haveUpdated();
 	for (i = 0; i < count; i++) {
-		array[i].reset();
+		array[i]->taggedRelease(OSTypeID(OSCollection));
 	}
 	count = 0;
 }
 
 bool
 OSArray::setObject(const OSMetaClassBase *anObject)
-{
-	return setObject(count, anObject);
-}
-
-bool
-OSArray::setObject(OSSharedPtr<const OSMetaClassBase> const& anObject)
 {
 	return setObject(count, anObject);
 }
@@ -273,19 +285,14 @@
 	haveUpdated();
 	if (index != count) {
 		for (i = count; i > index; i--) {
-			array[i] = os::move(array[i - 1]);
-		}
-	}
-	array[index].reset(anObject, OSRetain);
+			array[i] = array[i - 1];
+		}
+	}
+	array[index] = anObject;
+	anObject->taggedRetain(OSTypeID(OSCollection));
 	count++;
 
 	return true;
-}
-
-bool
-OSArray::setObject(unsigned int index, OSSharedPtr<const OSMetaClassBase> const& anObject)
-{
-	return setObject(index, anObject.get());
 }
 
 bool
@@ -311,7 +318,8 @@
 	for (unsigned int i = 0; i < otherCount; i++) {
 		const OSMetaClassBase *newObject = otherArray->getObject(i);
 
-		array[count++].reset(newObject, OSRetain);
+		array[count++] = newObject;
+		newObject->taggedRetain(OSTypeID(OSCollection));
 	}
 
 	return true;
@@ -321,38 +329,39 @@
 OSArray::
 replaceObject(unsigned int index, const OSMetaClassBase *anObject)
 {
+	const OSMetaClassBase *oldObject;
+
 	if ((index >= count) || !anObject) {
 		return;
 	}
 
 	haveUpdated();
-
-	array[index].reset(anObject, OSRetain);
-}
-
-void
-OSArray::replaceObject(unsigned int index, OSSharedPtr<const OSMetaClassBase> const& anObject)
-{
-	return replaceObject(index, anObject.get());
+	oldObject = array[index];
+	array[index] = anObject;
+	anObject->taggedRetain(OSTypeID(OSCollection));
+
+	oldObject->taggedRelease(OSTypeID(OSCollection));
 }
 
 void
 OSArray::removeObject(unsigned int index)
 {
 	unsigned int i;
-	ArraySharedPtrType oldObject;
+	const OSMetaClassBase *oldObject;
 
 	if (index >= count) {
 		return;
 	}
 
 	haveUpdated();
-	oldObject = os::move(array[index]);
+	oldObject = array[index];
 
 	count--;
 	for (i = index; i < count; i++) {
-		array[i] = os::move(array[i + 1]);
-	}
+		array[i] = array[i + 1];
+	}
+
+	oldObject->taggedRelease(OSTypeID(OSCollection));
 }
 
 bool
@@ -396,7 +405,7 @@
 	if (index >= count) {
 		return NULL;
 	} else {
-		return static_cast<OSObject *>(const_cast<OSMetaClassBase *>(array[index].get()));
+		return (OSObject *) (const_cast<OSMetaClassBase *>(array[index]));
 	}
 }
 
@@ -406,7 +415,7 @@
 	if (count == 0) {
 		return NULL;
 	} else {
-		return static_cast<OSObject *>(const_cast<OSMetaClassBase *>(array[count - 1].get()));
+		return (OSObject *) (const_cast<OSMetaClassBase *>(array[count - 1]));
 	}
 }
 
@@ -445,7 +454,7 @@
 	unsigned int index = (*iteratorP)++;
 
 	if (index < count) {
-		*ret = static_cast<OSObject *>(const_cast<OSMetaClassBase *>(array[index].get()));
+		*ret = (OSObject *)(const_cast<OSMetaClassBase *> (array[index]));
 		return true;
 	} else {
 		*ret = NULL;
@@ -480,7 +489,7 @@
 	if ((old ^ options) & mask) {
 		// Value changed need to recurse over all of the child collections
 		for (unsigned i = 0; i < count; i++) {
-			OSCollection *coll = OSDynamicCast(OSCollection, array[i].get());
+			OSCollection *coll = OSDynamicCast(OSCollection, array[i]);
 			if (coll) {
 				coll->setOptions(options, mask);
 			}
@@ -490,19 +499,18 @@
 	return old;
 }
 
-OSSharedPtr<OSCollection>
+OSCollection *
 OSArray::copyCollection(OSDictionary *cycleDict)
 {
-	OSSharedPtr<OSDictionary> ourCycleDict;
-	OSSharedPtr<OSCollection> ret;
-	OSSharedPtr<OSArray> newArray;
-
-	if (!cycleDict) {
-		ourCycleDict = OSDictionary::withCapacity(16);
-		if (!ourCycleDict) {
-			return nullptr;
-		}
-		cycleDict = ourCycleDict.get();
+	bool allocDict = !cycleDict;
+	OSCollection *ret = NULL;
+	OSArray *newArray = NULL;
+
+	if (allocDict) {
+		cycleDict = OSDictionary::withCapacity(16);
+		if (!cycleDict) {
+			return NULL;
+		}
 	}
 
 	do {
@@ -518,26 +526,37 @@
 		}
 
 		// Insert object into cycle Dictionary
-		cycleDict->setObject((const OSSymbol *) this, newArray.get());
+		cycleDict->setObject((const OSSymbol *) this, newArray);
 
 		for (unsigned int i = 0; i < count; i++) {
 			OSCollection *coll =
-			    OSDynamicCast(OSCollection, static_cast<OSObject *>(
-				    const_cast<OSMetaClassBase *>(
-					    newArray->array[i].get())));
+			    OSDynamicCast(OSCollection, EXT_CAST(newArray->array[i]));
 
 			if (coll) {
-				OSSharedPtr<OSCollection> newColl = coll->copyCollection(cycleDict);
+				OSCollection *newColl = coll->copyCollection(cycleDict);
 				if (!newColl) {
-					return ret;
+					goto abortCopy;
 				}
 
-				newArray->replaceObject(i, newColl.get());
+				newArray->replaceObject(i, newColl);
+				newColl->release();
 			}
-		}
-
-		ret = os::move(newArray);
+			;
+		}
+		;
+
+		ret = newArray;
+		newArray = NULL;
 	} while (false);
 
+abortCopy:
+	if (newArray) {
+		newArray->release();
+	}
+
+	if (allocDict) {
+		cycleDict->release();
+	}
+
 	return ret;
 }