Author: markj
Date: Sun May 19 17:14:36 2013
New Revision: 250812
URL: http://svnweb.freebsd.org/changeset/base/250812

Log:
  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

Added:
  head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cg/
     - copied from r250811, vendor/illumos/dist/cmd/dtrace/test/tst/common/cg/
Modified:
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c  Sun May 19 
16:45:17 2013        (r250811)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cg.c  Sun May 19 
17:14:36 2013        (r250812)
@@ -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_
        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_
        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_irlis
 
        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_irlis
                    "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 
                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, con
        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
        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
                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_irl
        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_ir
        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_
                 * 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_
                         * 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
 
        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
        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 *
        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 *
 
        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 *
                        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 *
                }
 
                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 *
                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 *
                 */
                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 *
 
                        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 *
                                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 *
                                    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 *
                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);
 }

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c Sun May 19 
16:45:17 2013        (r250811)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c Sun May 19 
17:14:36 2013        (r250812)
@@ -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

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c       Sun May 
19 16:45:17 2013        (r250811)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c       Sun May 
19 17:14:36 2013        (r250812)
@@ -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" },

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h     Sun May 
19 16:45:17 2013        (r250811)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_errtags.h     Sun May 
19 17:14:36 2013        (r250812)
@@ -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 */

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c      Sun May 
19 16:45:17 2013        (r250811)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.c      Sun May 
19 17:14:36 2013        (r250812)
@@ -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);
 }

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h      Sun May 
19 16:45:17 2013        (r250811)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_regset.h      Sun May 
19 17:14:36 2013        (r250812)
@@ -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_
 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
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to