Bug 1125185 - Define MOZ_COLD for marking "cold" functions r=waldo
authorDan Gohman <sunfish@mozilla.com>
Mon, 26 Jan 2015 17:30:19 -0800
changeset 254685 780d7bb5eb822d16e34233005dd71fce07a0586c
parent 254684 17934cf98597980544700323ce132830cfcb03b2
child 254686 ead7aa880dbe3c021242b5cd1333945e5937c501
push id721
push userjlund@mozilla.com
push dateTue, 21 Apr 2015 23:03:33 +0000
treeherdermozilla-release@d27c9211ebb3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs1125185
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1125185 - Define MOZ_COLD for marking "cold" functions r=waldo
js/public/Utility.h
js/src/ds/LifoAlloc.h
js/src/gc/StoreBuffer.h
js/src/jsinfer.h
js/src/jsutil.cpp
js/src/jsutil.h
js/src/vm/Runtime.h
mfbt/Assertions.h
mfbt/Attributes.h
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -48,17 +48,17 @@ namespace js {}
 #define JS_ALLOCATED_TENURED_PATTERN 0x4D
 #define JS_EMPTY_STOREBUFFER_PATTERN 0x1B
 #define JS_SWEPT_CODE_PATTERN 0x3B
 #define JS_SWEPT_FRAME_PATTERN 0x5B
 
 #define JS_STATIC_ASSERT(cond)           static_assert(cond, "JS_STATIC_ASSERT")
 #define JS_STATIC_ASSERT_IF(cond, expr)  MOZ_STATIC_ASSERT_IF(cond, expr, "JS_STATIC_ASSERT_IF")
 
-extern MOZ_NORETURN JS_PUBLIC_API(void)
+extern MOZ_NORETURN MOZ_COLD JS_PUBLIC_API(void)
 JS_Assert(const char *s, const char *file, int ln);
 
 /*
  * Custom allocator support for SpiderMonkey
  */
 #if defined JS_USE_CUSTOM_ALLOCATOR
 # include "jscustomallocator.h"
 #else
--- a/js/src/ds/LifoAlloc.h
+++ b/js/src/ds/LifoAlloc.h
@@ -143,19 +143,16 @@ class BumpChunk
     }
 
     static BumpChunk *new_(size_t chunkSize);
     static void delete_(BumpChunk *chunk);
 };
 
 } // namespace detail
 
