Bug 441324, part 2: Implement libmozalloc with support for fallible and infallible malloc et al. and |operator new|s. r=bsmedberg
authorChris Jones <jones.chris.g@gmail.com>
Wed, 03 Mar 2010 23:02:56 -0600
changeset 38923 5257693bcfbf901398bce97f823b5ba95b43dd53
parent 38922 d8c18f04396efc787769bd54998d3ea6fa48e97e
child 38924 81bd90ae58996af98822ee4fe1cacc35f328ca95
push idunknown
push userunknown
push dateunknown
reviewersbsmedberg
bugs441324
milestone1.9.3a3pre
Bug 441324, part 2: Implement libmozalloc with support for fallible and infallible malloc et al. and |operator new|s. r=bsmedberg
memory/Makefile.in
memory/mozalloc/Makefile.in
memory/mozalloc/mozalloc.cpp
memory/mozalloc/mozalloc.h
memory/mozalloc/mozalloc_macro_wrappers.h
memory/mozalloc/mozalloc_oom.cpp
memory/mozalloc/mozalloc_oom.h
new file mode 100644
--- /dev/null
+++ b/memory/Makefile.in
@@ -0,0 +1,52 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Mozilla platform.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation <http://www.mozilla.org/>.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS =
+
+ifdef MOZ_MEMORY
+DIRS += jemalloc
+endif
+
+DIRS += mozalloc
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/memory/mozalloc/Makefile.in
@@ -0,0 +1,66 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Ted Mielczarek <ted.mielczarek@gmail.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+VISIBILITY_FLAGS=
+
+MODULE		= mozalloc
+LIBRARY_NAME	= mozalloc
+FORCE_SHARED_LIB= 1
+DIST_INSTALL 	= 1
+
+# The wince shunt relies on this library in a somewhat complicated
+# way.  In wince builds, jemalloc replaces the wince libc allocators
+# and moz_* will end up using those symbols at run time.
+export NO_SHUNT	= 1
+
+EXPORTS_NAMESPACES 	= mozilla
+EXPORTS_mozilla 	= mozalloc.h mozalloc_macro_wrappers.h mozalloc_oom.h
+
+CPPSRCS =					\
+	mozalloc.cpp				\
+	mozalloc_oom.cpp			\
+	$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/memory/mozalloc/mozalloc.cpp
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <errno.h>
+#include <new>                  // for std::bad_alloc
+#include <string.h>
+
+#if defined(MALLOC_H)
+#  include MALLOC_H             // for memalign, valloc where available
+#endif // if defined(MALLOC_H)
+#include <stddef.h>             // for size_t
+#include <stdlib.h>             // for malloc, free
+
+// Make sure that "malloc" et al. resolve to their libc variants.
+#define MOZALLOC_DONT_DEFINE_MACRO_WRAPPERS
+#include "mozilla/mozalloc.h"
+#include "mozilla/mozalloc_oom.h"  // for mozalloc_handle_oom
+
+
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define LIKELY(x)    (__builtin_expect(!!(x), 1))
+#define UNLIKELY(x)  (__builtin_expect(!!(x), 0))
+#else
+#define LIKELY(x)    (x)
+#define UNLIKELY(x)  (x)
+#endif
+
+
+void
+moz_free(void* ptr)
+{
+    free(ptr);
+}
+
+void*
+moz_xmalloc(size_t size)
+{
+    void* ptr = malloc(size);
+    if (UNLIKELY(!ptr)) {
+        mozalloc_handle_oom();
+        return moz_xmalloc(size);
+    }
+    return ptr;
+}
+void*
+moz_malloc(size_t size)
+{
+    return malloc(size);
+}
+
+void*
+moz_xcalloc(size_t nmemb, size_t size)
+{
+    void* ptr = calloc(nmemb, size);
+    if (UNLIKELY(!ptr)) {
+        mozalloc_handle_oom();
+        return moz_xcalloc(nmemb, size);
+    }
+    return ptr;
+}
+void*
+moz_calloc(size_t nmemb, size_t size)
+{
+    return calloc(nmemb, size);
+}
+
+void*
+moz_xrealloc(void* ptr, size_t size)
+{
+    void* newptr = realloc(ptr, size);
+    if (UNLIKELY(!newptr)) {
+        mozalloc_handle_oom();
+        return moz_xrealloc(ptr, size);
+    }
+    return newptr;
+}
+void*
+moz_realloc(void* ptr, size_t size)
+{
+    return realloc(ptr, size);
+}
+
+char*
+moz_xstrdup(const char* str)
+{
+    char* dup = strdup(str);
+    if (UNLIKELY(!dup)) {
+        mozalloc_handle_oom();
+        return moz_xstrdup(str);
+    }
+    return dup;
+}
+char*
+moz_strdup(const char* str)
+{
+    return strdup(str);
+}
+
+#if defined(HAVE_STRNDUP)
+char*
+moz_xstrndup(const char* str, size_t strsize)
+{
+    char* dup = strndup(str, strsize);
+    if (UNLIKELY(!dup)) {
+        mozalloc_handle_oom();
+        return moz_xstrndup(str, strsize);
+    }
+    return dup;
+}
+char*
+moz_strndup(const char* str, size_t strsize)
+{
+    return strndup(str, strsize);
+}
+#endif  // if defined(HAVE_STRNDUP)
+
+#if defined(HAVE_POSIX_MEMALIGN)
+int
+moz_xposix_memalign(void **ptr, size_t alignment, size_t size)
+{
+    int err = posix_memalign(ptr, alignment, size);
+    if (UNLIKELY(err && ENOMEM == err)) {
+        mozalloc_handle_oom();
+        return moz_xposix_memalign(ptr, alignment, size);
+    }
+    // else: (0 == err) or (EINVAL == err)
+    return err;
+}
+int
+moz_posix_memalign(void **ptr, size_t alignment, size_t size)
+{
+    return posix_memalign(ptr, alignment, size);
+}
+#endif // if defined(HAVE_POSIX_MEMALIGN)
+
+#if defined(HAVE_MEMALIGN)
+void*
+moz_xmemalign(size_t boundary, size_t size)
+{
+    void* ptr = memalign(boundary, size);
+    if (UNLIKELY(!ptr && EINVAL != errno)) {
+        mozalloc_handle_oom();
+        return moz_xmemalign(boundary, size);
+    }
+    // non-NULL ptr or errno == EINVAL
+    return ptr;
+}
+void*
+moz_memalign(size_t boundary, size_t size)
+{
+    return memalign(boundary, size);
+}
+#endif // if defined(HAVE_MEMALIGN)
+
+#if defined(HAVE_VALLOC)
+void*
+moz_xvalloc(size_t size)
+{
+    void* ptr = valloc(size);
+    if (UNLIKELY(!ptr)) {
+        mozalloc_handle_oom();
+        return moz_xvalloc(size);
+    }
+    return ptr;
+}
+void*
+moz_valloc(size_t size)
+{
+    return valloc(size);
+}
+#endif // if defined(HAVE_VALLOC)
+
+
+namespace mozilla {
+
+const fallible_t fallible = fallible_t();
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/memory/mozalloc/mozalloc.h
@@ -0,0 +1,290 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_mozalloc_h
+#define mozilla_mozalloc_h
+
+
+/*
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=427099
+ */
+
+/* 
+ * NB: this header depends on the symbols malloc(), free(), and
+ * std::bad_alloc.  But because this header is used in situations
+ * where malloc/free have different visibility, we rely on code
+ * including this header to provide the declarations of malloc/free.
+ * I.e., we don't #include <stdlib.h> or <new> on purpose.
+ */
+
+#if defined(XP_WIN) || (defined(XP_OS2) && defined(__declspec))
+#  define MOZALLOC_EXPORT __declspec(dllexport)
+#elif defined(HAVE_VISIBILITY_ATTRIBUTE)
+/* Make sure symbols are still exported even if we're wrapped in a
+ * |visibility push(hidden)| blanket. */
+#  define MOZALLOC_EXPORT __attribute__ ((visibility ("default")))
+#else
+#  define MOZALLOC_EXPORT
+#endif
+
+
+#if defined(NS_ALWAYS_INLINE)
+#  define MOZALLOC_INLINE NS_ALWAYS_INLINE inline
+#elif defined(HAVE_FORCEINLINE)
+#  define MOZALLOC_INLINE __forceinline
+#else
+#  define MOZALLOC_INLINE inline
+#endif
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* ifdef __cplusplus */
+
+
+/* 
+ * If we don't have these system functions, but do have jemalloc
+ * replacements, go ahead and declare them independently of jemalloc.
+ * Trying to #include the jemalloc header causes redeclaration of some
+ * system functions with different visibility.
+ */
+/* FIXME/cjones: make something like the following work with jemalloc */
+#if 0
+#if !defined(HAVE_POSIX_MEMALIGN) && defined(HAVE_JEMALLOC_POSIX_MEMALIGN)
+MOZALLOC_IMPORT int posix_memalign(void **, size_t, size_t)
+    NS_WARN_UNUSED_RESULT;
+#endif
+#endif
+
+
+/*
+ * Each pair of declarations below is analogous to a "standard"
+ * allocation function, except that the out-of-memory handling is made
+ * explicit.  The |moz_x| versions will never return a NULL pointer;
+ * if memory is exhausted, they abort.  The |moz_| versions may return
+ * NULL pointers if memory is exhausted: their return value must be
+ * checked.
+ *
+ * All these allocation functions are *guaranteed* to return a pointer
+ * to memory allocated in such a way that that memory can be freed by
+ * passing that pointer to |moz_free()|.
+ */
+
+MOZALLOC_EXPORT
+void moz_free(void* ptr);
+
+MOZALLOC_EXPORT void* moz_xmalloc(size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT
+void* moz_malloc(size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+
+MOZALLOC_EXPORT void* moz_xcalloc(size_t nmemb, size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT void* moz_calloc(size_t nmemb, size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+
+MOZALLOC_EXPORT void* moz_xrealloc(void* ptr, size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT void* moz_realloc(void* ptr, size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+
+MOZALLOC_EXPORT char* moz_xstrdup(const char* str)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT char* moz_strdup(const char* str)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+
+#if defined(HAVE_STRNDUP)
+MOZALLOC_EXPORT char* moz_xstrndup(const char* str, size_t strsize)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT char* moz_strndup(const char* str, size_t strsize)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+#endif /* if defined(HAVE_STRNDUP) */
+
+
+#if defined(HAVE_POSIX_MEMALIGN)
+MOZALLOC_EXPORT int moz_xposix_memalign(void **ptr, size_t alignment, size_t size)
+    NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT int moz_posix_memalign(void **ptr, size_t alignment, size_t size)
+    NS_WARN_UNUSED_RESULT;
+#endif /* if defined(HAVE_POSIX_MEMALIGN) */
+
+
+#if defined(HAVE_MEMALIGN)
+MOZALLOC_EXPORT void* moz_xmemalign(size_t boundary, size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT void* moz_memalign(size_t boundary, size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+#endif /* if defined(HAVE_MEMALIGN) */
+
+
+#if defined(HAVE_VALLOC)
+MOZALLOC_EXPORT void* moz_xvalloc(size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+
+MOZALLOC_EXPORT void* moz_valloc(size_t size)
+    NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
+#endif /* if defined(HAVE_VALLOC) */
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* ifdef __cplusplus */
+
+
+#ifdef __cplusplus
+
+/*
+ * We implement the default operators new/delete as part of
+ * libmozalloc, replacing their definitions in libstdc++.  The
+ * operator new* definitions in libmozalloc will never return a NULL
+ * pointer.
+ *
+ * Each operator new immediately below returns a pointer to memory
+ * that can be delete'd by any of
+ *
+ *   (1) the matching infallible operator delete immediately below
+ *   (2) the matching "fallible" operator delete further below
+ *   (3) the matching system |operator delete(void*, std::nothrow)|
+ *   (4) the matching system |operator delete(void*) throw(std::bad_alloc)|
+ *
+ * NB: these are declared |throw(std::bad_alloc)|, though they will never
+ * throw that exception.  This declaration is consistent with the rule
+ * that |::operator new() throw(std::bad_alloc)| will never return NULL.
+ */
+
+/* NB: This is defined just to silence vacuous warnings about symbol
+ * visibility on OS X/gcc. These symbols are force-inline and not
+ * exported. */
+#if defined(XP_MACOSX)
+#  define MOZALLOC_EXPORT_NEW MOZALLOC_EXPORT
+#else
+#  define MOZALLOC_EXPORT_NEW
+#endif
+
+MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
+void* operator new(size_t size) throw()
+{
+    return moz_xmalloc(size);
+}
+
+MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
+void* operator new[](size_t size) throw()
+{
+    return moz_xmalloc(size);
+}
+
+MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
+void operator delete(void* ptr) throw()
+{
+    return moz_free(ptr);
+}
+
+MOZALLOC_EXPORT_NEW MOZALLOC_INLINE
+void operator delete[](void* ptr) throw()
+{
+    return moz_free(ptr);
+}
+
+
+/*
+ * We also add a new allocator variant: "fallible operator new."
+ * Unlike libmozalloc's implementations of the standard nofail
+ * allocators, this allocator is allowed to return NULL.  It can be used
+ * as follows
+ *
+ *   Foo* f = new (mozilla::fallible) Foo(...);
+ *
+ * operator delete(fallible) is defined for completeness only.
+ *
+ * Each operator new below returns a pointer to memory that can be
+ * delete'd by any of
+ *
+ *   (1) the matching "fallible" operator delete below
+ *   (2) the matching infallible operator delete above
+ *   (3) the matching system |operator delete(void*, std::nothrow)|
+ *   (4) the matching system |operator delete(void*) throw(std::bad_alloc)|
+ */
+
+namespace mozilla {
+
+struct MOZALLOC_EXPORT fallible_t { };
+
+} /* namespace mozilla */
+
+MOZALLOC_INLINE
+void* operator new(size_t size, const mozilla::fallible_t&) throw()
+{
+    return moz_malloc(size);
+}
+
+MOZALLOC_INLINE
+void* operator new[](size_t size, const mozilla::fallible_t&) throw()
+{
+    return moz_malloc(size);
+}
+
+MOZALLOC_INLINE
+void operator delete(void* ptr, const mozilla::fallible_t&) throw()
+{
+    moz_free(ptr);
+}
+
+MOZALLOC_INLINE
+void operator delete[](void* ptr, const mozilla::fallible_t&) throw()
+{
+    moz_free(ptr);
+}
+
+#endif  /* ifdef __cplusplus */
+
+
+#endif /* ifndef mozilla_mozalloc_h */
new file mode 100644
--- /dev/null
+++ b/memory/mozalloc/mozalloc_macro_wrappers.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_mozalloc_macro_wrappers_h
+#define mozilla_mozalloc_macro_wrappers_h
+
+
+/*
+ * Make libc "allocating functions" never fail (return NULL).
+ *
+ * FIXME: use infallible allocators by default after 
+ *   http://bugzilla.mozilla.org/show_bug.cgi?id=507249
+ * lands.
+ */
+#define free(_) moz_free(_)
+
+#define malloc(_) moz_malloc(_)
+
+#define calloc(_, __) moz_calloc(_, __)
+
+#define realloc(_, __) moz_realloc(_, __)
+
+#define strdup(_) moz_strdup(_)
+
+#if defined(HAVE_STRNDUP)
+#define strndup(_, __) moz_strndup(_, __)
+#endif
+
+#if defined(HAVE_POSIX_MEMALIGN)
+#define posix_memalign(_, __, ___) moz_posix_memalign(_, __, ___)
+#endif
+
+#if defined(HAVE_MEMALIGN)
+#define memalign(_, __) moz_memalign(_, __)
+#endif
+
+#if defined(HAVE_VALLOC)
+#define valloc(_) moz_valloc(_)
+#endif
+
+
+#endif /* ifndef mozilla_mozalloc_macro_wrappers_h */
new file mode 100644
--- /dev/null
+++ b/memory/mozalloc/mozalloc_oom.cpp
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>             // for abort()
+
+#if defined(_WIN32)
+#  include <signal.h>           // for raise
+#elif defined(XP_UNIX)
+#  include <unistd.h>           // for _exit
+#endif
+
+#include "mozilla/mozalloc_oom.h"
+
+static int gDummyCounter;
+
+void
+mozalloc_handle_oom()
+{
+    // NB: this is handle_oom() stage 1, which simply aborts on OOM.
+    // we might proceed to a stage 2 in which an attempt is made to
+    // reclaim memory
+
+    // XXX/cjones: most of this function was copied from
+    // xpcom/base/nsDebugImpl.cpp:Abort(), except that we assume on
+    // UNIX-like platforms can directly abort() rather than need to go
+    // through PR_Abort(). we don't want this code to rely on NSPR.
+
+#if defined(_WIN32)
+#  if !defined(WINCE)
+    //This should exit us
+    raise(SIGABRT);
+#  endif
+    //If we are ignored exit this way..
+    _exit(3);
+#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+    abort();
+#else
+#  warning not attempting to abort() on this platform
+#endif
+
+    // Still haven't aborted?  Try dereferencing null.
+    // (Written this way to lessen the likelihood of it being optimized away.)
+    gDummyCounter += *((int*) 0); // TODO annotation saying we know 
+    // this is crazy
+    
+    // Still haven't aborted?  Try _exit().
+    _exit(127);
+}
new file mode 100644
--- /dev/null
+++ b/memory/mozalloc/mozalloc_oom.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: sw=4 ts=4 et :
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_mozalloc_oom_h
+#define mozilla_mozalloc_oom_h
+
+
+#if defined(XP_WIN) || (defined(XP_OS2) && defined(__declspec))
+#  define MOZALLOC_EXPORT __declspec(dllexport)
+#elif defined(HAVE_VISIBILITY_ATTRIBUTE)
+/* Make sure symbols are still exported even if we're wrapped in a
+ * |visibility push(hidden)| blanket. */
+#  define MOZALLOC_EXPORT __attribute__ ((visibility ("default")))
+#else
+#  define MOZALLOC_EXPORT
+#endif
+
+
+/**
+ * Called when memory is critically low.  Returns iff it was able to 
+ * remedy the critical memory situation; if not, it will abort().
+ * 
+ * We have to re-#define MOZALLOC_EXPORT because this header can be
+ * used indepedently of mozalloc.h.
+ */
+MOZALLOC_EXPORT void mozalloc_handle_oom();
+
+
+/* TODO: functions to query system memory usage and register
+ * critical-memory handlers. */
+
+
+#endif /* ifndef mozilla_mozalloc_oom_h */