Add jit-tempdir.{c|h}
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 9 Dec 2014 20:00:07 +0000 (20:00 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 9 Dec 2014 20:00:07 +0000 (20:00 +0000)
gcc/jit/ChangeLog:
        PR jit/64206
* Make-lang.in (jit_OBJS): Add jit/jit-tempdir.o.
* jit-common.h (gcc::jit::tempdir): New forward decl.
* jit-playback.c: Include jit-tempdir.h.
(gcc::jit::playback::context::context): Initialize m_tempdir.
(gcc::jit::playback::context::~context): Move tempdir
cleanup to new file jit-tempdir.c
(make_tempdir_path_template): Move to new file jit-tempdir.c.
(gcc::jit::playback::context::compile): Move tempdir creation
to new tempdir object in new file jit-tempdir.c.
(gcc::jit::playback::context::make_fake_args): Get path from
tempdir object rather than from member data.
(gcc::jit::playback::context::convert_to_dso): Likewise.
(gcc::jit::playback::context::dlopen_built_dso): Likewise.
(gcc::jit::playback::context::dump_generated_code): Likewise.
(gcc::jit::playback::context::get_path_c_file): New function.
(gcc::jit::playback::context::get_path_s_file): New function.
(gcc::jit::playback::context::get_path_so_file): New function.
* jit-playback.h (gcc::jit::playback::context::get_path_c_file):
New function.
(gcc::jit::playback::context::get_path_s_file): New function.
(gcc::jit::playback::context::get_path_so_file): New function.
(gcc::jit::playback::context): Move fields "m_path_template",
"m_path_tempdir", "m_path_c_file", "m_path_s_file",
"m_path_so_file" to new jit::tempdir class; add field "m_tempdir".
* jit-tempdir.c: New file.
* jit-tempdir.h: New file.

From-SVN: r218533

gcc/jit/ChangeLog
gcc/jit/Make-lang.in
gcc/jit/jit-common.h
gcc/jit/jit-playback.c
gcc/jit/jit-playback.h
gcc/jit/jit-tempdir.c [new file with mode: 0644]
gcc/jit/jit-tempdir.h [new file with mode: 0644]

index d69571d5342d248a6220bb1319a7fd4dcba56833..9a95c79fef2df4894a1008abe389f62457719d01 100644 (file)
@@ -1,3 +1,33 @@
+2014-12-09  David Malcolm  <dmalcolm@redhat.com>
+
+        PR jit/64206
+       * Make-lang.in (jit_OBJS): Add jit/jit-tempdir.o.
+       * jit-common.h (gcc::jit::tempdir): New forward decl.
+       * jit-playback.c: Include jit-tempdir.h.
+       (gcc::jit::playback::context::context): Initialize m_tempdir.
+       (gcc::jit::playback::context::~context): Move tempdir
+       cleanup to new file jit-tempdir.c
+       (make_tempdir_path_template): Move to new file jit-tempdir.c.
+       (gcc::jit::playback::context::compile): Move tempdir creation
+       to new tempdir object in new file jit-tempdir.c.
+       (gcc::jit::playback::context::make_fake_args): Get path from
+       tempdir object rather than from member data.
+       (gcc::jit::playback::context::convert_to_dso): Likewise.
+       (gcc::jit::playback::context::dlopen_built_dso): Likewise.
+       (gcc::jit::playback::context::dump_generated_code): Likewise.
+       (gcc::jit::playback::context::get_path_c_file): New function.
+       (gcc::jit::playback::context::get_path_s_file): New function.
+       (gcc::jit::playback::context::get_path_so_file): New function.
+       * jit-playback.h (gcc::jit::playback::context::get_path_c_file):
+       New function.
+       (gcc::jit::playback::context::get_path_s_file): New function.
+       (gcc::jit::playback::context::get_path_so_file): New function.
+       (gcc::jit::playback::context): Move fields "m_path_template",
+       "m_path_tempdir", "m_path_c_file", "m_path_s_file",
+       "m_path_so_file" to new jit::tempdir class; add field "m_tempdir".
+       * jit-tempdir.c: New file.
+       * jit-tempdir.h: New file.
+
 2014-12-09  David Malcolm  <dmalcolm@redhat.com>
 
        * jit-playback.c (gcc::jit::playback::context::compile): Acquire the
index e88fd0038653aeb444aa3571ca216b906536acda..818e14b10b3b7b4c3a2a6bfbb65add1f4576680b 100644 (file)
@@ -65,6 +65,7 @@ jit_OBJS = attribs.o \
        jit/jit-recording.o \
        jit/jit-playback.o \
        jit/jit-result.o \
+       jit/jit-tempdir.o \
        jit/jit-builtins.o
 
 # Use strict warnings for this front end.
index c9dde3e63e2cc0fb91bfdbe53272202993247d05..25c2c6f9fcc0e2da25bcf8447e265a6679eb4e3f 100644 (file)
@@ -98,6 +98,7 @@ namespace jit {
 class result;
 class dump;
 class builtins_manager; // declared within jit-builtins.h
+class tempdir;
 
 namespace recording {
 
index 281ad85fa339b0e61f8a395a263fa5d069514c5c..84989005b446bc5d308d3734c436e656c00a2d24 100644 (file)
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "jit-playback.h"
 #include "jit-result.h"
 #include "jit-builtins.h"
+#include "jit-tempdir.h"
 
 
 /* gcc::jit::playback::context::build_cast uses the convert.h API,
@@ -86,6 +87,7 @@ namespace jit {
 
 playback::context::context (recording::context *ctxt)
   : m_recording_ctxt (ctxt),
+    m_tempdir (NULL),
     m_char_array_type_node (NULL),
     m_const_char_ptr (NULL)
 {
@@ -98,25 +100,8 @@ playback::context::context (recording::context *ctxt)
 
 playback::context::~context ()
 {
-  if (get_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES))
-    fprintf (stderr, "intermediate files written to %s\n", m_path_tempdir);
-  else
-    {
-      /* Clean up .s/.so and tempdir. */
-      if (m_path_s_file)
-        unlink (m_path_s_file);
-      if (m_path_so_file)
-        unlink (m_path_so_file);
-      if (m_path_tempdir)
-        rmdir (m_path_tempdir);
-    }
-
-  free (m_path_template);
-  /* m_path_tempdir aliases m_path_template, or is NULL, so don't
-     attempt to free it .  */
-  free (m_path_c_file);
-  free (m_path_s_file);
-  free (m_path_so_file);
+  if (m_tempdir)
+    delete m_tempdir;
   m_functions.release ();
 }
 
@@ -1515,44 +1500,6 @@ block (function *func,
   m_label_expr = NULL;
 }
 
-/* Construct a tempdir path template suitable for use by mkdtemp
-   e.g. "/tmp/libgccjit-XXXXXX", but respecting the rules in
-   libiberty's choose_tempdir rather than hardcoding "/tmp/".
-
-   The memory is allocated using malloc and must be freed.
-   Aborts the process if allocation fails. */
-
-static char *
-make_tempdir_path_template ()
-{
-  const char *tmpdir_buf;
-  size_t tmpdir_len;
-  const char *file_template_buf;
-  size_t file_template_len;
-  char *result;
-
-  /* The result of choose_tmpdir is a cached buffer within libiberty, so
-     we must *not* free it.  */
-  tmpdir_buf = choose_tmpdir ();
-
-  /* choose_tmpdir aborts on malloc failure.  */
-  gcc_assert (tmpdir_buf);
-
-  tmpdir_len = strlen (tmpdir_buf);
-  /* tmpdir_buf should now have a dir separator as the final byte.  */
-  gcc_assert (tmpdir_len > 0);
-  gcc_assert (tmpdir_buf[tmpdir_len - 1] == DIR_SEPARATOR);
-
-  file_template_buf = "libgccjit-XXXXXX";
-  file_template_len = strlen (file_template_buf);
-
-  result = XNEWVEC (char, tmpdir_len + file_template_len + 1);
-  strcpy (result, tmpdir_buf);
-  strcpy (result + tmpdir_len, file_template_buf);
-
-  return result;
-}
-
 /* A subclass of auto_vec <char *> that frees all of its elements on
    deletion.  */
 
@@ -1589,19 +1536,12 @@ compile ()
   const char *ctxt_progname;
   result *result_obj = NULL;
 
-  m_path_template = make_tempdir_path_template ();
-  if (!m_path_template)
-    return NULL;
+  int keep_intermediates =
+    get_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES);
 
-  /* Create tempdir using mkdtemp.  This is created with 0700 perms and
-     is unique.  Hence no other (non-root) users should have access to
-     the paths within it.  */
-  m_path_tempdir = mkdtemp (m_path_template);
-  if (!m_path_tempdir)
+  m_tempdir = new tempdir (keep_intermediates);
+  if (!m_tempdir->create ())
     return NULL;
-  m_path_c_file = concat (m_path_tempdir, "/fake.c", NULL);
-  m_path_s_file = concat (m_path_tempdir, "/fake.s", NULL);
-  m_path_so_file = concat (m_path_tempdir, "/fake.so", NULL);
 
   /* Call into the rest of gcc.
      For now, we have to assemble command-line options to pass into
@@ -1706,7 +1646,7 @@ make_fake_args (vec <char *> *argvec,
 #define ADD_ARG_TAKE_OWNERSHIP(arg) argvec->safe_push (arg)
 
   ADD_ARG (ctxt_progname);
-  ADD_ARG (m_path_c_file);
+  ADD_ARG (get_path_c_file ());
   ADD_ARG ("-fPIC");
 
   /* Handle int options: */
@@ -1886,10 +1826,10 @@ convert_to_dso (const char *ctxt_progname)
   argv[0] = gcc_driver_name;
   argv[1] = "-shared";
   /* The input: assembler.  */