-MOZ_NORETURN void
-CrashAtUnhandlableOOM(const char *reason);
-
 // LIFO bump allocator: used for phase-oriented and fast LIFO allocations.
 //
 // Note: |latest| is not necessary "last". We leave BumpChunks latent in the
 // chain after they've been released to avoid thrashing before a GC.
 class LifoAlloc
 {
     typedef detail::BumpChunk BumpChunk;
 
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -14,20 +14,16 @@
 #include "jsalloc.h"
 
 #include "ds/LifoAlloc.h"
 #include "gc/Nursery.h"
 #include "gc/Tracer.h"
 #include "js/MemoryMetrics.h"
 
 namespace js {
-
-MOZ_NORETURN void
-CrashAtUnhandlableOOM(const char *reason);
-
 namespace gc {
 
 /*
  * BufferableRef represents an abstract reference for use in the generational
  * GC's remembered set. Entries in the store buffer that cannot be represented
  * with the simple pointer-to-a-pointer scheme must derive from this class and
  * use the generic store buffer interface.
  */
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -1768,17 +1768,17 @@ inline const char * InferSpewColor(TypeC
 inline const char * InferSpewColor(TypeSet *types) { return nullptr; }
 inline void InferSpew(SpewChannel which, const char *fmt, ...) {}
 inline const char * TypeString(Type type) { return nullptr; }
 inline const char * TypeObjectString(TypeObject *type) { return nullptr; }
 
 #endif
 
 /* Print a warning, dump state and abort the program. */
-MOZ_NORETURN void TypeFailure(JSContext *cx, const char *fmt, ...);
+MOZ_NORETURN MOZ_COLD void TypeFailure(JSContext *cx, const char *fmt, ...);
 
 } /* namespace types */
 } /* namespace js */
 
 // JS::ubi::Nodes can point to js::LazyScripts; they're js::gc::Cell instances
 // with no associated compartment.
 namespace JS {
 namespace ubi {
--- a/js/src/jsutil.cpp
+++ b/js/src/jsutil.cpp
@@ -45,17 +45,17 @@ JS_Assert(const char *s, const char *fil
 #include <malloc.h>
 #include <stdlib.h>
 
 namespace js {
 
 // This function calls all the vanilla heap allocation functions.  It is never
 // called, and exists purely to help config/check_vanilla_allocations.py.  See
 // that script for more details.
-extern void
+extern MOZ_COLD void
 AllTheNonBasicVanillaNewAllocations()
 {
     // posix_memalign and aligned_alloc aren't available on all Linux
     // configurations.
     // valloc was deprecated in Android 5.0
     //char *q;
     //posix_memalign((void**)&q, 16, 16);
 
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -38,16 +38,19 @@ js_memcpy(void *dst_, const void *src_, 
     MOZ_ASSERT_IF(dst >= src, (size_t) (dst - src) >= len);
     MOZ_ASSERT_IF(src >= dst, (size_t) (src - dst) >= len);
 
     return memcpy(dst, src, len);
 }
 
 namespace js {
 
+MOZ_NORETURN MOZ_COLD void
+CrashAtUnhandlableOOM(const char *reason);
+
 template <class T>
 struct AlignmentTestStruct
 {
     char c;
     T t;
 };
 
 /* This macro determines the alignment requirements of a type. */
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -58,23 +58,23 @@ class TraceLoggerThread;
 
 /* Thread Local Storage slot for storing the runtime for a thread. */
 extern mozilla::ThreadLocal<PerThreadData*> TlsPerThreadData;
 
 } // namespace js
 
 struct DtoaState;
 
-extern void
+extern MOZ_COLD void
 js_ReportOutOfMemory(js::ExclusiveContext *cx);
 
-extern void
+extern MOZ_COLD void
 js_ReportAllocationOverflow(js::ExclusiveContext *maybecx);
 
-extern void
+extern MOZ_COLD void
 js_ReportOverRecursed(js::ExclusiveContext *cx);
 
 namespace js {
 
 class Activation;
 class ActivationIterator;
 class AsmJSActivation;
 class AsmJSModule;
--- a/mfbt/Assertions.h
+++ b/mfbt/Assertions.h
@@ -126,34 +126,34 @@ extern "C" {
 /*
  * Prints |aStr| as an assertion failure (using aFilename and aLine as the
  * location of the assertion) to the standard debug-output channel.
  *
  * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method.  This
  * method is primarily for internal use in this header, and only secondarily
  * for use in implementing release-build assertions.
  */
-static MOZ_ALWAYS_INLINE void
+static MOZ_COLD MOZ_ALWAYS_INLINE void
 MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine)
   MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
 {
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert",
                       "Assertion failure: %s, at %s:%d\n",
                       aStr, aFilename, aLine);
 #else
   fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine);
 #ifdef MOZ_DUMP_ASSERTION_STACK
   nsTraceRefcnt::WalkTheStack(stderr);
 #endif
   fflush(stderr);
 #endif
 }
 
-static MOZ_ALWAYS_INLINE void
+static MOZ_COLD MOZ_ALWAYS_INLINE void
 MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine)
   MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
 {
 #ifdef ANDROID
   __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
                       "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine);
 #else
   fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine);
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -186,16 +186,37 @@
  * This modifier does not affect the corresponding function's linking behavior.
  */
 #if defined(MOZ_HAVE_NORETURN)
 #  define MOZ_NORETURN          MOZ_HAVE_NORETURN
 #else
 #  define MOZ_NORETURN          /* no support */
 #endif
 
+/**
+ * MOZ_COLD tells the compiler that a function is "cold", meaning infrequently
+ * executed. This may lead it to optimize for size more aggressively than speed,
+ * or to allocate the body of the function in a distant part of the text segment
+ * to help keep it from taking up unnecessary icache when it isn't in use.
+ *
+ * Place this attribute at the very beginning of a function definition. For
+ * example, write
+ *
+ *   MOZ_COLD int foo();
+ *
+ * or
+ *
+ *   MOZ_COLD int foo() { return 42; }
+ */
+#if defined(__GNUC__) || defined(__clang__)
+#  define MOZ_COLD __attribute__ ((cold))
+#else
+#  define MOZ_COLD
+#endif
+
 /*
  * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function
  * declaration, indicates that for the purposes of static analysis, this
  * function does not return.  (The function definition does not need to be
  * annotated.)
  *
  * MOZ_ReportCrash(const char* s, const char* file, int ln)
  *   MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS