Commit d1e5f2c7 by David Malcolm Committed by David Malcolm

Add jit-tempdir.{c|h}

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
parent 661fce82
2014-12-09 David Malcolm <dmalcolm@redhat.com> 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 * jit-playback.c (gcc::jit::playback::context::compile): Acquire the
mutex here, immediately before using toplev, and release it here, on mutex here, immediately before using toplev, and release it here, on
each exit path after acquisition. each exit path after acquisition.
......
...@@ -65,6 +65,7 @@ jit_OBJS = attribs.o \ ...@@ -65,6 +65,7 @@ jit_OBJS = attribs.o \
jit/jit-recording.o \ jit/jit-recording.o \
jit/jit-playback.o \ jit/jit-playback.o \
jit/jit-result.o \ jit/jit-result.o \
jit/jit-tempdir.o \
jit/jit-builtins.o jit/jit-builtins.o
# Use strict warnings for this front end. # Use strict warnings for this front end.
......
...@@ -98,6 +98,7 @@ namespace jit { ...@@ -98,6 +98,7 @@ namespace jit {
class result; class result;
class dump; class dump;
class builtins_manager; // declared within jit-builtins.h class builtins_manager; // declared within jit-builtins.h
class tempdir;
namespace recording { namespace recording {
......
...@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "jit-playback.h" #include "jit-playback.h"
#include "jit-result.h" #include "jit-result.h"
#include "jit-builtins.h" #include "jit-builtins.h"
#include "jit-tempdir.h"
/* gcc::jit::playback::context::build_cast uses the convert.h API, /* gcc::jit::playback::context::build_cast uses the convert.h API,
...@@ -86,6 +87,7 @@ namespace jit { ...@@ -86,6 +87,7 @@ namespace jit {
playback::context::context (recording::context *ctxt) playback::context::context (recording::context *ctxt)
: m_recording_ctxt (ctxt), : m_recording_ctxt (ctxt),
m_tempdir (NULL),
m_char_array_type_node (NULL), m_char_array_type_node (NULL),
m_const_char_ptr (NULL) m_const_char_ptr (NULL)
{ {
...@@ -98,25 +100,8 @@ playback::context::context (recording::context *ctxt) ...@@ -98,25 +100,8 @@ playback::context::context (recording::context *ctxt)
playback::context::~context () playback::context::~context ()
{ {
if (get_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES)) if (m_tempdir)
fprintf (stderr, "intermediate files written to %s\n", m_path_tempdir); delete m_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);
m_functions.release (); m_functions.release ();
} }
...@@ -1515,44 +1500,6 @@ block (function *func, ...@@ -1515,44 +1500,6 @@ block (function *func,
m_label_expr = NULL; 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 /* A subclass of auto_vec <char *> that frees all of its elements on
deletion. */ deletion. */
...@@ -1589,19 +1536,12 @@ compile () ...@@ -1589,19 +1536,12 @@ compile ()
const char *ctxt_progname; const char *ctxt_progname;
result *result_obj = NULL; result *result_obj = NULL;
m_path_template = make_tempdir_path_template (); int keep_intermediates =
if (!m_path_template) get_bool_option (GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES);
return NULL;
/* Create tempdir using mkdtemp. This is created with 0700 perms and m_tempdir = new tempdir (keep_intermediates);
is unique. Hence no other (non-root) users should have access to if (!m_tempdir->create ())
the paths within it. */
m_path_tempdir = mkdtemp (m_path_template);
if (!m_path_tempdir)
return NULL; 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. /* Call into the rest of gcc.
For now, we have to assemble command-line options to pass into For now, we have to assemble command-line options to pass into
...@@ -1706,7 +1646,7 @@ make_fake_args (vec <char *> *argvec, ...@@ -1706,7 +1646,7 @@ make_fake_args (vec <char *> *argvec,
#define ADD_ARG_TAKE_OWNERSHIP(arg) argvec->safe_push (arg) #define ADD_ARG_TAKE_OWNERSHIP(arg) argvec->safe_push (arg)
ADD_ARG (ctxt_progname); ADD_ARG (ctxt_progname);
ADD_ARG (m_path_c_file); ADD_ARG (get_path_c_file ());
ADD_ARG ("-fPIC"); ADD_ARG ("-fPIC");
/* Handle int options: */ /* Handle int options: */
...@@ -1886,10 +1826,10 @@ convert_to_dso (const char *ctxt_progname) ...@@ -1886,10 +1826,10 @@ convert_to_dso (const char *ctxt_progname)
argv[0] = gcc_driver_name; argv[0] = gcc_driver_name;
argv[1] = "-shared"; argv[1] = "-shared";
/* The input: assembler. */ /* The input: assembler. */
argv[2] = m_path_s_file; argv[2] = m_tempdir->get_path_s_file ();
/* The output: shared library. */ /* The output: shared library. */
argv[3] = "-o"; argv[3] = "-o";
argv[4] = m_path_so_file; argv[4] = m_tempdir->get_path_so_file ();
/* Don't use the linker plugin. /* Don't use the linker plugin.
If running with just a "make" and not a "make install", then we'd If running with just a "make" and not a "make install", then we'd
...@@ -1953,7 +1893,8 @@ dlopen_built_dso () ...@@ -1953,7 +1893,8 @@ dlopen_built_dso ()
/* Clear any existing error. */ /* Clear any existing error. */
dlerror (); 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) { if ((error = dlerror()) != NULL) {
add_error (NULL, "%s", error); add_error (NULL, "%s", error);
} }
...@@ -2038,7 +1979,7 @@ dump_generated_code () ...@@ -2038,7 +1979,7 @@ dump_generated_code ()
{ {
char buf[4096]; char buf[4096];
size_t sz; size_t sz;
FILE *f_in = fopen (m_path_s_file, "r"); FILE *f_in = fopen (get_path_s_file (), "r");
if (!f_in) if (!f_in)
return; return;
...@@ -2048,6 +1989,37 @@ dump_generated_code () ...@@ -2048,6 +1989,37 @@ dump_generated_code ()
fclose (f_in); 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 *, /* qsort comparator for comparing pairs of playback::source_line *,
ordering them by line number. */ ordering them by line number. */
......
...@@ -231,6 +231,10 @@ private: ...@@ -231,6 +231,10 @@ private:
void handle_locations (); 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: private:
/* Functions for implementing "compile". */ /* Functions for implementing "compile". */
...@@ -259,16 +263,7 @@ private: ...@@ -259,16 +263,7 @@ private:
private: private:
::gcc::jit::recording::context *m_recording_ctxt; ::gcc::jit::recording::context *m_recording_ctxt;
/* Allocated using xmalloc (by xstrdup). */ tempdir *m_tempdir;
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;
auto_vec<function *> m_functions; auto_vec<function *> m_functions;
tree m_char_array_type_node; tree m_char_array_type_node;
......
/* 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);
}
/* 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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment