Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 May 2013 17:14:37 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r250812 - in head/cddl/contrib/opensolaris: cmd/dtrace/test/tst/common/cg lib/libdtrace/common
Message-ID:  <201305191714.r4JHEbJ1057384@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305191714.r4JHEbJ1057384>