Skip to content

Commit

Permalink
Reduce register pressure in substr()
Browse files Browse the repository at this point in the history
Have substr() return the result string pointer.  This means that we can
delay allocating the register to hold the result until after the call to
dt_substr() has been made.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Reviewed-by: Eugene Loh <eugene.loh@oracle.com>
  • Loading branch information
kvanhees committed Mar 18, 2022
1 parent 8d80e9a commit 6bd24a5
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 14 deletions.
4 changes: 3 additions & 1 deletion bpf/substr.S
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define BPF_FUNC_probe_read_str 45

/*
* void dt_substr(char *dst, const char *src, int32_t idx, int32_t cnt,
* char *dt_substr(char *dst, const char *src, int32_t idx, int32_t cnt,
* uint64_t argc)
*
* %r1 = dst, %r2 = src, %r3 = idx, %r4 = cnt, %r5 = argc
Expand Down Expand Up @@ -124,10 +124,12 @@ dt_substr :
* &src[idx]);
*/

mov %r0, %r9
exit

.Lempty:
/* Store the empty string in the destination. */
stb [%r9+0], 0
mov %r0, %r9
exit
.size dt_substr, .-dt_substr
29 changes: 16 additions & 13 deletions libdtrace/dt_cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3997,26 +3997,20 @@ dt_cg_subr_substr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_node(cnt, dlp, drp);

/*
* Allocate the result register and associate it with a temporary
* string slot.
* Allocate a temporary string slot for the result.
*/
dnp->dn_reg = dt_regset_alloc(drp);
if (dnp->dn_reg == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
dt_cg_tstring_alloc(yypcb, dnp);

emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, BPF_REG_FP, DT_STK_DCTX));
emit(dlp, BPF_LOAD(BPF_DW, dnp->dn_reg, dnp->dn_reg, DCTX_MEM));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, dnp->dn_reg, dnp->dn_tstring->dn_value));

if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);

emit(dlp, BPF_MOV_REG(BPF_REG_1, dnp->dn_reg));
emit(dlp, BPF_MOV_REG(BPF_REG_2, str->dn_reg));
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_FP, DT_STK_DCTX));
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_1, DCTX_MEM));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, dnp->dn_tstring->dn_value));
emit(dlp, BPF_MOV_REG(BPF_REG_2, str->dn_reg));
dt_regset_free(drp, str->dn_reg);
dt_cg_tstring_free(yypcb, str);
emit(dlp, BPF_MOV_REG(BPF_REG_3, idx->dn_reg));
emit(dlp, BPF_MOV_REG(BPF_REG_3, idx->dn_reg));
dt_regset_free(drp, idx->dn_reg);
if (cnt != NULL) {
emit(dlp, BPF_MOV_REG(BPF_REG_4, cnt->dn_reg));
Expand All @@ -4030,8 +4024,17 @@ dt_cg_subr_substr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_substr");
assert(idp != NULL);
emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
dt_regset_free_args(drp);

/*
* Allocate the result register, and assign the result to it..
*/
dnp->dn_reg = dt_regset_alloc(drp);
if (dnp->dn_reg == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);

emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
dt_regset_free(drp, BPF_REG_0);
dt_regset_free_args(drp);

TRACE_REGSET(" subr-substr:End ");
}
Expand Down

0 comments on commit 6bd24a5

Please sign in to comment.