-  argv[2] = m_path_s_file;
+  argv[2] = m_tempdir->get_path_s_file ();
   /* The output: shared library.  */
   argv[3] = "-o";
-  argv[4] = m_path_so_file;
+  argv[4] = m_tempdir->get_path_so_file ();
 
   /* Don't use the linker plugin.
      If running with just a "make" and not a "make install", then we'd
@@ -1953,7 +1893,8 @@ dlopen_built_dso ()
   /* Clear any existing error.  */
   dlerror ();
 
-  handle = dlopen (m_path_so_file, RTLD_NOW | RTLD_LOCAL);
+  handle = dlopen (m_tempdir->get_path_so_file (),
+                  RTLD_NOW | RTLD_LOCAL);
   if ((error = dlerror()) != NULL)  {
     add_error (NULL, "%s", error);
   }
@@ -2038,7 +1979,7 @@ dump_generated_code ()
 {
   char buf[4096];
   size_t sz;
-  FILE *f_in = fopen (m_path_s_file, "r");
+  FILE *f_in = fopen (get_path_s_file (), "r");
   if (!f_in)
     return;
 
@@ -2048,6 +1989,37 @@ dump_generated_code ()
   fclose (f_in);
 }
 
+/* Get the supposed path of the notional "fake.c" file within the
+   tempdir.  This file doesn't exist, but the rest of the compiler
+   needs a name.  */
+
+const char *
+playback::context::
+get_path_c_file () const
+{
+  return m_tempdir->get_path_c_file ();
+}
+
+/* Get the path of the assembler output file "fake.s" file within the
+   tempdir. */
+
+const char *
+playback::context::
+get_path_s_file () const
+{
+  return m_tempdir->get_path_s_file ();
+}
+
+/* Get the path of the DSO object file "fake.so" file within the
+   tempdir. */
+
+const char *
+playback::context::
+get_path_so_file () const
+{
+  return m_tempdir->get_path_so_file ();
+}
+
 /* qsort comparator for comparing pairs of playback::source_line *,
    ordering them by line number.  */
 
index 1373ecc7b2b451477fee356161c505f13ef91065..22fc2834fbfe7c2454203cd531e1d5f914c3ce1d 100644 (file)
@@ -231,6 +231,10 @@ private:
 
   void handle_locations ();
 
+  const char * get_path_c_file () const;
+  const char * get_path_s_file () const;
+  const char * get_path_so_file () const;
+
 private:
 
   /* Functions for implementing "compile".  */
@@ -259,16 +263,7 @@ private:
 private:
   ::gcc::jit::recording::context *m_recording_ctxt;
 
-  /* Allocated using xmalloc (by xstrdup).  */
-  char *m_path_template;
-
-  /* This either aliases m_path_template, or is NULL.  */
-  char *m_path_tempdir;
-
-  /* The following are allocated using xmalloc.  */
-  char *m_path_c_file;
-  char *m_path_s_file;
-  char *m_path_so_file;
+  tempdir *m_tempdir;
 
   auto_vec<function *> m_functions;
   tree m_char_array_type_node;
