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
diff --git a/ChangeLog b/ChangeLog
index 2944668..c76b48e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Sat Apr 19 02:03:24 CEST 2003 Daniel Veillard <daniel@veillard.com>
+
+	* 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 <daniel@veillard.com>
 
 	* configure.in: switched to have thread support enabled by default,
diff --git a/DOCBparser.c b/DOCBparser.c
index 232c5a5..5a811cb 100644
--- a/DOCBparser.c
+++ b/DOCBparser.c
@@ -2682,7 +2682,7 @@
      * 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 @@
 		}
 
 	    }
-	    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 @@
     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 86c575f..572a750 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -2268,7 +2268,7 @@
 	    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 @@
      * 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 @@
     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 @@
     
     /* 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 cd410cc..89589ca 100644
--- a/c14n.c
+++ b/c14n.c
@@ -1854,7 +1854,7 @@
      * 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 a9dc3a4..dcf255f 100644
--- a/catalog.c
+++ b/catalog.c
@@ -867,7 +867,7 @@
         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 @@
     } 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 de55e2e..de69abf 100644
--- a/encoding.c
+++ b/encoding.c
@@ -283,7 +283,7 @@
     
     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 c4eb3f5..380c94e 100644
--- a/globals.c
+++ b/globals.c
@@ -50,6 +50,7 @@
 
 xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
 xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
+xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
 xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
 xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
 #else
@@ -70,6 +71,17 @@
  */
 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
  * @size:  the new size requested in bytes
@@ -120,6 +132,7 @@
 
 #undef	xmlFree
 #undef	xmlMalloc
+#undef	xmlMallocAtomic
 #undef	xmlMemStrdup
 #undef	xmlRealloc
 
@@ -435,11 +448,13 @@
 #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 6f880c0..9a7e3d1 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -45,6 +45,7 @@
 #undef	xmlLineNumbersDefaultValue
 #undef	xmlLoadExtDtdDefaultValue
 #undef	xmlMalloc
+#undef	xmlMallocAtomic
 #undef	xmlMemStrdup
 #undef	xmlParserDebugEntities
 #undef	xmlParserVersion
@@ -97,6 +98,8 @@
 
   	xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
   	xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
+
+	xmlMallocFunc xmlMallocAtomic;
 };
 
 #ifdef __cplusplus
@@ -116,6 +119,7 @@
  * 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
@@ -131,6 +135,14 @@
 #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 \
 (*(__xmlRealloc()))
@@ -153,8 +165,10 @@
 #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 8e8df94..f35ffff 100644
--- a/include/libxml/xmlmemory.h
+++ b/include/libxml/xmlmemory.h
@@ -86,12 +86,15 @@
  * 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 @@
 			 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.
@@ -130,6 +143,16 @@
  */
 #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
  * @size:  number of bytes to allocate
diff --git a/nanohttp.c b/nanohttp.c
index 376660b..8c5f995 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -484,7 +484,7 @@
 
     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 @@
     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 19da806..2e8021e 100644
--- a/parser.c
+++ b/parser.c
@@ -777,7 +777,7 @@
 	return(NULL);
     }
     length = xmlStrlen(entity->name) + 5;
-    buffer = xmlMalloc(length);
+    buffer = xmlMallocAtomic(length);
     if (buffer == NULL) {
     	return(NULL);
     }
@@ -1072,7 +1072,7 @@
      * 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 @@
     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 @@
     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 @@
 	 */
 	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 @@
 	     */
 	    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 @@
 	    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 @@
 	    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 @@
 	    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 @@
 	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 @@
      * 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 @@
 	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 @@
 	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 @@
     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 @@
 		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 @@
     }
     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 @@
     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 @@
     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 3900a0e..741d766 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -2519,7 +2519,7 @@
 			(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 d453b93..c56c7ea 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -8134,7 +8134,7 @@
     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 b18c209..abe9cf2 100644
--- a/tree.c
+++ b/tree.c
@@ -156,7 +156,7 @@
     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 @@
         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 @@
     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 @@
     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 @@
     }
 
     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 ab03767..b5d9360 100644
--- a/uri.c
+++ b/uri.c
@@ -227,7 +227,7 @@
 
 
     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 @@
     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 @@
     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 @@
             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 @@
 	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 @@
     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 5527668..c8aa793 100644
--- a/xmlmemory.c
+++ b/xmlmemory.c
@@ -76,6 +76,8 @@
 #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;
@@ -206,6 +208,70 @@
 }
 
 /**
+ * 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 @@
 	    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 @@
            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 @@
 	return(-1);
     xmlFree = freeFunc;
     xmlMalloc = mallocFunc;
+    xmlMallocAtomic = mallocFunc;
     xmlRealloc = reallocFunc;
     xmlMemStrdup = strdupFunc;
     return(0);
@@ -773,3 +844,69 @@
     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 73e5deb..6cdadc9 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -2633,7 +2633,7 @@
     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 c2762b6..8f1e9c1 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -2792,7 +2792,7 @@
     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 @@
 	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 6aca079..67d835b 100644
--- a/xpath.c
+++ b/xpath.c
@@ -7319,7 +7319,7 @@
 	    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 018084e..b9164b1 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -940,7 +940,7 @@
 
     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");