/* occasionally. It is ok to read it */
/* without acquiring the lock. */
+#define VERBOSE 2
#ifndef SMALL_CONFIG
/* GC_print_stats should be visible to extra/MacOS.c. */
- extern int GC_print_stats; /* Nonzero generates basic GC log. */
+# ifndef GC_ANDROID_LOG
+ extern int GC_print_stats; /* Nonzero generates basic GC log. */
/* VERBOSE generates add'l messages. */
+# define GC_real_print_stats GC_print_stats
+# else
+# ifndef GC_print_stats
+# define GC_print_stats VERBOSE
+# endif
+ extern int GC_real_print_stats;
+ /* Influences logging only if redirected to a file. */
+# endif
#else /* SMALL_CONFIG */
# define GC_print_stats 0
/* Will this remove the message character strings from the executable? */
/* With a particular level of optimizations, it should... */
#endif
-#define VERBOSE 2
#ifdef KEEP_BACK_PTRS
GC_EXTERN long GC_backtraces;
}
#endif
+#ifndef GC_ANDROID_LOG
/* GC_stats_log_printf should be called only if GC_print_stats. */
# define GC_stats_log_printf GC_log_printf
/* GC_verbose_log_printf is called only if GC_print_stats is VERBOSE. */
# define GC_verbose_log_printf GC_log_printf
+#else
+ GC_INNER void GC_stats_log_printf(const char *format, ...)
+ GC_ATTR_FORMAT_PRINTF(1, 2);
+ GC_INNER void GC_verbose_log_printf(const char *format, ...)
+ GC_ATTR_FORMAT_PRINTF(1, 2);
+#endif /* GC_ANDROID_LOG */
/* Convenient macros for GC_stats/verbose_log_printf invocation. */
#define GC_COND_LOG_PRINTF if (!GC_print_stats) {} else GC_stats_log_printf
GC_bool GC_quiet = 0; /* used also in pcr_interface.c */
#ifndef SMALL_CONFIG
- int GC_print_stats = 0;
+ int GC_real_print_stats = 0;
#endif
#ifdef GC_PRINT_BACK_HEIGHT
# ifdef GC_PRINT_VERBOSE_STATS
/* This is useful for debugging and profiling on platforms with */
/* missing getenv() (like WinCE). */
- GC_print_stats = VERBOSE;
+ GC_real_print_stats = VERBOSE;
# else
if (0 != GETENV("GC_PRINT_VERBOSE_STATS")) {
- GC_print_stats = VERBOSE;
+ GC_real_print_stats = VERBOSE;
} else if (0 != GETENV("GC_PRINT_STATS")) {
- GC_print_stats = 1;
+ GC_real_print_stats = 1;
}
# endif
# if defined(UNIX_LIKE) || defined(CYGWIN32) || defined(SYMBIAN)
ABORT("write to GC log failed");
}
+# define GC_warn_printf GC_err_printf
+
#else
# define GC_LOG_PRINTF_IMPL(loglevel, fileLogCond, format) \
void GC_log_printf(const char *format, ...)
{
- GC_LOG_PRINTF_IMPL(ANDROID_LOG_INFO, TRUE, format);
+ GC_LOG_PRINTF_IMPL(ANDROID_LOG_DEBUG, TRUE, format);
+ }
+
+ GC_INNER void GC_stats_log_printf(const char *format, ...)
+ {
+ GC_LOG_PRINTF_IMPL(ANDROID_LOG_INFO, GC_real_print_stats != 0, format);
+ }
+
+ GC_INNER void GC_verbose_log_printf(const char *format, ...)
+ {
+ GC_LOG_PRINTF_IMPL(ANDROID_LOG_VERBOSE, GC_real_print_stats == VERBOSE,
+ format);
+ }
+
+ STATIC void GC_warn_printf(const char *format, ...)
+ {
+ char buf[BUFSZ + 1];
+
+ GC_PRINTF_FILLBUF(buf, format);
+ __android_log_write(ANDROID_LOG_WARN, GC_ANDROID_LOG_TAG, buf);
+ if (GC_real_print_stats && GC_stderr != GC_DEFAULT_STDERR_FD
+ && WRITE(GC_stderr, buf, strlen(buf)) < 0)
+ ABORT("write to stderr failed");
}
#endif /* GC_ANDROID_LOG */
STATIC void GC_CALLBACK GC_default_warn_proc(char *msg, GC_word arg)
{
/* TODO: Add assertion on arg comply with msg (format). */
- GC_err_printf(msg, arg);
+ GC_warn_printf(msg, arg);
}
GC_INNER GC_warn_proc GC_current_warn_proc = GC_default_warn_proc;