1 /* Jitter: Routine unified API: header.
2 
3    Copyright (C) 2019, 2020 Luca Saiu
4    Written by Luca Saiu
5 
6    This file is part of Jitter.
7 
8    Jitter is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12 
13    Jitter is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with Jitter.  If not, see <http://www.gnu.org/licenses/>. */
20 
21 
22 #ifndef JITTER_ROUTINE_H_
23 #define JITTER_ROUTINE_H_
24 
25 #include <jitter/jitter.h>
26 
27 #include <jitter/jitter-mutable-routine.h>
28 #include <jitter/jitter-print.h>
29 #include <jitter/jitter-specialize.h>
30 
31 
32 
33 
34 /* Introduction.
35  * ************************************************************************** */
36 
37 /* This user API is a simplified alternative to using both struct
38    jitter_mutable_routine and struct jitter_executable_routine.  The ordinary
39    API using both structs potentially allows for slight time savings due to
40    fewer indirections, and more substantial space savings in case executable
41    routines are generated without need for their mutable counterparts.
42 
43    This unified API has the advantage of simplicity: the user does not need to
44    pay attention about which operation requires each kind of routine, including
45    destruction which when handled carelessly from the ordinary API may open
46    opportunities for memory leaks.
47 
48    The unified API follows the ordinary API, only changing the routine type in
49    function and macro arguments.  Comments about individual operations are not
50    duplicated here: see <jitter/jitter-mutable-routine.h> and
51    <jitter/jitter-specialize.h> for more information. */
52 
53 
54 
55 
56 /* Data structure.
57  * ************************************************************************** */
58 
59 /* The internal implementation of a struct routine is to be considered
60    abstract.  It is independent from the VM. */
61 
62 /* A unified routine is actually implemented as a pointer to a mutable routine,
63    with the convention that the unified API never destroys the executable
64    routine pointed by it, if any, until the unified routine is destroyed as
65    well.
66    There is no need for a wrapper pointing to two routine kinds, when in the
67    ordinary API they each point to each other already. */
68 typedef struct jitter_mutable_routine *
69 jitter_routine;
70 
71 
72 
73 
74 /* Operations.
75  * ************************************************************************** */
76 
77 /* See the comments in <jitter/jitter-mutable-routine.h> ,
78    <jitter/jitter-specialize.h> and. <jitter/jitter-disassemble.h>
79 
80    The unified API only wraps the operations actually indended for the user.
81    Since this is all only intended for the user, it makes little sense to define
82    VM-indepdendent wrappers here to be wrapped again in templates/vm.h .  This
83    section only provides declarations for what actually needs to be implemented
84    as a VM-independent function; everything else is wrapped, once, directly in
85    templates/vm.h . */
86 
87 /* Destroy the given routine, which must have been previously allocated with
88    vmprefix_make_routine. */
89 void
90 jitter_destroy_routine (jitter_routine r);
91 
92 /* Like jitter_pin_excutable_routine , for the unified routine API. */
93 void
94 jitter_pin_routine (jitter_routine r)
95   __attribute__ ((nonnull (1)));
96 
97 /* Like jitter_pin_excutable_routine , for the unified routine API. */
98 void
99 jitter_unpin_routine (jitter_routine r)
100   __attribute__ ((nonnull (1)));
101 
102 /* Like jitter_mutable_routine_print , for the unified routine API. */
103 void
104 jitter_routine_print (jitter_print_context out, const jitter_routine r)
105   __attribute__ ((nonnull (1, 2)));
106 
107 /* Like jitter_excecutable_routine_disassemble , for the unified routine API. */
108 void
109 jitter_routine_disassemble (jitter_print_context out,
110                             const jitter_routine r, bool raw,
111                             const char *objdump_name,
112                             const char *objdump_options_or_NULL)
113   __attribute__ ((nonnull(1, 2, 4)));
114 
115 
116 
117 
118 /* In case it does not exist yet, make the executable counterpart of the given
119    unified routine.  After this function returns it is safe to access the
120    executable routine from a pointer in the mutable routine, without
121    checking.
122    It is not always necessary to use this function is user code, as a unified
123    routine automatically generates an executable routine at its first execution
124    or extraction of external labels [FIXME: external labels are not implemented
125    yet; the other use case is already supported at this point].
126    However relying on this automatic behavior is dangerous in a multi-threaded
127    setting where an executable routine may be generated at the same time for the
128    same unified routine: there is no mutex to automatically handle a critical
129    section, and it is the user's responsibility to provide for it if needed.
130    This function is also used internally. */
131 struct jitter_executable_routine *
132 jitter_routine_make_executable_if_needed (jitter_routine r)
133   __attribute__ ((nonnull (1), returns_nonnull));
134 
135 #endif // #ifndef JITTER_ROUTINE_H_
136