summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2013-05-19 17:14:36 +0000
committermarkj <markj@FreeBSD.org>2013-05-19 17:14:36 +0000
commit9e08262228664ec82db5b2827324c4bd41571af3 (patch)
tree191b586f26c3dbc072d2f8d29909688c6d134bdb /cddl
parent0e0a417d2bcaf3630559ef3ff0ba356da3a6f4b4 (diff)
parent73d9b47b2a7a8df111f99bb69b7879f98cd3b57c (diff)
downloadFreeBSD-src-9e08262228664ec82db5b2827324c4bd41571af3.zip
FreeBSD-src-9e08262228664ec82db5b2827324c4bd41571af3.tar.gz
Re-introduce another part of r249367. This commit fixes a register leak in
dt_cg_ptrsize() and generally cleans up some of the error handling around register allocation. This change corresponds to part of illumos-gate commit e5803b76927480: 3025 register leak in D code generation Reviewed by: pfg Obtained from: illumos MFC after: 1 month
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d41
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d44
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c178
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c23
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c5
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h3
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c37
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h8
8 files changed, 242 insertions, 97 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d
new file mode 100644
index 0000000..636e568
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.D_NOREG.noreg.d
@@ -0,0 +1,41 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Compile some code that requires exactly 9 registers. This should run out
+ * of registers.
+ *
+ * Changes to the code generator might cause this test to succeeed in which
+ * case the code should be changed to another sequence that exhausts the
+ * available internal registers.
+ *
+ * Note that this and err.baddif.d should be kept in sync.
+ */
+
+BEGIN
+{
+ a = 4;
+ trace((a + a) * ((a + a) * ((a + a) * ((a + a) * ((a + a) *
+ ((a + a) * (a + a)))))));
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d
new file mode 100644
index 0000000..d849348
--- /dev/null
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/err.baddif.d
@@ -0,0 +1,44 @@
+/*
+ * CDDL HEADER START
+ *
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
+ * Compile some code that requires exactly 9 registers. This should generate
+ * invalid DIF because the kernel will flag the fact that we're using more
+ * registers than are available internally.
+ *
+ * Changes to the code generator might cause this test to succeeed in which
+ * case the code should be changed to another sequence that exhausts the
+ * available internal registers.
+ *
+ * Note that this and err.D_NOREG.noreg.d should be kept in sync.
+ */
+
+#pragma D option iregs=9
+
+BEGIN
+{
+ a = 4;
+ trace((a + a) * ((a + a) * ((a + a) * ((a + a) * ((a + a) *
+ ((a + a) * (a + a)))))));
+}
+
+BEGIN
+{
+ exit(0);
+}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
index a33cccd..5fdf5ad 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
@@ -19,12 +19,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/sysmacros.h>
@@ -193,9 +196,6 @@ dt_cg_ptrsize(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
ssize_t size;
int sreg;
- if ((sreg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
type = ctf_type_resolve(ctfp, dnp->dn_type);
kind = ctf_type_kind(ctfp, type);
assert(kind == CTF_K_POINTER || kind == CTF_K_ARRAY);
@@ -212,6 +212,7 @@ dt_cg_ptrsize(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
if ((size = ctf_type_size(ctfp, type)) == 1)
return; /* multiply or divide by one can be omitted */
+ sreg = dt_regset_alloc(drp);
dt_cg_setx(dlp, sreg, size);
instr = DIF_INSTR_FMT(op, dreg, sreg, dreg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -251,9 +252,7 @@ dt_cg_field_get(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp,
assert(dnp->dn_op == DT_TOK_PTR || dnp->dn_op == DT_TOK_DOT);
r1 = dnp->dn_left->dn_reg;
-
- if ((r2 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ r2 = dt_regset_alloc(drp);
/*
* On little-endian architectures, ctm_offset counts from the right so
@@ -356,10 +355,9 @@ dt_cg_field_set(dt_node_t *src, dt_irlist_t *dlp,
"bits %u\n", m.ctm_offset, m.ctm_type, e.cte_bits);
}
- if ((r1 = dt_regset_alloc(drp)) == -1 ||
- (r2 = dt_regset_alloc(drp)) == -1 ||
- (r3 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ r1 = dt_regset_alloc(drp);
+ r2 = dt_regset_alloc(drp);
+ r3 = dt_regset_alloc(drp);
/*
* Compute shifts and masks. We need to compute "shift" as the amount
@@ -423,8 +421,7 @@ dt_cg_store(dt_node_t *src, dt_irlist_t *dlp, dt_regset_t *drp, dt_node_t *dst)
size = dt_node_type_size(src);
if (src->dn_flags & DT_NF_REF) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ reg = dt_regset_alloc(drp);
dt_cg_setx(dlp, reg, size);
instr = DIF_INSTR_COPYS(src->dn_reg, reg, dst->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -474,30 +471,58 @@ dt_cg_typecast(const dt_node_t *src, const dt_node_t *dst,
size_t dstsize = dt_node_type_size(dst);
dif_instr_t instr;
- int reg, n;
+ int rg;
- if (dt_node_is_scalar(dst) && (dstsize < srcsize ||
- (src->dn_flags & DT_NF_SIGNED) ^ (dst->dn_flags & DT_NF_SIGNED))) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ if (!dt_node_is_scalar(dst))
+ return; /* not a scalar */
+ if (dstsize == srcsize &&
+ ((src->dn_flags ^ dst->dn_flags) & DT_NF_SIGNED) != 0)
+ return; /* not narrowing or changing signed-ness */
+ if (dstsize > srcsize && (src->dn_flags & DT_NF_SIGNED) == 0)
+ return; /* nothing to do in this case */
- if (dstsize < srcsize)
- n = sizeof (uint64_t) * NBBY - dstsize * NBBY;
- else
- n = sizeof (uint64_t) * NBBY - srcsize * NBBY;
+ rg = dt_regset_alloc(drp);
+
+ if (dstsize > srcsize) {
+ int n = sizeof (uint64_t) * NBBY - srcsize * NBBY;
+ int s = (dstsize - srcsize) * NBBY;
- dt_cg_setx(dlp, reg, n);
+ dt_cg_setx(dlp, rg, n);
- instr = DIF_INSTR_FMT(DIF_OP_SLL,
- src->dn_reg, reg, dst->dn_reg);
+ instr = DIF_INSTR_FMT(DIF_OP_SLL, src->dn_reg, rg, dst->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
- instr = DIF_INSTR_FMT((dst->dn_flags & DT_NF_SIGNED) ?
- DIF_OP_SRA : DIF_OP_SRL, dst->dn_reg, reg, dst->dn_reg);
+ if ((dst->dn_flags & DT_NF_SIGNED) || n == s) {
+ instr = DIF_INSTR_FMT(DIF_OP_SRA,
+ dst->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ } else {
+ dt_cg_setx(dlp, rg, s);
+ instr = DIF_INSTR_FMT(DIF_OP_SRA,
+ dst->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ dt_cg_setx(dlp, rg, n - s);
+ instr = DIF_INSTR_FMT(DIF_OP_SRL,
+ dst->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp,
+ dt_cg_node_alloc(DT_LBL_NONE, instr));
+ }
+ } else if (dstsize != sizeof (uint64_t)) {
+ int n = sizeof (uint64_t) * NBBY - dstsize * NBBY;
+
+ dt_cg_setx(dlp, rg, n);
+ instr = DIF_INSTR_FMT(DIF_OP_SLL, src->dn_reg, rg, dst->dn_reg);
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
+
+ instr = DIF_INSTR_FMT((dst->dn_flags & DT_NF_SIGNED) ?
+ DIF_OP_SRA : DIF_OP_SRL, dst->dn_reg, rg, dst->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
- dt_regset_free(drp, reg);
}
+
+ dt_regset_free(drp, rg);
}
/*
@@ -523,8 +548,7 @@ dt_cg_arglist(dt_ident_t *idp, dt_node_t *args,
for (dnp = args; dnp != NULL; dnp = dnp->dn_list)
dt_cg_node(dnp, dlp, drp);
- dt_irlist_append(dlp,
- dt_cg_node_alloc(DT_LBL_NONE, DIF_INSTR_FLUSHTS));
+ dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, DIF_INSTR_FLUSHTS));
for (dnp = args; dnp != NULL; dnp = dnp->dn_list, i++) {
dtrace_diftype_t t;
@@ -538,17 +562,18 @@ dt_cg_arglist(dt_ident_t *idp, dt_node_t *args,
dt_cg_typecast(dnp, &isp->dis_args[i], dlp, drp);
isp->dis_args[i].dn_reg = -1;
- if (t.dtdt_flags & DIF_TF_BYREF)
+ if (t.dtdt_flags & DIF_TF_BYREF) {
op = DIF_OP_PUSHTR;
- else
+ if (t.dtdt_size != 0) {
+ reg = dt_regset_alloc(drp);
+ dt_cg_setx(dlp, reg, t.dtdt_size);
+ } else {
+ reg = DIF_REG_R0;
+ }
+ } else {
op = DIF_OP_PUSHTV;
-
- if (t.dtdt_size != 0) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
- dt_cg_setx(dlp, reg, t.dtdt_size);
- } else
reg = DIF_REG_R0;
+ }
instr = DIF_INSTR_PUSHTS(op, t.dtdt_kind, reg, dnp->dn_reg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -629,9 +654,7 @@ dt_cg_prearith_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp, uint_t op)
dt_cg_node(dnp->dn_child, dlp, drp);
dnp->dn_reg = dnp->dn_child->dn_reg;
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ reg = dt_regset_alloc(drp);
dt_cg_setx(dlp, reg, size);
instr = DIF_INSTR_FMT(op, dnp->dn_reg, reg, dnp->dn_reg);
@@ -688,9 +711,7 @@ dt_cg_postarith_op(dt_node_t *dnp, dt_irlist_t *dlp,
dt_cg_node(dnp->dn_child, dlp, drp);
dnp->dn_reg = dnp->dn_child->dn_reg;
- if ((nreg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ nreg = dt_regset_alloc(drp);
dt_cg_setx(dlp, nreg, size);
instr = DIF_INSTR_FMT(op, dnp->dn_reg, nreg, nreg);
dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -1008,9 +1029,7 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
* set it to the size of our data structure, and then replace
* it with the result of an allocs of the specified size.
*/
- if ((r1 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ r1 = dt_regset_alloc(drp);
dt_cg_setx(dlp, r1,
ctf_type_size(dxp->dx_dst_ctfp, dxp->dx_dst_base));
@@ -1054,8 +1073,7 @@ dt_cg_asgn_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
* and add r1 to it before storing the result.
*/
if (ctm.ctm_offset != 0) {
- if ((r2 = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ r2 = dt_regset_alloc(drp);
/*
* Add the member offset rounded down to the
@@ -1142,8 +1160,7 @@ dt_cg_assoc_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
if (dnp->dn_ident->di_flags & DT_IDFLG_TLS)
op = DIF_OP_LDTAA;
@@ -1273,9 +1290,7 @@ dt_cg_array_op(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
if ((size = dt_node_type_size(dnp)) == sizeof (uint64_t))
return;
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ reg = dt_regset_alloc(drp);
assert(size < sizeof (uint64_t));
n = sizeof (uint64_t) * NBBY - size * NBBY;
@@ -1384,7 +1399,6 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_ident_t *idp;
ssize_t stroff;
uint_t op;
- int reg;
switch (dnp->dn_op) {
case DT_TOK_COMMA:
@@ -1622,10 +1636,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
case DT_TOK_SIZEOF: {
size_t size = dt_node_sizeof(dnp->dn_child);
-
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ dnp->dn_reg = dt_regset_alloc(drp);
assert(size != 0);
dt_cg_setx(dlp, dnp->dn_reg, size);
break;
@@ -1650,8 +1661,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
assert(dxp->dx_ident->di_flags & DT_IDFLG_CGREG);
assert(dxp->dx_ident->di_id != 0);
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
if (dxp->dx_arg == -1) {
instr = DIF_INSTR_MOV(
@@ -1735,8 +1745,9 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
}
if (m.ctm_offset != 0) {
- if ((reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ int reg;
+
+ reg = dt_regset_alloc(drp);
/*
* If the offset is not aligned on a byte boundary, it
@@ -1782,8 +1793,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
break;
case DT_TOK_STRING:
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
assert(dnp->dn_kind == DT_NODE_STRING);
stroff = dt_strtab_insert(yypcb->pcb_strtab, dnp->dn_string);
@@ -1806,8 +1816,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
*/
if (dnp->dn_kind == DT_NODE_VAR &&
(dnp->dn_ident->di_flags & DT_IDFLG_CGREG)) {
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
instr = DIF_INSTR_MOV(dnp->dn_ident->di_id,
dnp->dn_reg);
dt_irlist_append(dlp,
@@ -1848,11 +1857,9 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dt_cg_arglist(dnp->dn_ident, dnp->dn_args, dlp, drp);
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
- instr = DIF_INSTR_CALL(
- dnp->dn_ident->di_id, dnp->dn_reg);
+ dnp->dn_reg = dt_regset_alloc(drp);
+ instr = DIF_INSTR_CALL(dnp->dn_ident->di_id,
+ dnp->dn_reg);
dt_irlist_append(dlp,
dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -1880,8 +1887,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
break;
}
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ dnp->dn_reg = dt_regset_alloc(drp);
if (dnp->dn_ident->di_flags & DT_IDFLG_LOCAL)
op = DIF_OP_LDLS;
@@ -1911,9 +1917,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
dtrace_errmsg(dtp, dtrace_errno(dtp)));
}
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ dnp->dn_reg = dt_regset_alloc(drp);
dt_cg_xsetx(dlp, dnp->dn_ident,
DT_LBL_NONE, dnp->dn_reg, sym.st_value);
@@ -1933,9 +1937,7 @@ dt_cg_node(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
break;
case DT_TOK_INT:
- if ((dnp->dn_reg = dt_regset_alloc(drp)) == -1)
- longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
-
+ dnp->dn_reg = dt_regset_alloc(drp);
dt_cg_setx(dlp, dnp->dn_reg, dnp->dn_value);
break;
@@ -1950,6 +1952,7 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
{
dif_instr_t instr;
dt_xlator_t *dxp;
+ dt_ident_t *idp;
if (pcb->pcb_regs == NULL && (pcb->pcb_regs =
dt_regset_create(pcb->pcb_hdl->dt_conf.dtc_difintregs)) == NULL)
@@ -1976,9 +1979,9 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
assert(pcb->pcb_dret == NULL);
pcb->pcb_dret = dnp;
- if (dt_node_is_dynamic(dnp)) {
+ if (dt_node_resolve(dnp, DT_IDENT_XLPTR) != NULL) {
dnerror(dnp, D_CG_DYN, "expression cannot evaluate to result "
- "of dynamic type\n");
+ "of a translated pointer\n");
}
/*
@@ -1994,6 +1997,14 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
}
dt_cg_node(dnp, &pcb->pcb_ir, pcb->pcb_regs);
+
+ if ((idp = dt_node_resolve(dnp, DT_IDENT_XLSOU)) != NULL) {
+ int reg = dt_cg_xlate_expand(dnp, idp,
+ &pcb->pcb_ir, pcb->pcb_regs);
+ dt_regset_free(pcb->pcb_regs, dnp->dn_reg);
+ dnp->dn_reg = reg;
+ }
+
instr = DIF_INSTR_RET(dnp->dn_reg);
dt_regset_free(pcb->pcb_regs, dnp->dn_reg);
dt_irlist_append(&pcb->pcb_ir, dt_cg_node_alloc(DT_LBL_NONE, instr));
@@ -2003,4 +2014,7 @@ dt_cg(dt_pcb_t *pcb, dt_node_t *dnp)
dxp->dx_ident->di_id = 0;
dxp->dx_ident->di_flags &= ~DT_IDFLG_CGREG;
}
+
+ dt_regset_free(pcb->pcb_regs, 0);
+ dt_regset_assert_free(pcb->pcb_regs);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
index f4bb0c4..fff4235 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
@@ -19,12 +19,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
#include <strings.h>
#include <stdio.h>
@@ -212,12 +215,22 @@ dt_dis_pushts(const dtrace_difo_t *dp,
{
static const char *const tnames[] = { "D type", "string" };
uint_t type = DIF_INSTR_TYPE(in);
+ const char *pad;
- (void) fprintf(fp, "%-4s DT_TYPE(%u), %%r%u, %%r%u",
- name, type, DIF_INSTR_R2(in), DIF_INSTR_RS(in));
+ if (DIF_INSTR_OP(in) == DIF_OP_PUSHTV) {
+ (void) fprintf(fp, "%-4s DT_TYPE(%u), %%r%u",
+ name, type, DIF_INSTR_RS(in));
+ pad = "\t\t";
+ } else {
+ (void) fprintf(fp, "%-4s DT_TYPE(%u), %%r%u, %%r%u",
+ name, type, DIF_INSTR_R2(in), DIF_INSTR_RS(in));
+ pad = "\t";
+ }
- if (type < sizeof (tnames) / sizeof (tnames[0]))
- (void) fprintf(fp, "\t! DT_TYPE(%u) = %s", type, tnames[type]);
+ if (type < sizeof (tnames) / sizeof (tnames[0])) {
+ (void) fprintf(fp, "%s! DT_TYPE(%u) = %s", pad,
+ type, tnames[type]);
+ }
}
static void
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
index a28505c..75814c1 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
@@ -23,6 +23,10 @@
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#include <string.h>
#include <strings.h>
#include <dt_impl.h>
@@ -37,7 +41,6 @@ static const struct {
{ EDT_VERSREDUCED, "Requested version conflicts with earlier setting" },
{ EDT_CTF, "Unexpected libctf error" },
{ EDT_COMPILER, "Error in D program compilation" },
- { EDT_NOREG, "Insufficient registers to generate code" },
{ EDT_NOTUPREG, "Insufficient tuple registers to generate code" },
{ EDT_NOMEM, "Memory allocation failure" },
{ EDT_INT2BIG, "Integer constant table limit exceeded" },
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
index eff9f28..353f581 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
@@ -26,7 +26,7 @@
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _DT_ERRTAGS_H
@@ -260,6 +260,7 @@ typedef enum {
D_LLQUANT_FACTOREVEN, /* llquantize() bad # steps/factor */
D_LLQUANT_FACTORSMALL, /* llquantize() magnitude too small */
D_LLQUANT_MAGTOOBIG, /* llquantize() high mag too large */
+ D_NOREG, /* no available internal registers */
D_PRINTM_ADDR, /* printm() memref bad type */
D_PRINTM_SIZE, /* printm() size bad type */
D_PRINTT_ADDR, /* printt() typeref bad type */
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
index 05cc15c..0c747ed 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
@@ -19,12 +19,15 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
#include <sys/types.h>
#include <sys/bitmap.h>
@@ -33,18 +36,19 @@
#include <stdlib.h>
#include <dt_regset.h>
+#include <dt_impl.h>
dt_regset_t *
-dt_regset_create(ulong_t size)
+dt_regset_create(ulong_t nregs)
{
- ulong_t n = BT_BITOUL(size + 1); /* + 1 for %r0 */
+ ulong_t n = BT_BITOUL(nregs);
dt_regset_t *drp = malloc(sizeof (dt_regset_t));
if (drp == NULL)
return (NULL);
drp->dr_bitmap = malloc(sizeof (ulong_t) * n);
- drp->dr_size = size + 1;
+ drp->dr_size = nregs;
if (drp->dr_bitmap == NULL) {
dt_regset_destroy(drp);
@@ -68,6 +72,25 @@ dt_regset_reset(dt_regset_t *drp)
bzero(drp->dr_bitmap, sizeof (ulong_t) * BT_BITOUL(drp->dr_size));
}
+void
+dt_regset_assert_free(dt_regset_t *drp)
+{
+ int reg;
+ boolean_t fail = B_FALSE;
+ for (reg = 0; reg < drp->dr_size; reg++) {
+ if (BT_TEST(drp->dr_bitmap, reg) != 0) {
+ dt_dprintf("%%r%d was left allocated\n", reg);
+ fail = B_TRUE;
+ }
+ }
+
+ /*
+ * We set this during dtest runs to check for register leaks.
+ */
+ if (fail && getenv("DTRACE_DEBUG_REGSET") != NULL)
+ abort();
+}
+
int
dt_regset_alloc(dt_regset_t *drp)
{
@@ -95,13 +118,15 @@ dt_regset_alloc(dt_regset_t *drp)
}
}
- return (-1); /* no available registers */
+ xyerror(D_NOREG, "Insufficient registers to generate code");
+ /*NOTREACHED*/
+ return (-1);
}
void
dt_regset_free(dt_regset_t *drp, int reg)
{
- assert(reg > 0 && reg < drp->dr_size);
+ assert(reg >= 0 && reg < drp->dr_size);
assert(BT_TEST(drp->dr_bitmap, reg) != 0);
BT_CLEAR(drp->dr_bitmap, reg);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
index 25e64d0..3508284 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
@@ -19,16 +19,19 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
#ifndef _DT_REGSET_H
#define _DT_REGSET_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#ifdef __cplusplus
@@ -45,6 +48,7 @@ extern void dt_regset_destroy(dt_regset_t *);
extern void dt_regset_reset(dt_regset_t *);
extern int dt_regset_alloc(dt_regset_t *);
extern void dt_regset_free(dt_regset_t *, int);
+extern void dt_regset_assert_free(dt_regset_t *);
#ifdef __cplusplus
}
OpenPOWER on IntegriCloud