1 /* Jitter: VM-specific configuration and internal implementation header. 2 3 Copyright (C) 2017, 2018, 2019 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_VM_H_ 23 #define JITTER_VM_H_ 24 25 #include <stdio.h> 26 27 #include <jitter/jitter.h> 28 #include <jitter/jitter-mutable-routine.h> 29 #include <jitter/jitter-patch-in.h> 30 #include <jitter/jitter-list.h> 31 32 33 34 35 /* VM-specific attributes. 36 * ************************************************************************** */ 37 38 /* The kind of profiling instrumentation enabled in a VM. This is selected with 39 CPP macros when compiling vm1 and vm2. 40 41 Notice that the enum value can be used as a bit mask, with 42 jitter_vm_instrumentation_count and jitter_vm_instrumentation_sample being 43 two independent features that can be enabled or disabled, each contributing 44 to the enum jitter_vm_instrumentation value as operands of a bitwise or 45 operation. */ 46 enum jitter_vm_instrumentation 47 { 48 /* No instrumentation, as suitable for production. */ 49 jitter_vm_instrumentation_none 50 = 0, 51 52 /* Counting instrumentation. This permits to count how many time each 53 specialised instruction is executed, exactly. 54 This mode is unsuitable for production as the instrumentation overhead 55 is severe. For every VM instruction: 56 - load; 57 - 64-bit load (often with an offset larger than 16 bits); 58 - 64-bit increment; 59 - 64-bit store (often with an offset larger than 16 bits). 60 This is also heavy on l1d, since the 64-bit memory location accessed 61 depends on the specialised opcode, and many different location can be 62 touched. */ 63 jitter_vm_instrumentation_count 64 = 1, 65 66 /* Sampling instrumentation. This permits to count how much time is spent 67 executing each specialised instruction, subject to sampling errors. 68 The instrumentation overhead is less extreme in this case. For every 69 VM instruction: 70 - store of a 16-bit constant (zero-extended or sign-extended to word 71 size) depending on the instruction; 72 and then the overhead of handling a periodic signal. 73 The address being written to is always the same. */ 74 jitter_vm_instrumentation_sample 75 = 2, 76 77 /* Enable both counting and sampling. The overhead will be equal to the sum 78 of the two overheads above, again making this mode is again unsuitable 79 for production VMs. */ 80 jitter_vm_instrumentation_count_and_sample 81 = jitter_vm_instrumentation_count | jitter_vm_instrumentation_sample 82 }; 83 84 /* Return a human-readable description of the given instrumentation. The 85 returned string points to global constant memory, and the user does not 86 need to free it. */ 87 const char * 88 jitter_vm_instrumentation_to_string (enum jitter_vm_instrumentation i); 89 90 /* A struct containing the configuration-specific parameters of a VM. This 91 struct exists in only one constant instance per VM, and does not depend on 92 initialisation functions. It is convenient to be used, for example, in 93 handling the command-line option --version . */ 94 struct jitter_vm_configuration 95 { 96 /* Identifier prefixes for the generated C code. */ 97 char *lower_case_prefix, *upper_case_prefix; 98 99 /* How many fast registers per class this VM can have, as a maximum. -1 means 100 that there is no limit. */ 101 int max_fast_register_no_per_class; 102 103 /* How many nonresidual literals we support, as a maximum; -1 means that there 104 is no limit. */ 105 int max_nonresidual_literal_no; 106 107 /* A textual description of the dispatching technique. */ 108 char *dispatch_human_readable; 109 110 /* The kind of profiling instrumentation for this VM. */ 111 enum jitter_vm_instrumentation instrumentation; 112 }; 113 114 /* Print the current VM configuration, as set by jitterc and CPP macros, to the 115 given stream in a human-readable format. */ 116 void 117 jitter_print_vm_configuration (FILE *f, 118 const struct jitter_vm_configuration *c); 119 120 121 122 123 /* VM internal implementation. 124 * ************************************************************************** */ 125 126 /* Everything from this point on is subject to change and not meant for the 127 user. */ 128 129 /* A struct defining the VM-specific attributes of a VM. Each VM has its own 130 unique instance of this, shared by every routine for the same VM and 131 initialized by vmprefix_initialize in template code. 132 This structure is used internally, and the user does not need to see it. */ 133 struct jitter_vm 134 { 135 /* Configuration-specific data for this VM. */ 136 const struct jitter_vm_configuration *configuration; 137 138 /* Threads or pointers to native code blocks of course don't exist with 139 switch-dispatching. */ 140 #ifndef JITTER_DISPATCH_SWITCH 141 /* True iff threads appear to be valid: of non-negative size, sequential, 142 non-overlapping. */ 143 bool threads_validated; 144 145 // FIXME: add a comment per field. 146 jitter_thread *threads; 147 long *thread_sizes; 148 149 /* The address of the symbol defined in the data location subsection as 150 a const char * global. See jitter-data-locations.h . */ 151 const char *data_locations; 152 #endif // #ifndef JITTER_DISPATCH_SWITCH 153 154 const size_t *specialized_instruction_residual_arities; 155 const unsigned long *specialized_instruction_label_bitmasks; 156 157 /* This is NULL when using a dispatching model not needing the bitmask. */ 158 const unsigned long *specialized_instruction_fast_label_bitmasks; 159 160 #ifdef JITTER_HAVE_PATCH_IN 161 const struct jitter_patch_in_descriptor *patch_in_descriptors; 162 size_t patch_in_descriptor_no; 163 /* A patch-in table as defined in jitter/jitter-patch-in.h . */ 164 struct patch_in_table_entry *patch_in_table; 165 #endif // #ifdef JITTER_HAVE_PATCH_IN 166 167 const bool *specialized_instruction_relocatables; 168 const bool *specialized_instruction_callers; 169 const bool *specialized_instruction_callees; 170 const char * const *specialized_instruction_names; 171 size_t specialized_instruction_no; 172 173 struct jitter_hash_table *meta_instruction_string_hash; 174 175 struct jitter_meta_instruction *meta_instructions; 176 size_t meta_instruction_no; 177 178 /* An array whose indices are specialised instruction opcodes, and whose 179 elements are the corresponding unspecialised instructions opcodes -- or -1 180 when there is no mapping mapping having */ 181 const int *specialized_instruction_to_unspecialized_instruction; 182 183 /* Specific meta-instruction pointers for implicit instructions. 184 VM-independent routine specialization relies on those, so they have to be 185 accessible to the Jitter library, out of generated code*/ 186 const struct jitter_meta_instruction *exitvm_meta_instruction; 187 const struct jitter_meta_instruction *unreachable_meta_instruction; 188 189 /* The longest unspecialized/meta instruction name length, not mangled, 190 without counting the final '\0' character. Special specialized 191 instruction, having no unspecialized counterparts, are ignored here. */ 192 size_t max_meta_instruction_name_length; 193 194 /* A function returning a pointer to a constant register class descriptor 195 given the register class character, or NULL if the character is not 196 associated to any register class. */ 197 const struct jitter_register_class * 198 (* register_class_character_to_register_class) (char c); 199 200 /* Translate one or more unspecialized instructions starting from *ins into 201 p->specialized_program by calling the appropriate 202 vmprefix_add_specialized_instruction_* functions for the opcode and every 203 argument, returning the number of unspecialized instructions covered by the 204 one new specialized instruction which is being added. The result is always 205 1 or more -- more than 1 when a superinstruction is being recognized. The 206 actual function is machine-generated. */ 207 /* FIXME: the comment above has been obsolete for a long time (in the end I 208 decided not to have superinstructions), and the API can be simplified. 209 The result should be void, not int. */ 210 int (*specialize_instruction) (struct jitter_mutable_routine *p, 211 const struct jitter_instruction *ins); 212 213 /* Rewrite an instruction. This points to the vmprefix_rewrite function declared 214 in templates/vm.h and implemented in Jitter-generated code. */ 215 void (*rewrite) (struct jitter_mutable_routine *p); 216 217 /* A linked list of all the existing states for this VM. */ 218 struct jitter_list_header states; 219 }; 220 221 222 #endif // #ifndef JITTER_VM_H_ 223