2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-03-23 14:11:05 +08:00

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
This commit is contained in:
David Malcolm 2014-12-09 20:00:07 +00:00 committed by David Malcolm
parent 661fce82a6
commit d1e5f2c7e2
7 changed files with 292 additions and 83 deletions

@ -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

@ -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.

@ -98,6 +98,7 @@ namespace jit {
class result;
class dump;
class builtins_manager; // declared within jit-builtins.h
class tempdir;
namespace recording {

@ -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. */

@ -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;

129
gcc/jit/jit-tempdir.c Normal file

@ -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);
}

81
gcc/jit/jit-tempdir.h Normal file

@ -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 */