ICU-7247 use LocalMemory & MaybeStackArray in some places

X-SVN-Rev: 26964
This commit is contained in:
Markus Scherer 2009-11-21 22:04:55 +00:00
parent 786d5042dd
commit d73228968d
5 changed files with 98 additions and 178 deletions

View file

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1997-2008, International Business Machines
* Copyright (C) 1997-2009, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*
@ -320,9 +320,7 @@ Locale::Locale( const char * newLanguage,
}
else
{
char togo_stack[ULOC_FULLNAME_CAPACITY];
char *togo;
char *togo_heap = NULL;
MaybeStackArray<char, ULOC_FULLNAME_CAPACITY> togo;
int32_t size = 0;
int32_t lsize = 0;
int32_t csize = 0;
@ -389,24 +387,18 @@ Locale::Locale( const char * newLanguage,
/*if the whole string is longer than our internal limit, we need
to go to the heap for temporary buffers*/
if (size >= ULOC_FULLNAME_CAPACITY)
if (size >= togo.getCapacity())
{
togo_heap = (char *)uprv_malloc(sizeof(char)*(size+1));
// If togo_heap could not be created, initialize with default settings.
if (togo_heap == NULL) {
if (togo.resize(size+1) == NULL) {
init(NULL, FALSE);
}
togo = togo_heap;
}
else
{
togo = togo_stack;
}
togo[0] = 0;
// Now, copy it back.
p = togo;
p = togo.getAlias();
if ( lsize != 0 )
{
uprv_strcpy(p, newLanguage);
@ -450,11 +442,7 @@ Locale::Locale( const char * newLanguage,
// Parse it, because for example 'language' might really be a complete
// string.
init(togo, FALSE);
if (togo_heap) {
uprv_free(togo_heap);
}
init(togo.getAlias(), FALSE);
}
}

View file

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2002-2006, International Business Machines
* Copyright (c) 2002-2009, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
* Author: Alan Liu
@ -598,8 +598,6 @@ PropertyAliases::swap(const UDataSwapper *ds,
ValueMap *outValueMaps;
ValueMap valueMap;
uint8_t *temp;
int32_t i;
inAliases=(const PropertyAliases *)inBytes;
@ -647,26 +645,25 @@ PropertyAliases::swap(const UDataSwapper *ds,
* resort strings in name->enum maps
* swap value maps
*/
temp=(uint8_t *)uprv_malloc(aliases.total_size);
if(temp==NULL) {
LocalMemory<uint8_t> temp;
if(temp.allocateInsteadAndReset(aliases.total_size)==NULL) {
udata_printError(ds, "upname_swap(): unable to allocate temp memory (%d bytes)\n",
aliases.total_size);
*pErrorCode=U_MEMORY_ALLOCATION_ERROR;
return 0;
}
uprv_memset(temp, 0, aliases.total_size);
/* swap properties->name groups map */
NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes,
temp, aliases.enumToName_offset, pErrorCode);
temp.getAlias(), aliases.enumToName_offset, pErrorCode);
/* swap name->properties map */
NameToEnum::swap(ds, inBytes, length, outBytes,
temp, aliases.nameToEnum_offset, pErrorCode);
temp.getAlias(), aliases.nameToEnum_offset, pErrorCode);
/* swap properties->value maps map */
NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes,
temp, aliases.enumToValue_offset, pErrorCode);
temp.getAlias(), aliases.enumToValue_offset, pErrorCode);
/* enumerate all ValueMaps and swap them */
inValueMaps=(const ValueMap *)(inBytes+aliases.valueMap_offset);
@ -679,16 +676,16 @@ PropertyAliases::swap(const UDataSwapper *ds,
if(valueMap.enumToName_offset!=0) {
EnumToOffset::swap(ds, inBytes, length, outBytes,
temp, valueMap.enumToName_offset,
temp.getAlias(), valueMap.enumToName_offset,
pErrorCode);
} else if(valueMap.ncEnumToName_offset!=0) {
NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes,
temp, valueMap.ncEnumToName_offset,
temp.getAlias(), valueMap.ncEnumToName_offset,
pErrorCode);
}
if(valueMap.nameToEnum_offset!=0) {
NameToEnum::swap(ds, inBytes, length, outBytes,
temp, valueMap.nameToEnum_offset,
temp.getAlias(), valueMap.nameToEnum_offset,
pErrorCode);
}
}
@ -698,9 +695,6 @@ PropertyAliases::swap(const UDataSwapper *ds,
outValueMaps, pErrorCode);
/* name groups and strings were swapped above */
/* release temp */
uprv_free(temp);
}
return aliases.total_size;