diff --git a/gcc/jit/jit-tempdir.c b/gcc/jit/jit-tempdir.c
new file mode 100644 (file)
index 0000000..f64fbee
--- /dev/null
@@ -0,0 +1,129 @@
+/* Managing temporary directories and their content within libgccjit.so
+   Copyright (C) 2014 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-tempdir.h"
+
+
+/* Construct a tempdir path template suitable for use by mkdtemp
+   e.g. "/tmp/libgccjit-XXXXXX", but respecting the rules in
+   libiberty's choose_tempdir rather than hardcoding "/tmp/".
+
+   The memory is allocated using malloc and must be freed.
+   Aborts the process if allocation fails. */
+
+static char *
+make_tempdir_path_template ()
+{
+  const char *tmpdir_buf;
+  size_t tmpdir_len;
+  const char *file_template_buf;
+  size_t file_template_len;
+  char *result;
+
+  /* The result of choose_tmpdir is a cached buffer within libiberty, so
+     we must *not* free it.  */
+  tmpdir_buf = choose_tmpdir ();
+
+  /* choose_tmpdir aborts on malloc failure.  */
+  gcc_assert (tmpdir_buf);
+
+  tmpdir_len = strlen (tmpdir_buf);
+  /* tmpdir_buf should now have a dir separator as the final byte.  */
+  gcc_assert (tmpdir_len > 0);
+  gcc_assert (tmpdir_buf[tmpdir_len - 1] == DIR_SEPARATOR);
+
+  file_template_buf = "libgccjit-XXXXXX";
+  file_template_len = strlen (file_template_buf);
+
+  result = XNEWVEC (char, tmpdir_len + file_template_len + 1);
+  strcpy (result, tmpdir_buf);
+  strcpy (result + tmpdir_len, file_template_buf);
+
+  return result;
+}
+
+/* The constructor for the jit::tempdir object.
+   The real work is done by the jit::tempdir::create method.  */
+
+gcc::jit::tempdir::tempdir (int keep_intermediates)
+  : m_keep_intermediates (keep_intermediates),
+    m_path_template (NULL),
+    m_path_tempdir (NULL),
+    m_path_c_file (NULL),
+    m_path_s_file (NULL),
+    m_path_so_file (NULL)
+{
+}
+
+/* Do the real work of creating the on-disk tempdir.
+   We do this here, rather than in the jit::tempdir constructor
+   so that we can handle failure without needing exceptions.  */
+
+bool
+gcc::jit::tempdir::create ()
+{
+  m_path_template = make_tempdir_path_template ();
+  if (!m_path_template)
+    return false;
+
+  /* Create tempdir using mkdtemp.  This is created with 0700 perms and
+     is unique.  Hence no other (non-root) users should have access to
+     the paths within it.  */
+  m_path_tempdir = mkdtemp (m_path_template);
+  if (!m_path_tempdir)
+    return false;
+  m_path_c_file = concat (m_path_tempdir, "/fake.c", NULL);
+  m_path_s_file = concat (m_path_tempdir, "/fake.s", NULL);
+  m_path_so_file = concat (m_path_tempdir, "/fake.so", NULL);
+
+  /* Success.  */
+  return true;
+}
+
+/* The destructor for the jit::tempdir object, which
+   cleans up the filesystem directory and its contents
+   (unless keep_intermediates was set).  */
+
+gcc::jit::tempdir::~tempdir ()
+{
+  if (m_keep_intermediates)
+    fprintf (stderr, "intermediate files written to %s\n", m_path_tempdir);
+  else
+    {
+      /* Clean up .s/.so and tempdir. */
+      if (m_path_s_file)
+        unlink (m_path_s_file);
+      if (m_path_so_file)
+        unlink (m_path_so_file);
+      if (m_path_tempdir)
+        rmdir (m_path_tempdir);
+    }
+
+  free (m_path_template);
+  /* m_path_tempdir aliases m_path_template, or is NULL, so don't
+     attempt to free it .  */
+  free (m_path_c_file);
+  free (m_path_s_file);
+  free (m_path_so_file);
+}
diff --git a/gcc/jit/jit-tempdir.h b/gcc/jit/jit-tempdir.h
new file mode 100644 (file)
index 0000000..31636dd
--- /dev/null
@@ -0,0 +1,81 @@
+/* Managing temporary directories and their content within libgccjit.so
+   Copyright (C) 2014 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/>.  */
+
+#ifndef JIT_TEMPDIR_H
+#define JIT_TEMPDIR_H
+
+namespace gcc {
+
+namespace jit {
+
+/* A class to keep track of the jit::playback::context's tempdir.
+
+   The tempdir has the following layout:
+
+     /tmp/libgccjit-XXXXXX/
+                        ./fake.c
+                           (doesn't exist, but the rest of the
+                            compiler needs a source code filename)
+
+                        ./fake.s
+                             (created by toplev::main)
+
+                        ./fake.so
+                             (created by playback::context::convert_to_dso).
+
+  It is normally deleted from the filesystem in the playback::context's
+  dtor, unless GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES was set.  */
+
+class tempdir
+{
+ public:
+  tempdir (int keep_intermediates);
+  ~tempdir ();
+
+  bool create ();
+
+  const char * get_path () const { return m_path_tempdir; }
+  const char * get_path_c_file () const { return m_path_c_file; }
+  const char * get_path_s_file () const { return m_path_s_file; }
+  const char * get_path_so_file () const { return m_path_so_file; }
+
+ private:
+  /* Was GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES set?  If so, keep the
+     on-disk tempdir around after this wrapper object goes away.  */
+  int m_keep_intermediates;
+
+  /* Allocated using xmalloc (by xstrdup).  */
+  char *m_path_template;
+
+  /* This either aliases m_path_template, or is NULL.  */
+  char *m_path_tempdir;
+
+  /* The following are allocated using xmalloc.  */
+  char *m_path_c_file;
+  char *m_path_s_file;
+  char *m_path_so_file;
+
+};
+
+} // namespace gcc::jit
+
+} // namespace gcc
+
+#endif /* JIT_TEMPDIR_H */