mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 1349695 - Part 2: Use separate arrays in txNodeSorter::sortNodeSet. r=peterv
This separates out the index and object arrays in order to make the size calculations clearer. More modern containers are used to make memory management simpler. MozReview-Commit-ID: 2Jmpq7caY3J
This commit is contained in:
parent
eab1efdc4e
commit
7a68f28ccb
@ -10,12 +10,13 @@
|
||||
#include "txNodeSetContext.h"
|
||||
#include "txExpr.h"
|
||||
#include "txStringUtils.h"
|
||||
#include "prmem.h"
|
||||
#include "nsQuickSort.h"
|
||||
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
|
||||
using mozilla::CheckedUint32;
|
||||
using mozilla::MakeUniqueFallible;
|
||||
|
||||
/*
|
||||
* Sorts Nodes as specified by the W3C XSLT 1.0 Recommendation
|
||||
@ -144,60 +145,53 @@ txNodeSorter::sortNodeSet(txNodeSet* aNodes, txExecutionState* aEs,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create and set up memoryblock for sort-values and indexarray
|
||||
uint32_t len = static_cast<uint32_t>(aNodes->size());
|
||||
|
||||
// Limit resource use to something sane.
|
||||
CheckedUint32 indexSize = CheckedUint32(len) * sizeof(uint32_t);
|
||||
CheckedUint32 sortValuesSize = CheckedUint32(len) * sizeof(txObject*) * mNKeys;
|
||||
CheckedUint32 arraySize = indexSize + sortValuesSize;
|
||||
if (!arraySize.isValid()) {
|
||||
CheckedUint32 len = aNodes->size();
|
||||
CheckedUint32 numSortValues = len * mNKeys;
|
||||
CheckedUint32 sortValuesSize = numSortValues * sizeof(txObject*);
|
||||
if (!sortValuesSize.isValid()) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
void* mem = PR_Malloc(arraySize.value());
|
||||
NS_ENSURE_TRUE(mem, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
uint32_t* indexes = static_cast<uint32_t*>(mem);
|
||||
txObject** sortValues = reinterpret_cast<txObject**>(indexes + len);
|
||||
auto indexes = MakeUniqueFallible<uint32_t[]>(len.value());
|
||||
auto sortValues = MakeUniqueFallible<txObject*[]>(numSortValues.value());
|
||||
if (!indexes || !sortValues) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
for (i = 0; i < len.value(); ++i) {
|
||||
indexes[i] = i;
|
||||
}
|
||||
memset(sortValues, 0, sortValuesSize.value());
|
||||
memset(sortValues.get(), 0, sortValuesSize.value());
|
||||
|
||||
// Sort the indexarray
|
||||
SortData sortData;
|
||||
sortData.mNodeSorter = this;
|
||||
sortData.mContext = evalContext;
|
||||
sortData.mSortValues = sortValues;
|
||||
sortData.mSortValues = sortValues.get();
|
||||
sortData.mRv = NS_OK;
|
||||
NS_QuickSort(indexes, len, sizeof(uint32_t), compareNodes, &sortData);
|
||||
NS_QuickSort(indexes.get(), len.value(), sizeof(uint32_t), compareNodes, &sortData);
|
||||
|
||||
// Delete these here so we don't have to deal with them at every possible
|
||||
// failurepoint
|
||||
uint32_t numSortValues = len * mNKeys;
|
||||
for (i = 0; i < numSortValues; ++i) {
|
||||
for (i = 0; i < numSortValues.value(); ++i) {
|
||||
delete sortValues[i];
|
||||
}
|
||||
|
||||
if (NS_FAILED(sortData.mRv)) {
|
||||
PR_Free(mem);
|
||||
// The txExecutionState owns the evalcontext so no need to handle it
|
||||
return sortData.mRv;
|
||||
}
|
||||
|
||||
// Insert nodes in sorted order in new nodeset
|
||||
for (i = 0; i < len; ++i) {
|
||||
for (i = 0; i < len.value(); ++i) {
|
||||
rv = sortedNodes->append(aNodes->get(indexes[i]));
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_Free(mem);
|
||||
// The txExecutionState owns the evalcontext so no need to handle it
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
PR_Free(mem);
|
||||
delete aEs->popEvalContext();
|
||||
|
||||
NS_ADDREF(*aResult = sortedNodes);
|
||||
|
Loading…
Reference in New Issue
Block a user