summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2009-10-13 13:01:52 +0100
committerNicholas Clark <nick@ccl4.org>2009-10-13 13:01:52 +0100
commit98fe6610b077571e54be1d655e66e1ad657a8910 (patch)
tree532bceb1ec03d62f050fe0aaa10aae2addb9f312
parent26c7b074d5d3f0a79fab5f1c4eb28f38e81b88d2 (diff)
downloadperl-98fe6610b077571e54be1d655e66e1ad657a8910.tar.gz
Change S_ckwarn_common() to looping over the packed warning value.
The core never uses WARN3() or WARN4(), and rarely uses WARN2(), so the previous code, effectively an unwrapped loop, wasn't a speed up. Functionally equivalent smaller code fits better into CPU caches.
-rw-r--r--util.c25
-rw-r--r--warnings.h2
-rw-r--r--warnings.pl2
3 files changed, 22 insertions, 7 deletions
diff --git a/util.c b/util.c
index 13b56a0802..b72f263dc5 100644
--- a/util.c
+++ b/util.c
@@ -1627,15 +1627,26 @@ S_ckwarn_common(pTHX_ U32 w)
if (PL_curcop->cop_warnings == pWARN_NONE)
return FALSE;
+ /* Check the assumption that at least the first slot is non-zero. */
+ assert(unpackWARN1(w));
+
+ /* Check the assumption that it is valid to stop as soon as a zero slot is
+ seen. */
+ if (!unpackWARN2(w)) {
+ assert(!unpackWARN3(w));
+ assert(!unpackWARN4(w));
+ } else if (!unpackWARN3(w)) {
+ assert(!unpackWARN4(w));
+ }
+
/* Right, dealt with all the special cases, which are implemented as non-
pointers, so there is a pointer to a real warnings mask. */
- return isWARN_on(PL_curcop->cop_warnings, unpackWARN1(w))
- || (unpackWARN2(w) &&
- isWARN_on(PL_curcop->cop_warnings, unpackWARN2(w)))
- || (unpackWARN3(w) &&
- isWARN_on(PL_curcop->cop_warnings, unpackWARN3(w)))
- || (unpackWARN4(w) &&
- isWARN_on(PL_curcop->cop_warnings, unpackWARN4(w)));
+ do {
+ if (isWARN_on(PL_curcop->cop_warnings, unpackWARN1(w)))
+ return TRUE;
+ } while (w >>= WARNshift);
+
+ return FALSE;
}
/* Set buffer=NULL to get a new one. */
diff --git a/warnings.h b/warnings.h
index 8f891a7511..56b307912d 100644
--- a/warnings.h
+++ b/warnings.h
@@ -105,6 +105,8 @@
#define ckWARN3_d(w1,w2,w3) Perl_ckwarn_d(aTHX_ packWARN3(w1,w2,w3))
#define ckWARN4_d(w1,w2,w3,w4) Perl_ckwarn_d(aTHX_ packWARN4(w1,w2,w3,w4))
+#define WARNshift 8
+
#define packWARN(a) (a )
#define packWARN2(a,b) ((a) | ((b)<<8) )
#define packWARN3(a,b,c) ((a) | ((b)<<8) | ((c)<<16) )
diff --git a/warnings.pl b/warnings.pl
index 6bd611b604..dabc97d63a 100644
--- a/warnings.pl
+++ b/warnings.pl
@@ -353,6 +353,8 @@ print $warn <<'EOM';
#define ckWARN3_d(w1,w2,w3) Perl_ckwarn_d(aTHX_ packWARN3(w1,w2,w3))
#define ckWARN4_d(w1,w2,w3,w4) Perl_ckwarn_d(aTHX_ packWARN4(w1,w2,w3,w4))
+#define WARNshift 8
+
#define packWARN(a) (a )
#define packWARN2(a,b) ((a) | ((b)<<8) )
#define packWARN3(a,b,c) ((a) | ((b)<<8) | ((c)<<16) )