Message ID | 20240316015720.3661236-23-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | plugins: Rewrite plugin code generation | expand |
On 3/16/24 05:57, Richard Henderson wrote: > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > accel/tcg/plugin-gen.c | 31 ++++--------------------------- > 1 file changed, 4 insertions(+), 27 deletions(-) > > diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c > index fd52ea3987..c354825779 100644 > --- a/accel/tcg/plugin-gen.c > +++ b/accel/tcg/plugin-gen.c > @@ -14,33 +14,10 @@ > * Injecting the desired instrumentation could be done with a second > * translation pass that combined the instrumentation requests, but that > * would be ugly and inefficient since we would decode the guest code twice. > - * Instead, during TB translation we add "empty" instrumentation calls for all > - * possible instrumentation events, and then once we collect the instrumentation > - * requests from plugins, we either "fill in" those empty events or remove them > - * if they have no requests. > - * > - * When "filling in" an event we first copy the empty callback's TCG ops. This > - * might seem unnecessary, but it is done to support an arbitrary number > - * of callbacks per event. Take for example a regular instruction callback. > - * We first generate a callback to an empty helper function. Then, if two > - * plugins register one callback each for this instruction, we make two copies > - * of the TCG ops generated for the empty callback, substituting the function > - * pointer that points to the empty helper function with the plugins' desired > - * callback functions. After that we remove the empty callback's ops. > - * > - * Note that the location in TCGOp.args[] of the pointer to a helper function > - * varies across different guest and host architectures. Instead of duplicating > - * the logic that figures this out, we rely on the fact that the empty > - * callbacks point to empty functions that are unique pointers in the program. > - * Thus, to find the right location we just have to look for a match in > - * TCGOp.args[]. This is the main reason why we first copy an empty callback's > - * TCG ops and then fill them in; regardless of whether we have one or many > - * callbacks for that event, the logic to add all of them is the same. > - * > - * When generating more than one callback per event, we make a small > - * optimization to avoid generating redundant operations. For instance, for the > - * second and all subsequent callbacks of an event, we do not need to reload the > - * CPU's index into a TCG temp, since the first callback did it already. > + * Instead, during TB translation we add "plugin_cb" marker opcodes > + * for all possible instrumentation events, and then once we collect the > + * instrumentation requests from plugins, we generate code for those markers > + * or remove them if they have no requests. > */ > #include "qemu/osdep.h" > #include "qemu/plugin.h" Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c index fd52ea3987..c354825779 100644 --- a/accel/tcg/plugin-gen.c +++ b/accel/tcg/plugin-gen.c @@ -14,33 +14,10 @@ * Injecting the desired instrumentation could be done with a second * translation pass that combined the instrumentation requests, but that * would be ugly and inefficient since we would decode the guest code twice. - * Instead, during TB translation we add "empty" instrumentation calls for all - * possible instrumentation events, and then once we collect the instrumentation - * requests from plugins, we either "fill in" those empty events or remove them - * if they have no requests. - * - * When "filling in" an event we first copy the empty callback's TCG ops. This - * might seem unnecessary, but it is done to support an arbitrary number - * of callbacks per event. Take for example a regular instruction callback. - * We first generate a callback to an empty helper function. Then, if two - * plugins register one callback each for this instruction, we make two copies - * of the TCG ops generated for the empty callback, substituting the function - * pointer that points to the empty helper function with the plugins' desired - * callback functions. After that we remove the empty callback's ops. - * - * Note that the location in TCGOp.args[] of the pointer to a helper function - * varies across different guest and host architectures. Instead of duplicating - * the logic that figures this out, we rely on the fact that the empty - * callbacks point to empty functions that are unique pointers in the program. - * Thus, to find the right location we just have to look for a match in - * TCGOp.args[]. This is the main reason why we first copy an empty callback's - * TCG ops and then fill them in; regardless of whether we have one or many - * callbacks for that event, the logic to add all of them is the same. - * - * When generating more than one callback per event, we make a small - * optimization to avoid generating redundant operations. For instance, for the - * second and all subsequent callbacks of an event, we do not need to reload the - * CPU's index into a TCG temp, since the first callback did it already. + * Instead, during TB translation we add "plugin_cb" marker opcodes + * for all possible instrumentation events, and then once we collect the + * instrumentation requests from plugins, we generate code for those markers + * or remove them if they have no requests. */ #include "qemu/osdep.h" #include "qemu/plugin.h"
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- accel/tcg/plugin-gen.c | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-)