aboutsummaryrefslogtreecommitdiff
path: root/gcc/jit/jit-logging.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2015-01-08 19:41:07 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2015-01-08 19:41:07 +0000
commiteb4c16eb849c4c06009186a4df409186d46f5e8d (patch)
treefb0c1dc7bb71ee82c586ff5bfaf5f70fad96ddb7 /gcc/jit/jit-logging.c
parentefa7df3c625146460d7ec345d32a4efb42be871b (diff)
downloadgcc-eb4c16eb849c4c06009186a4df409186d46f5e8d.zip
gcc-eb4c16eb849c4c06009186a4df409186d46f5e8d.tar.gz
gcc-eb4c16eb849c4c06009186a4df409186d46f5e8d.tar.bz2
New jit API entrypoint: gcc_jit_context_set_logfile
gcc/jit/ChangeLog: * Make-lang.in (jit_OBJS): Add jit/jit-logging.o. * docs/internals/index.rst (Overview of code structure): Mention gcc_jit_context_set_logfile, and embed the example logfile. * docs/internals/test-hello-world.exe.log.txt: New file: example of a logfile. * docs/topics/contexts.rst (Debugging): Add documentation for gcc_jit_context_set_logfile. * docs/_build/texinfo/libgccjit.texi: Regenerate. * dummy-frontend.c: Include "jit-logging.h". (jit_langhook_init): Assert that there is an active playback context. If it has a logger, log entry/exit to this function. (jit_langhook_write_globals): Likewise. * jit-common.h (gcc::jit::logger): New forward declaration. * jit-logging.c: New file. * jit-logging.h: New file. * jit-playback.c: Include "jit-logging.h". (gcc::jit::playback::context::context): Initialize the log_user base class from the recording context's logger (if any). Use JIT_LOG_SCOPE to log entry/exit from the function body. (gcc::jit::playback::context::~context): Use JIT_LOG_SCOPE to log entry/exit from the function body. (gcc::jit::playback::build_stmt_list): Likewise. (gcc::jit::playback::function::postprocess): Likewise. (gcc::jit::playback::context::compile): Likewise. Log the entry/exit to toplev::main and toplev::finalize. Log the fake argv passed to toplev::main. (gcc::jit::playback::context::acquire_mutex): Use JIT_LOG_SCOPE to log entry/exit from the function body. (gcc::jit::playback::context::release_mutex): Likewise. (gcc::jit::playback::context::make_fake_args): Likewise. (gcc::jit::playback::context::extract_any_requested_dumps): Likewise. (gcc::jit::playback::context::convert_to_dso): Likewise. Also, log the arguments that the driver is invoked with. (gcc::jit::playback::context::dlopen_built_dso): Likewise. Pass the logger to the result object. (gcc::jit::playback::context::replay): Use JIT_LOG_SCOPE to log entry/exit from the function body. (gcc::jit::playback::context::dump_generated_code): Likewise. (gcc::jit::playback::context::handle_locations): Likewise. * jit-playback.h (gcc::jit::playback::context): Make this be a subclass of gcc::jit::log_user. * jit-recording.c: Include "jit-logging.h". (gcc::jit::recording::context::context: Initialize the logger to NULL for root contexts, or to the parent's logger for child contexts. (gcc::jit::recording::context::~context): Use JIT_LOG_SCOPE to log entry/exit from the function body. (gcc::jit::recording::context::replay_into): Likewise. (gcc::jit::recording::context::disassociate_from_playback): Likewise. (gcc::jit::recording::context::compile): Likewise. (recording::context::add_error_va): Likewise. Also, log the error. (gcc::jit::recording::context::validate): Use JIT_LOG_SCOPE to log entry/exit from the function body. * jit-recording.h: Include "jit-logging.h". (gcc::jit::recording::context): Make this be a subclass of gcc::jit::log_user. * jit-result.c: Include "jit-common.h" and "jit-logging.h". (gcc::jit::result::result): Add logger param, recording it. Use JIT_LOG_SCOPE to log entry/exit from the function body. (gcc::jit::result::~result(): Use JIT_LOG_SCOPE to log entry/exit from the function body. (gcc::jit::result::get_code): Likewise. * jit-result.h (gcc::jit::result): Make this be a subclass of gcc::jit::log_user. (gcc::jit::result::result): Add logger parameter. * libgccjit++.h (gccjit::context::set_logfile): New function. * libgccjit.c: Include "jit-logging.h". (gcc_jit_context_acquire): Log the context. (gcc_jit_context_release): Use JIT_LOG_FUNC to log entry/exit from the function body, and log the context. (gcc_jit_context_new_child_context): Likewise, logging both contexts. (gcc_jit_context_new_location): Use JIT_LOG_FUNC to log entry/exit from the function body. (gcc_jit_context_get_type): Likewise. (gcc_jit_context_get_int_type): Likewise. (gcc_jit_context_new_array_type): Likewise. (gcc_jit_context_new_field): Likewise. (gcc_jit_context_new_struct_type): Likewise. (gcc_jit_context_new_opaque_struct): Likewise. (gcc_jit_struct_set_fields): Likewise. (gcc_jit_context_new_union_type): Likewise. (gcc_jit_context_new_function_ptr_type): Likewise. (gcc_jit_context_new_param): Likewise. (gcc_jit_context_new_function): Likewise. (gcc_jit_context_get_builtin_function): Likewise. (gcc_jit_function_get_param): Likewise. (gcc_jit_function_dump_to_dot): Likewise. (gcc_jit_function_new_block): Likewise. (gcc_jit_context_new_global): Likewise. (gcc_jit_context_new_rvalue_from_int): Likewise. (gcc_jit_context_zero): Likewise. (gcc_jit_context_one): Likewise. (gcc_jit_context_new_rvalue_from_double): Likewise. (gcc_jit_context_new_rvalue_from_ptr): Likewise. (gcc_jit_context_null): Likewise. (gcc_jit_context_new_string_literal): Likewise. (gcc_jit_context_new_unary_op): Likewise. (gcc_jit_context_new_binary_op): Likewise. (gcc_jit_context_new_comparison): Likewise. (gcc_jit_context_new_call): Likewise. (gcc_jit_context_new_call_through_ptr): Likewise. (gcc_jit_context_new_cast): Likewise. (gcc_jit_context_new_array_access): Likewise. (gcc_jit_lvalue_access_field): Likewise. (gcc_jit_rvalue_access_field): Likewise. (gcc_jit_rvalue_dereference_field): Likewise. (gcc_jit_rvalue_dereference): Likewise. (gcc_jit_lvalue_get_address): Likewise. (gcc_jit_function_new_local): Likewise. (gcc_jit_block_add_eval): Likewise. (gcc_jit_block_add_assignment): Likewise. (gcc_jit_block_add_assignment_op): Likewise. (gcc_jit_block_end_with_conditional): Likewise. (gcc_jit_block_add_comment): Likewise. (gcc_jit_block_end_with_jump): Likewise. (gcc_jit_block_end_with_return): Likewise. (gcc_jit_block_end_with_void_return): Likewise. (gcc_jit_context_set_str_option): Likewise. (gcc_jit_context_set_int_option): Likewise. (gcc_jit_context_set_bool_option): Likewise. (gcc_jit_context_enable_dump): Likewise. (gcc_jit_context_compile): Likewise. Also log the context, and the result. (gcc_jit_context_dump_to_file): Likewise. (gcc_jit_context_set_logfile): New function. (gcc_jit_context_get_first_error): Use JIT_LOG_FUNC to log entry/exit from the function body. (gcc_jit_result_get_code): Likewise. Also log the fnname) and the ptr to be returned. (gcc_jit_result_release): Likewise. Also log the result. * libgccjit.h: Include <stdio.h>, since we need FILE *. (gcc_jit_context_set_logfile): New declaration. * libgccjit.map (gcc_jit_context_set_logfile): New. gcc/testsuite/ChangeLog: * jit.dg/harness.h (set_up_logging): New function. (test_jit): Fail if gcc_jit_context_acquire fails. Call set_up_logging on the context, so that every testcase is logged to a particular file. * jit.dg/test-nested-contexts.c (main): Open a logfile, and call gcc_jit_context_set_logfile on the top-level context. From-SVN: r219357
Diffstat (limited to 'gcc/jit/jit-logging.c')
-rw-r--r--gcc/jit/jit-logging.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/gcc/jit/jit-logging.c b/gcc/jit/jit-logging.c
new file mode 100644
index 0000000..61b898b
--- /dev/null
+++ b/gcc/jit/jit-logging.c
@@ -0,0 +1,168 @@
+/* Internals of libgccjit: logging
+ Copyright (C) 2014-2015 Free Software Foundation, Inc.
+ Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "jit-logging.h"
+
+namespace gcc {
+
+namespace jit {
+
+/* Implementation of class gcc::jit::logger. */
+
+/* The constructor for gcc::jit::logger, used by
+ gcc_jit_context_set_logfile. */
+
+logger::logger (FILE *f_out,
+ int, /* flags */
+ int /* verbosity */) :
+ m_refcount (0),
+ m_f_out (f_out),
+ m_indent_level (0),
+ m_log_refcount_changes (false)
+{
+}
+
+/* The destructor for gcc::jit::logger, invoked via
+ the decref method when the refcount hits zero.
+ Note that we do not close the underlying FILE * (m_f_out). */
+
+logger::~logger ()
+{
+ /* This should be the last message emitted. */
+ log ("%s", __PRETTY_FUNCTION__);
+ gcc_assert (m_refcount == 0);
+}
+
+/* Increment the reference count of the gcc::jit::logger. */
+
+void
+logger::incref (const char *reason)
+{
+ m_refcount++;
+ if (m_log_refcount_changes)
+ log ("%s: reason: %s refcount now %i ",
+ __PRETTY_FUNCTION__, reason, m_refcount);
+}
+
+/* Decrement the reference count of the gcc::jit::logger,
+ deleting it if nothing is referring to it. */
+
+void
+logger::decref (const char *reason)
+{
+ gcc_assert (m_refcount > 0);
+ --m_refcount;
+ if (m_log_refcount_changes)
+ log ("%s: reason: %s refcount now %i",
+ __PRETTY_FUNCTION__, reason, m_refcount);
+ if (0 == m_refcount)
+ delete this;
+}
+
+/* Write a formatted message to the log, by calling the log_va method. */
+
+void
+logger::log (const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ log_va (fmt, ap);
+ va_end (ap);
+}
+
+/* Write an indented line to the log file.
+
+ We explicitly flush after each line: if something crashes the process,
+ we want the logfile/stream to contain the most up-to-date hint about the
+ last thing that was happening, without it being hidden in an in-process
+ buffer. */
+
+void
+logger::log_va (const char *fmt, va_list ap)
+{
+ fprintf (m_f_out, "JIT: ");
+ for (int i = 0; i < m_indent_level; i++)
+ fputc (' ', m_f_out);
+ vfprintf (m_f_out, fmt, ap);
+ fprintf (m_f_out, "\n");
+ fflush (m_f_out);
+}
+
+/* Record the entry within a particular scope, indenting subsequent
+ log lines accordingly. */
+
+void
+logger::enter_scope (const char *scope_name)
+{
+ log ("entering: %s", scope_name);
+ m_indent_level += 1;
+}
+
+/* Record the exit from a particular scope, restoring the indent level to
+ before the scope was entered. */
+
+void
+logger::exit_scope (const char *scope_name)
+{
+ if (m_indent_level)
+ m_indent_level -= 1;
+ else
+ log ("(mismatching indentation)");
+ log ("exiting: %s", scope_name);
+}
+
+/* Implementation of class gcc::jit::log_user. */
+
+/* The constructor for gcc::jit::log_user. */
+
+log_user::log_user (logger *logger) : m_logger (logger)
+{
+ if (m_logger)
+ m_logger->incref("log_user ctor");
+}
+
+/* The destructor for gcc::jit::log_user. */
+
+log_user::~log_user ()
+{
+ if (m_logger)
+ m_logger->decref("log_user dtor");
+}
+
+/* Set the logger for a gcc::jit::log_user, managing the reference counts
+ of the old and new logger (either of which might be NULL). */
+
+void
+log_user::set_logger (logger *logger)
+{
+ if (logger)
+ logger->incref ("log_user::set_logger");
+ if (m_logger)
+ m_logger->decref ("log_user::set_logger");
+ m_logger = logger;
+}
+
+} // namespace gcc::jit
+
+} // namespace gcc