From 3c908dca479ed50dca24b8593bca90e40dbde6b8 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Sat, 19 Apr 2003 00:07:51 +0000 Subject: [PATCH] added xmlMallocAtomic() to be used when allocating blocks which do not * DOCBparser.c HTMLparser.c c14n.c catalog.c encoding.c globals.c nanohttp.c parser.c parserInternals.c relaxng.c tree.c uri.c xmlmemory.c xmlreader.c xmlregexp.c xpath.c xpointer.c include/libxml/globals.h include/libxml/xmlmemory.h: added xmlMallocAtomic() to be used when allocating blocks which do not contains pointers, add xmlGcMemSetup() and xmlGcMemGet() to allow registering the full set of functions needed by a garbage collecting allocator like libgc, ref #109944 Daniel --- ChangeLog | 11 +++ DOCBparser.c | 6 +- HTMLparser.c | 8 +-- c14n.c | 2 +- catalog.c | 4 +- encoding.c | 2 +- globals.c | 15 ++++ include/libxml/globals.h | 14 ++++ include/libxml/xmlmemory.h | 23 ++++++ nanohttp.c | 4 +- parser.c | 36 +++++----- parserInternals.c | 2 +- relaxng.c | 2 +- tree.c | 12 ++-- uri.c | 12 ++-- xmlmemory.c | 139 ++++++++++++++++++++++++++++++++++++- xmlreader.c | 2 +- xmlregexp.c | 4 +- xpath.c | 2 +- xpointer.c | 2 +- 20 files changed, 251 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2944668a..c76b48ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Sat Apr 19 02:03:24 CEST 2003 Daniel Veillard + + * DOCBparser.c HTMLparser.c c14n.c catalog.c encoding.c globals.c + nanohttp.c parser.c parserInternals.c relaxng.c tree.c uri.c + xmlmemory.c xmlreader.c xmlregexp.c xpath.c xpointer.c + include/libxml/globals.h include/libxml/xmlmemory.h: added + xmlMallocAtomic() to be used when allocating blocks which + do not contains pointers, add xmlGcMemSetup() and xmlGcMemGet() + to allow registering the full set of functions needed by + a garbage collecting allocator like libgc, ref #109944 + Fri Apr 18 16:37:41 CEST 2003 Daniel Veillard * configure.in: switched to have thread support enabled by default, diff --git a/DOCBparser.c b/DOCBparser.c index 232c5a54..5a811cbc 100644 --- a/DOCBparser.c +++ b/DOCBparser.c @@ -2682,7 +2682,7 @@ docbParseSGMLAttribute(docbParserCtxtPtr ctxt, const xmlChar stop) { * allocate a translation buffer. */ buffer_size = DOCB_PARSER_BIG_BUFFER_SIZE; - buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar)); if (buffer == NULL) { xmlGenericError(xmlGenericErrorContext, "docbParseSGMLAttribute: malloc failed"); @@ -3195,7 +3195,7 @@ docbParsePI(xmlParserCtxtPtr ctxt) { } } - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -3315,7 +3315,7 @@ docbParseComment(docbParserCtxtPtr ctxt) { ctxt->instate = XML_PARSER_COMMENT; SHRINK; SKIP(4); - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); diff --git a/HTMLparser.c b/HTMLparser.c index 86c575f0..572a7501 100644 --- a/HTMLparser.c +++ b/HTMLparser.c @@ -2268,7 +2268,7 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) { xmlChar *buffer; int max = len * 2; - buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, @@ -2333,7 +2333,7 @@ htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) { * allocate a translation buffer. */ buffer_size = HTML_PARSER_BUFFER_SIZE; - buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar)); if (buffer == NULL) { xmlGenericError(xmlGenericErrorContext, "htmlParseHTMLAttribute: malloc failed\n"); @@ -2900,7 +2900,7 @@ htmlParseComment(htmlParserCtxtPtr ctxt) { ctxt->instate = XML_PARSER_COMMENT; SHRINK; SKIP(4); - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -5378,7 +5378,7 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding) /* set encoding */ if (encoding) { - content = xmlMalloc (xmlStrlen(content_line) + strlen(encoding) + 1); + content = xmlMallocAtomic (xmlStrlen(content_line) + strlen(encoding) + 1); if (content) { strcpy ((char *)content, (char *)content_line); strcat ((char *)content, (char *)encoding); diff --git a/c14n.c b/c14n.c index cd410ccf..89589ca6 100644 --- a/c14n.c +++ b/c14n.c @@ -1854,7 +1854,7 @@ xmlC11NNormalizeString(const xmlChar * input, * allocate an translation buffer. */ buffer_size = 1000; - buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar)); if (buffer == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc failed"); return (NULL); diff --git a/catalog.c b/catalog.c index a9dc3a48..dcf255fb 100644 --- a/catalog.c +++ b/catalog.c @@ -867,7 +867,7 @@ xmlLoadFileContent(const char *filename) return (NULL); } #endif - content = xmlMalloc(size + 10); + content = xmlMallocAtomic(size + 10); if (content == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size + 10); @@ -1955,7 +1955,7 @@ xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) { } else { stop = ' '; } - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); diff --git a/encoding.c b/encoding.c index de55e2e0..de69abfd 100644 --- a/encoding.c +++ b/encoding.c @@ -283,7 +283,7 @@ xmlUTF8Strndup(const xmlChar *utf, int len) { if ((utf == NULL) || (len < 0)) return(NULL); i = xmlUTF8Strsize(utf, len); - ret = (xmlChar *) xmlMalloc((i + 1) * sizeof(xmlChar)); + ret = (xmlChar *) xmlMallocAtomic((i + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %ld byte failed\n", diff --git a/globals.c b/globals.c index c4eb3f5e..380c94e6 100644 --- a/globals.c +++ b/globals.c @@ -50,6 +50,7 @@ extern char * xmlMemoryStrdup(const char *str); xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree; xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc; +xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc; xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc; xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup; #else @@ -69,6 +70,17 @@ xmlFreeFunc xmlFree = (xmlFreeFunc) free; * Returns a pointer to the newly allocated block or NULL in case of error */ xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc; +/** + * xmlMallocAtomic: + * @size: the size requested in bytes + * + * The variable holding the libxml malloc() implementation for atomic + * data (i.e. blocks not containings pointers), useful when using a + * garbage collecting allocator. + * + * Returns a pointer to the newly allocated block or NULL in case of error + */ +xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) malloc; /** * xmlRealloc: * @mem: an already allocated block of memory @@ -120,6 +132,7 @@ xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlStrdup; #undef xmlFree #undef xmlMalloc +#undef xmlMallocAtomic #undef xmlMemStrdup #undef xmlRealloc @@ -435,11 +448,13 @@ xmlInitializeGlobalState(xmlGlobalStatePtr gs) #if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY) gs->xmlFree = (xmlFreeFunc) xmlMemFree; gs->xmlMalloc = (xmlMallocFunc) xmlMemMalloc; + gs->xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc; gs->xmlRealloc = (xmlReallocFunc) xmlMemRealloc; gs->xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup; #else gs->xmlFree = (xmlFreeFunc) free; gs->xmlMalloc = (xmlMallocFunc) malloc; + gs->xmlMallocAtomic = (xmlMallocFunc) malloc; gs->xmlRealloc = (xmlReallocFunc) realloc; gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup; #endif diff --git a/include/libxml/globals.h b/include/libxml/globals.h index 6f880c08..9a7e3d1b 100644 --- a/include/libxml/globals.h +++ b/include/libxml/globals.h @@ -45,6 +45,7 @@ extern "C" { #undef xmlLineNumbersDefaultValue #undef xmlLoadExtDtdDefaultValue #undef xmlMalloc +#undef xmlMallocAtomic #undef xmlMemStrdup #undef xmlParserDebugEntities #undef xmlParserVersion @@ -97,6 +98,8 @@ struct _xmlGlobalState xmlRegisterNodeFunc xmlRegisterNodeDefaultValue; xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue; + + xmlMallocFunc xmlMallocAtomic; }; #ifdef __cplusplus @@ -116,6 +119,7 @@ xmlDeregisterNodeFunc xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func); * In general the memory allocation entry points are not kept * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED * - xmlMalloc + * - xmlMallocAtomic * - xmlRealloc * - xmlMemStrdup * - xmlFree @@ -130,6 +134,14 @@ extern xmlMallocFunc *__xmlMalloc(void); LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc; #endif +#ifdef LIBXML_THREAD_ENABLED +extern xmlMallocFunc *__xmlMallocAtomic(void); +#define xmlMallocAtomic \ +(*(__xmlMallocAtomic())) +#else +LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMallocAtomic; +#endif + #ifdef LIBXML_THREAD_ENABLED extern xmlReallocFunc *__xmlRealloc(void); #define xmlRealloc \ @@ -153,8 +165,10 @@ extern xmlStrdupFunc *__xmlMemStrdup(void); #else LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup; #endif + #else /* !LIBXML_THREAD_ALLOC_ENABLED */ LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc; +LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMallocAtomic; LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc; LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree; LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup; diff --git a/include/libxml/xmlmemory.h b/include/libxml/xmlmemory.h index 8e8df944..f35ffffb 100644 --- a/include/libxml/xmlmemory.h +++ b/include/libxml/xmlmemory.h @@ -86,12 +86,15 @@ typedef char *(*xmlStrdupFunc)(const char *str); * The 4 interfaces used for all memory handling within libxml. LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree; LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc; +LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMallocAtomic; LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc; LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup; */ /* * The way to overload the existing functions. + * The xmlGc function have an extra entry for atomic block + * allocations useful for garbage collected memory allocators */ int xmlMemSetup (xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, @@ -101,6 +104,16 @@ int xmlMemGet (xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc, xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc); +int xmlGcMemSetup (xmlFreeFunc freeFunc, + xmlMallocFunc mallocFunc, + xmlMallocFunc mallocAtomicFunc, + xmlReallocFunc reallocFunc, + xmlStrdupFunc strdupFunc); +int xmlGcMemGet (xmlFreeFunc *freeFunc, + xmlMallocFunc *mallocFunc, + xmlMallocFunc *mallocAtomicFunc, + xmlReallocFunc *reallocFunc, + xmlStrdupFunc *strdupFunc); /* * Initialization of the memory layer. @@ -129,6 +142,16 @@ char * xmlMemoryStrdup (const char *str); * Returns the pointer to the allocated area or NULL in case of error. */ #define xmlMalloc(size) xmlMallocLoc((size), __FILE__, __LINE__) +/** + * xmlMallocAtomic: + * @size: number of bytes to allocate + * + * Wrapper for the malloc() function used in the XML library for allocation + * of block not containing pointers to other areas. + * + * Returns the pointer to the allocated area or NULL in case of error. + */ +#define xmlMallocAtomic(size) xmlMallocAtomicLoc((size), __FILE__, __LINE__) /** * xmlRealloc: * @ptr: pointer to the existing allocated area diff --git a/nanohttp.c b/nanohttp.c index 376660bc..8c5f995e 100644 --- a/nanohttp.c +++ b/nanohttp.c @@ -484,7 +484,7 @@ xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) { while (ctxt->state & XML_NANO_HTTP_READ) { if (ctxt->in == NULL) { - ctxt->in = (char *) xmlMalloc(65000 * sizeof(char)); + ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char)); if (ctxt->in == NULL) { ctxt->last = -1; xmlGenericError( xmlGenericErrorContext, @@ -1125,7 +1125,7 @@ retry: if (contentType && *contentType) blen += strlen(*contentType) + 16; blen += strlen(method) + strlen(ctxt->path) + 24; - bp = xmlMalloc(blen); + bp = xmlMallocAtomic(blen); if ( bp == NULL ) { xmlNanoHTTPFreeCtxt( ctxt ); xmlGenericError( xmlGenericErrorContext, diff --git a/parser.c b/parser.c index 19da8069..2e8021e5 100644 --- a/parser.c +++ b/parser.c @@ -777,7 +777,7 @@ xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) { return(NULL); } length = xmlStrlen(entity->name) + 5; - buffer = xmlMalloc(length); + buffer = xmlMallocAtomic(length); if (buffer == NULL) { return(NULL); } @@ -1072,7 +1072,7 @@ xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what, * allocate a translation buffer. */ buffer_size = XML_PARSER_BIG_BUFFER_SIZE; - buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar)); if (buffer == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlStringDecodeEntities: malloc failed"); @@ -1196,7 +1196,7 @@ xmlStrndup(const xmlChar *cur, int len) { xmlChar *ret; if ((cur == NULL) || (len < 0)) return(NULL); - ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar)); + ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %ld byte failed\n", @@ -1243,7 +1243,7 @@ xmlCharStrndup(const char *cur, int len) { xmlChar *ret; if ((cur == NULL) || (len < 0)) return(NULL); - ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar)); + ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %ld byte failed\n", (len + 1) * (long)sizeof(xmlChar)); @@ -1741,7 +1741,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) { */ max = len * 2; - buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, @@ -1813,7 +1813,7 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) { */ max = len * 2; - buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { if ((ctxt != NULL) && (ctxt->sax != NULL) && (ctxt->sax->error != NULL)) @@ -1987,7 +1987,7 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) { xmlChar *buffer; int max = len * 2; - buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, @@ -2073,7 +2073,7 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) { xmlChar *buffer; int max = len * 2; - buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, @@ -2153,7 +2153,7 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) { xmlChar *buffer; int max = len * 2; - buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) ctxt->sax->error(ctxt->userData, @@ -2228,7 +2228,7 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { if (ctxt->recovery == 0) ctxt->disableSAX = 1; return(NULL); } - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -2461,7 +2461,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt) { * allocate a translation buffer. */ buf_size = XML_PARSER_BUFFER_SIZE; - buf = (xmlChar *) xmlMalloc(buf_size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlParseAttValue: malloc failed"); @@ -2634,7 +2634,7 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) { return(NULL); } - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -2718,7 +2718,7 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) { if (ctxt->recovery == 0) ctxt->disableSAX = 1; return(NULL); } - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -3098,7 +3098,7 @@ xmlParseComment(xmlParserCtxtPtr ctxt) { ctxt->instate = XML_PARSER_COMMENT; SHRINK; SKIP(4); - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -3352,7 +3352,7 @@ xmlParsePI(xmlParserCtxtPtr ctxt) { xmlFree(target); return; } - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -6959,7 +6959,7 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) { } NEXTL(sl); cur = CUR_CHAR(l); - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -7291,7 +7291,7 @@ xmlParseVersionNum(xmlParserCtxtPtr ctxt) { int size = 10; xmlChar cur; - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); @@ -7413,7 +7413,7 @@ xmlParseEncName(xmlParserCtxtPtr ctxt) { cur = CUR; if (((cur >= 'a') && (cur <= 'z')) || ((cur >= 'A') && (cur <= 'Z'))) { - buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); if (buf == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc of %d byte failed\n", size); diff --git a/parserInternals.c b/parserInternals.c index 3900a0e7..741d7667 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -2519,7 +2519,7 @@ xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt, (2 * ctxt->node_seq.maximum)); if (ctxt->node_seq.buffer == NULL) - tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size); + tmp_buffer = (xmlParserNodeInfo *) xmlMallocAtomic(byte_size); else tmp_buffer = (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer, diff --git a/relaxng.c b/relaxng.c index d453b93e..c56c7ea5 100644 --- a/relaxng.c +++ b/relaxng.c @@ -8134,7 +8134,7 @@ xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar *str) { while (*tmp != 0) tmp++; len = tmp - str; - ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar)); + ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar)); if (ret == NULL) { if (ctxt != NULL) { VALID_ERR(XML_RELAXNG_ERR_MEMORY); diff --git a/tree.c b/tree.c index b18c209e..abe9cf24 100644 --- a/tree.c +++ b/tree.c @@ -156,7 +156,7 @@ xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix, lenp = strlen((char *) prefix); if ((memory == NULL) || (len < lenn + lenp + 2)) { - ret = (xmlChar *) xmlMalloc(lenn + lenp + 2); + ret = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); if (ret == NULL) return(NULL); } else { ret = memory; @@ -3977,10 +3977,10 @@ xmlGetNodePath(xmlNodePtr node) return (NULL); buf_len = 500; - buffer = (xmlChar *) xmlMalloc(buf_len * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(buf_len * sizeof(xmlChar)); if (buffer == NULL) return (NULL); - buf = (xmlChar *) xmlMalloc(buf_len * sizeof(xmlChar)); + buf = (xmlChar *) xmlMallocAtomic(buf_len * sizeof(xmlChar)); if (buf == NULL) { xmlFree(buffer); return (NULL); @@ -6087,7 +6087,7 @@ xmlBufferCreate(void) { ret->use = 0; ret->size = xmlDefaultBufferSize; ret->alloc = xmlBufferAllocScheme; - ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar)); + ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); if (ret->content == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlBufferCreate : out of memory!\n"); @@ -6119,7 +6119,7 @@ xmlBufferCreateSize(size_t size) { ret->alloc = xmlBufferAllocScheme; ret->size = (size ? size+2 : 0); /* +1 for ending null */ if (ret->size){ - ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar)); + ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); if (ret->content == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlBufferCreate : out of memory!\n"); @@ -6338,7 +6338,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) } if (buf->content == NULL) - rebuf = (xmlChar *) xmlMalloc(newSize * sizeof(xmlChar)); + rebuf = (xmlChar *) xmlMallocAtomic(newSize * sizeof(xmlChar)); else rebuf = (xmlChar *) xmlRealloc(buf->content, newSize * sizeof(xmlChar)); diff --git a/uri.c b/uri.c index ab03767f..b5d93602 100644 --- a/uri.c +++ b/uri.c @@ -227,7 +227,7 @@ xmlSaveUri(xmlURIPtr uri) { max = 80; - ret = (xmlChar *) xmlMalloc((max + 1) * sizeof(xmlChar)); + ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlSaveUri: out of memory\n"); @@ -803,7 +803,7 @@ xmlURIUnescapeString(const char *str, int len, char *target) { if (len < 0) return(NULL); if (target == NULL) { - ret = (char *) xmlMalloc(len + 1); + ret = (char *) xmlMallocAtomic(len + 1); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlURIUnescapeString: out of memory\n"); @@ -864,7 +864,7 @@ xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) { if (!(len > 0)) return(NULL); len += 20; - ret = (xmlChar *) xmlMalloc(len); + ret = (xmlChar *) xmlMallocAtomic(len); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlURIEscapeStr: out of memory\n"); @@ -1391,7 +1391,7 @@ xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash) len2 = strlen(uri->path); len += len2; } - path = (char *) xmlMalloc(len + 1); + path = (char *) xmlMallocAtomic(len + 1); if (path == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlParseURIPathSegments: out of memory\n"); @@ -1885,7 +1885,7 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) { len += strlen(ref->path); if (bas->path != NULL) len += strlen(bas->path); - res->path = (char *) xmlMalloc(len); + res->path = (char *) xmlMallocAtomic(len); if (res->path == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlBuildURI: out of memory\n"); @@ -1997,7 +1997,7 @@ xmlCanonicPath(const xmlChar *path) len = xmlStrlen(path); if ((len > 2) && IS_WINDOWS_PATH(path)) { uri->scheme = xmlStrdup(BAD_CAST "file"); - uri->path = xmlMalloc(len + 2); + uri->path = xmlMallocAtomic(len + 2); uri->path[0] = '/'; p = uri->path + 1; strncpy(p, path, len + 1); diff --git a/xmlmemory.c b/xmlmemory.c index 55276686..c8aa793e 100644 --- a/xmlmemory.c +++ b/xmlmemory.c @@ -76,6 +76,8 @@ char * xmlMemoryStrdup(const char *str); #define MALLOC_TYPE 1 #define REALLOC_TYPE 2 #define STRDUP_TYPE 3 +#define MALLOC_ATOMIC_TYPE 4 +#define REALLOC_ATOMIC_TYPE 5 typedef struct memnod { unsigned int mh_tag; @@ -205,6 +207,70 @@ xmlMallocLoc(size_t size, const char * file, int line) return(ret); } +/** + * xmlMallocAtomicLoc: + * @size: an int specifying the size in byte to allocate. + * @file: the file name or NULL + * @line: the line number + * + * a malloc() equivalent, with logging of the allocation info. + * + * Returns a pointer to the allocated area or NULL in case of lack of memory. + */ + +void * +xmlMallocAtomicLoc(size_t size, const char * file, int line) +{ + MEMHDR *p; + void *ret; + + if (!xmlMemInitialized) xmlInitMemory(); +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "Malloc(%d)\n",size); +#endif + + TEST_POINT + + p = (MEMHDR *) malloc(RESERVE_SIZE+size); + + if (!p) { + xmlGenericError(xmlGenericErrorContext, + "xmlMallocLoc : Out of free space\n"); + xmlMemoryDump(); + return(NULL); + } + p->mh_tag = MEMTAG; + p->mh_number = ++block; + p->mh_size = size; + p->mh_type = MALLOC_ATOMIC_TYPE; + p->mh_file = file; + p->mh_line = line; + debugMemSize += size; + if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; +#ifdef MEM_LIST + debugmem_list_add(p); +#endif + +#ifdef DEBUG_MEMORY + xmlGenericError(xmlGenericErrorContext, + "Malloc(%d) Ok\n",size); +#endif + + if (xmlMemStopAtBlock == block) xmlMallocBreakpoint(); + + ret = HDR_2_CLIENT(p); + + if (xmlMemTraceBlockAt == ret) { + xmlGenericError(xmlGenericErrorContext, + "%p : Malloc(%d) Ok\n", xmlMemTraceBlockAt, size); + xmlMallocBreakpoint(); + } + + TEST_POINT + + return(ret); +} /** * xmlMemMalloc: * @size: an int specifying the size in byte to allocate. @@ -523,8 +589,10 @@ xmlMemShow(FILE *fp, int nr) switch (p->mh_type) { case STRDUP_TYPE:fprintf(fp,"strdup() in ");break; case MALLOC_TYPE:fprintf(fp,"malloc() in ");break; + case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break; case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; - default:fprintf(fp," ??? in ");break; + case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break; + default:fprintf(fp," ??? in ");break; } if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line); @@ -578,6 +646,8 @@ xmlMemDisplay(FILE *fp) case STRDUP_TYPE:fprintf(fp,"strdup() in ");break; case MALLOC_TYPE:fprintf(fp,"malloc() in ");break; case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; + case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break; + case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break; default:fprintf(fp," ??? in ");break; } if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line); @@ -747,6 +817,7 @@ xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, return(-1); xmlFree = freeFunc; xmlMalloc = mallocFunc; + xmlMallocAtomic = mallocFunc; xmlRealloc = reallocFunc; xmlMemStrdup = strdupFunc; return(0); @@ -773,3 +844,69 @@ xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc, return(0); } +/** + * xmlGcMemSetup: + * @freeFunc: the free() function to use + * @mallocFunc: the malloc() function to use + * @mallocAtomicFunc: the malloc() function to use for atomic allocations + * @reallocFunc: the realloc() function to use + * @strdupFunc: the strdup() function to use + * + * Override the default memory access functions with a new set + * This has to be called before any other libxml routines ! + * The mallocAtomicFunc is specialized for atomic block + * allocations (i.e. of areas useful for garbage collected memory allocators + * + * Should this be blocked if there was already some allocations + * done ? + * + * Returns 0 on success + */ +int +xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, + xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc, + xmlStrdupFunc strdupFunc) { + if (freeFunc == NULL) + return(-1); + if (mallocFunc == NULL) + return(-1); + if (mallocAtomicFunc == NULL) + return(-1); + if (reallocFunc == NULL) + return(-1); + if (strdupFunc == NULL) + return(-1); + xmlFree = freeFunc; + xmlMalloc = mallocFunc; + xmlMallocAtomic = mallocAtomicFunc; + xmlRealloc = reallocFunc; + xmlMemStrdup = strdupFunc; + return(0); +} + +/** + * xmlGcMemGet: + * @freeFunc: place to save the free() function in use + * @mallocFunc: place to save the malloc() function in use + * @mallocAtomicFunc: place to save the atomic malloc() function in use + * @reallocFunc: place to save the realloc() function in use + * @strdupFunc: place to save the strdup() function in use + * + * Provides the memory access functions set currently in use + * The mallocAtomicFunc is specialized for atomic block + * allocations (i.e. of areas useful for garbage collected memory allocators + * + * Returns 0 on success + */ +int +xmlGcMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc, + xmlMallocFunc *mallocAtomicFunc, xmlReallocFunc *reallocFunc, + xmlStrdupFunc *strdupFunc) { + if (freeFunc != NULL) *freeFunc = xmlFree; + if (mallocFunc != NULL) *mallocFunc = xmlMalloc; + if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic; + if (reallocFunc != NULL) *reallocFunc = xmlRealloc; + if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup; + return(0); +} + diff --git a/xmlreader.c b/xmlreader.c index 73e5deb5..6cdadc97 100644 --- a/xmlreader.c +++ b/xmlreader.c @@ -2633,7 +2633,7 @@ xmlTextReaderBuildMessage(const char *msg, va_list ap) { char *larger; char *str; - str = (char *) xmlMalloc(150); + str = (char *) xmlMallocAtomic(150); if (str == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n"); return NULL; diff --git a/xmlregexp.c b/xmlregexp.c index c2762b6b..8f1e9c1d 100644 --- a/xmlregexp.c +++ b/xmlregexp.c @@ -2792,7 +2792,7 @@ xmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value, lenp = strlen((char *) value); if (150 < lenn + lenp + 2) { - str = (xmlChar *) xmlMalloc(lenn + lenp + 2); + str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); if (str == NULL) { exec->status = -1; return(-1); @@ -4114,7 +4114,7 @@ xmlAutomataNewTransition2(xmlAutomataPtr am, xmlAutomataStatePtr from, lenn = strlen((char *) token2); lenp = strlen((char *) token); - str = (xmlChar *) xmlMalloc(lenn + lenp + 2); + str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2); if (str == NULL) { xmlRegFreeAtom(atom); return(NULL); diff --git a/xpath.c b/xpath.c index 6aca0798..67d835be 100644 --- a/xpath.c +++ b/xpath.c @@ -7319,7 +7319,7 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { xmlChar *buffer; int max = len * 2; - buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar)); if (buffer == NULL) { XP_ERROR0(XPATH_MEMORY_ERROR); } diff --git a/xpointer.c b/xpointer.c index 018084ea..b9164b17 100644 --- a/xpointer.c +++ b/xpointer.c @@ -940,7 +940,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { len = xmlStrlen(ctxt->cur); len++; - buffer = (xmlChar *) xmlMalloc(len * sizeof (xmlChar)); + buffer = (xmlChar *) xmlMallocAtomic(len * sizeof (xmlChar)); if (buffer == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlXPtrEvalXPtrPart: out of memory\n");