Loading...
libkern/c++/OSDictionary.cpp xnu-12377.101.15 xnu-7195.141.2
--- xnu/xnu-12377.101.15/libkern/c++/OSDictionary.cpp
+++ xnu/xnu-7195.141.2/libkern/c++/OSDictionary.cpp
@@ -91,14 +91,16 @@
 		return false;
 	}
 
+	unsigned int size = inCapacity * sizeof(dictEntry);
 //fOptions |= kSort;
 
-	dictionary = kallocp_type_container(dictEntry, &inCapacity, Z_WAITOK_ZERO);
+	dictionary = (dictEntry *) kalloc_container(size);
 	if (!dictionary) {
 		return false;
 	}
 
-	OSCONTAINER_ACCUMSIZE(inCapacity * sizeof(dictEntry));
+	os::uninitialized_value_construct(dictionary, dictionary + inCapacity);
+	OSCONTAINER_ACCUMSIZE(size);
 
 	count = 0;
 	capacity = inCapacity;
@@ -280,7 +282,7 @@
 	(void) super::setOptions(0, kImmutable);
 	flushCollection();
 	if (dictionary) {
-		kfree_type(dictEntry, capacity, dictionary);
+		kfree(dictionary, capacity * sizeof(dictEntry));
 		OSCONTAINER_ACCUMSIZE( -(capacity * sizeof(dictEntry)));
 	}
 
@@ -316,7 +318,8 @@
 OSDictionary::ensureCapacity(unsigned int newCapacity)
 {
 	dictEntry *newDict;
-	unsigned int finalCapacity;
+	vm_size_t finalCapacity;
+	vm_size_t oldSize, newSize;
 
 	if (newCapacity <= capacity) {
 		return capacity;
@@ -331,12 +334,29 @@
 		return capacity;
 	}
 
-	newDict = kreallocp_type_container(dictEntry, dictionary,
-	    capacity, &finalCapacity, Z_WAITOK_ZERO);
+	newSize = sizeof(dictEntry) * finalCapacity;
+
+	newDict = (dictEntry *) kallocp_container(&newSize);
 	if (newDict) {
-		OSCONTAINER_ACCUMSIZE(sizeof(dictEntry) * (finalCapacity - capacity));
+		// use all of the actual allocation size
+		finalCapacity = (newSize / sizeof(dictEntry));
+		if (finalCapacity > UINT_MAX) {
+			// failure, too large
+			kfree(newDict, newSize);
+			return capacity;
+		}
+
+		oldSize = sizeof(dictEntry) * capacity;
+
+		os::uninitialized_move(dictionary, dictionary + capacity, newDict);
+		os::uninitialized_value_construct(newDict + capacity, newDict + finalCapacity);
+		os::destroy(dictionary, dictionary + capacity);
+
+		OSCONTAINER_ACCUMSIZE(((size_t)newSize) - ((size_t)oldSize));
+		kfree(dictionary, oldSize);
+
 		dictionary = newDict;
-		capacity = finalCapacity;
+		capacity = (unsigned int) finalCapacity;
 	}
 
 	return capacity;
@@ -348,8 +368,8 @@
 	haveUpdated();
 
 	for (unsigned int i = 0; i < count; i++) {
-		dictionary[i].key.reset();
-		dictionary[i].value.reset();
+		dictionary[i].key->taggedRelease(OSTypeID(OSCollection));
+		dictionary[i].value->taggedRelease(OSTypeID(OSCollection));
 	}
 	count = 0;
 }