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