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:
parent
661fce82a6
commit
d1e5f2c7e2
@ -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
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
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 */
|
Loading…
x
Reference in New Issue
Block a user