View file

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2002-2008, International Business Machines
* Copyright (c) 2002-2009, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
@ -955,74 +955,56 @@ void RBBITableBuilder::setAdd(UVector *dest, UVector *source) {
int32_t destOriginalSize = dest->size();
int32_t sourceSize = source->size();
int32_t di = 0;
void *(destS[16]), *(sourceS[16]); // Handle small cases without malloc
void **destH = 0, **sourceH = 0;
void **destBuff, **sourceBuff;
MaybeStackArray<void *, 16> destArray, sourceArray; // Handle small cases without malloc
void **destPtr, **sourcePtr;
void **destLim, **sourceLim;
if (destOriginalSize > (int32_t)(sizeof(destS)/sizeof(destS[0]))) {
destH = (void **)uprv_malloc(sizeof(void *) * destOriginalSize);
destBuff = destH;
}
else {
destBuff = destS;
}
if (destBuff == 0) {
return;
}
destLim = destBuff + destOriginalSize;
if (sourceSize > (int32_t)(sizeof(sourceS)/sizeof(sourceS[0]))) {
sourceH = (void **)uprv_malloc(sizeof(void *) * sourceSize);
sourceBuff = sourceH;
}
else {
sourceBuff = sourceS;
}
if (sourceBuff == 0) {
if (destH) {
uprv_free(destH);
if (destOriginalSize > destArray.getCapacity()) {
if (destArray.resize(destOriginalSize) == NULL) {
return;
}
return;
}
sourceLim = sourceBuff + sourceSize;
destPtr = destArray.getAlias();
destLim = destPtr + destOriginalSize; // destArray.getArrayLimit()?
if (sourceSize > sourceArray.getCapacity()) {
if (sourceArray.resize(sourceSize) == NULL) {
return;
}
}
sourcePtr = sourceArray.getAlias();
sourceLim = sourcePtr + sourceSize; // sourceArray.getArrayLimit()?
// Avoid multiple "get element" calls by getting the contents into arrays
(void) dest->toArray(destBuff);
(void) source->toArray(sourceBuff);
(void) dest->toArray(destPtr);
(void) source->toArray(sourcePtr);
dest->setSize(sourceSize+destOriginalSize, *fStatus);
while (sourceBuff < sourceLim && destBuff < destLim) {
if (*destBuff == *sourceBuff) {
dest->setElementAt(*sourceBuff++, di++);
destBuff++;
while (sourcePtr < sourceLim && destPtr < destLim) {
if (*destPtr == *sourcePtr) {
dest->setElementAt(*sourcePtr++, di++);
destPtr++;
}
// This check is required for machines with segmented memory, like i5/OS.
// Direct pointer comparison is not recommended.
else if (uprv_memcmp(destBuff, sourceBuff, sizeof(void *)) < 0) {
dest->setElementAt(*destBuff++, di++);
else if (uprv_memcmp(destPtr, sourcePtr, sizeof(void *)) < 0) {
dest->setElementAt(*destPtr++, di++);
}
else { /* *sourceBuff < *destBuff */
dest->setElementAt(*sourceBuff++, di++);
else { /* *sourcePtr < *destPtr */
dest->setElementAt(*sourcePtr++, di++);
}
}
// At most one of these two cleanup loops will execute
while (destBuff < destLim) {
dest->setElementAt(*destBuff++, di++);
while (destPtr < destLim) {
dest->setElementAt(*destPtr++, di++);
}
while (sourceBuff < sourceLim) {
dest->setElementAt(*sourceBuff++, di++);
while (sourcePtr < sourceLim) {
dest->setElementAt(*sourcePtr++, di++);
}
dest->setSize(di, *fStatus);
if (destH) {
uprv_free(destH);
}
if (sourceH) {
uprv_free(sourceH);
}
}

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2001-2006, International Business Machines
* Copyright (C) 2001-2009, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -534,8 +534,7 @@ unorm_compare(const UChar *s1, int32_t length1,
const UChar *s2, int32_t length2,
uint32_t options,
UErrorCode *pErrorCode) {
UChar fcd1[300], fcd2[300];
UChar *d1, *d2;
MaybeStackArray<UChar, 300> fcd1, fcd2;
const UnicodeSet *nx;
UNormalizationMode mode;
int32_t normOptions;
@ -563,7 +562,6 @@ unorm_compare(const UChar *s1, int32_t length1,
return 0;
}
d1=d2=0;
options|=_COMPARE_EQUIV;
result=0;
@ -616,58 +614,50 @@ unorm_compare(const UChar *s1, int32_t length1,
*/
if(!isFCD1) {
_len1=unorm_internalNormalizeWithNX(fcd1, LENGTHOF(fcd1),
_len1=unorm_internalNormalizeWithNX(fcd1.getAlias(), fcd1.getCapacity(),
s1, length1,
mode, normOptions, nx,
pErrorCode);
if(*pErrorCode!=U_BUFFER_OVERFLOW_ERROR) {
s1=fcd1;
} else {
d1=(UChar *)uprv_malloc(_len1*U_SIZEOF_UCHAR);
if(d1==0) {
if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
if(fcd1.resize(_len1)==NULL) {
*pErrorCode=U_MEMORY_ALLOCATION_ERROR;
goto cleanup;
return result;
}
*pErrorCode=U_ZERO_ERROR;
_len1=unorm_internalNormalizeWithNX(d1, _len1,
_len1=unorm_internalNormalizeWithNX(fcd1.getAlias(), fcd1.getCapacity(),
s1, length1,
mode, normOptions, nx,
pErrorCode);
if(U_FAILURE(*pErrorCode)) {
goto cleanup;
return result;
}
s1=d1;
}
s1=fcd1.getAlias();
length1=_len1;
}
if(!isFCD2) {
_len2=unorm_internalNormalizeWithNX(fcd2, LENGTHOF(fcd2),
_len2=unorm_internalNormalizeWithNX(fcd2.getAlias(), fcd2.getCapacity(),
s2, length2,
mode, normOptions, nx,
pErrorCode);
if(*pErrorCode!=U_BUFFER_OVERFLOW_ERROR) {
s2=fcd2;
} else {
d2=(UChar *)uprv_malloc(_len2*U_SIZEOF_UCHAR);
if(d2==0) {
if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR) {
if(fcd2.resize(_len2)==NULL) {
*pErrorCode=U_MEMORY_ALLOCATION_ERROR;
goto cleanup;
return result;
}
*pErrorCode=U_ZERO_ERROR;
_len2=unorm_internalNormalizeWithNX(d2, _len2,
_len2=unorm_internalNormalizeWithNX(fcd2.getAlias(), fcd2.getCapacity(),
s2, length2,
mode, normOptions, nx,
pErrorCode);
if(U_FAILURE(*pErrorCode)) {
goto cleanup;
return result;
}
s2=d2;
}
s2=fcd2.getAlias();
length2=_len2;
}
}
@ -675,15 +665,6 @@ unorm_compare(const UChar *s1, int32_t length1,
if(U_SUCCESS(*pErrorCode)) {
result=unorm_cmpEquivFold(s1, length1, s2, length2, options, pErrorCode);
}
cleanup:
if(d1!=0) {
uprv_free(d1);
}
if(d2!=0) {
uprv_free(d2);
}
return result;
}

View file

@ -330,89 +330,64 @@ usprep_getProfile(const char* path,
/* fetch the data from the cache */
umtx_lock(&usprepMutex);
profile = (UStringPrepProfile*) (uhash_get(SHARED_DATA_HASHTABLE,&stackKey));
if(profile != NULL) {
profile->refCount++;
}
umtx_unlock(&usprepMutex);
if(profile == NULL){
UStringPrepKey* key = (UStringPrepKey*) uprv_malloc(sizeof(UStringPrepKey));
if(key == NULL){
*status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
if(profile == NULL) {
/* else load the data and put the data in the cache */
profile = (UStringPrepProfile*) uprv_malloc(sizeof(UStringPrepProfile));
if(profile == NULL){
LocalMemory<UStringPrepProfile> newProfile;
if(newProfile.allocateInsteadAndReset() == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
uprv_free(key);
return NULL;
}
/* initialize the data struct members */
uprv_memset(profile->indexes,0,sizeof(profile->indexes));
profile->mappingData = NULL;
profile->sprepData = NULL;
profile->refCount = 0;
/* initialize the key memebers */
key->name = (char*) uprv_malloc(uprv_strlen(name)+1);
if(key->name == NULL){
*status = U_MEMORY_ALLOCATION_ERROR;
uprv_free(key);
uprv_free(profile);
return NULL;
}
uprv_strcpy(key->name, name);
key->path=NULL;
if(path != NULL){
key->path = (char*) uprv_malloc(uprv_strlen(path)+1);
if(key->path == NULL){
*status = U_MEMORY_ALLOCATION_ERROR;
uprv_free(key->name);
uprv_free(key);
uprv_free(profile);
return NULL;
}
uprv_strcpy(key->path, path);
}
/* load the data */
if(!loadData(profile, path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){
uprv_free(key->path);
uprv_free(key->name);
uprv_free(key);
uprv_free(profile);
if(!loadData(newProfile.getAlias(), path, name, _SPREP_DATA_TYPE, status) || U_FAILURE(*status) ){
return NULL;
}
/* get the options */
profile->doNFKC = (UBool)((profile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0);
profile->checkBiDi = (UBool)((profile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0);
newProfile->doNFKC = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_NORMALIZATION_ON) > 0);
newProfile->checkBiDi = (UBool)((newProfile->indexes[_SPREP_OPTIONS] & _SPREP_CHECK_BIDI_ON) > 0);
if(profile->checkBiDi) {
profile->bdp = ubidi_getSingleton(status);
if(newProfile->checkBiDi) {
newProfile->bdp = ubidi_getSingleton(status);
if(U_FAILURE(*status)) {
usprep_unload(profile);
uprv_free(key->path);
uprv_free(key->name);
uprv_free(key);
uprv_free(profile);
usprep_unload(newProfile.getAlias());
return NULL;
}
} else {
profile->bdp = NULL;
}
LocalMemory<UStringPrepKey> key;
LocalMemory<char> keyName;
LocalMemory<char> keyPath;
if( key.allocateInsteadAndReset() == NULL ||
keyName.allocateInsteadAndCopy(uprv_strlen(name)+1) == NULL ||
(path != NULL &&
keyPath.allocateInsteadAndCopy(uprv_strlen(path)+1) == NULL)
) {
*status = U_MEMORY_ALLOCATION_ERROR;
usprep_unload(newProfile.getAlias());
return NULL;
}
/* initialize the key members */
key->name = keyName.orphan();
uprv_strcpy(key->name, name);
if(path != NULL){
key->path = keyPath.orphan();
uprv_strcpy(key->path, path);
}
profile = newProfile.orphan();
umtx_lock(&usprepMutex);
/* add the data object to the cache */
uhash_put(SHARED_DATA_HASHTABLE, key, profile, status);
profile->refCount = 1;
uhash_put(SHARED_DATA_HASHTABLE, key.orphan(), profile, status);
umtx_unlock(&usprepMutex);
}
umtx_lock(&usprepMutex);
/* increment the refcount */
profile->refCount++;
umtx_unlock(&usprepMutex);
return profile;
}