[core] Add branch prediction annotations to Parrot.
From: Mark Glines <mark@glines.org>
---
include/parrot/compiler.h | 8 ++++++++
include/parrot/exceptions.h | 4 ++--
src/gc/mark_sweep.c | 2 +-
src/hash.c | 6 +++---
4 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/include/parrot/compiler.h b/include/parrot/compiler.h
index 7657801..051718d 100644
a
|
b
|
|
28 | 28 | # define PARROT_HAS_SAL 0 |
29 | 29 | #endif |
30 | 30 | |
| 31 | #ifdef __GNUC__ |
| 32 | # define likely(x) __builtin_expect(!!(x), 1) |
| 33 | # define unlikely(x) __builtin_expect(!!(x), 0) |
| 34 | #else |
| 35 | # define likely(x) (x) |
| 36 | # define unlikely(x) (x) |
| 37 | #endif |
| 38 | |
31 | 39 | #ifdef HASATTRIBUTE_NEVER_WORKS |
32 | 40 | # error This attribute can never succeed. Something has mis-sniffed your configuration. |
33 | 41 | #endif |
diff --git a/include/parrot/exceptions.h b/include/parrot/exceptions.h
index 1c0a3a2..14def86 100644
a
|
b
|
|
280 | 280 | # define PARROT_ASSERT_ARG(x) (0) |
281 | 281 | # define ASSERT_ARGS(a) |
282 | 282 | #else |
283 | | # define PARROT_ASSERT(x) (x) ? ((void)0) : Parrot_confess(#x, __FILE__, __LINE__) |
284 | | # define PARROT_ASSERT_ARG(x) ((x) ? (0) : (Parrot_confess(#x, __FILE__, __LINE__), 0)) |
| 283 | # define PARROT_ASSERT(x) likely(x) ? ((void)0) : Parrot_confess(#x, __FILE__, __LINE__) |
| 284 | # define PARROT_ASSERT_ARG(x) (likely(x) ? (0) : (Parrot_confess(#x, __FILE__, __LINE__), 0)) |
285 | 285 | |
286 | 286 | # ifdef __GNUC__ |
287 | 287 | # define ASSERT_ARGS(a) ASSERT_ARGS_ ## a ; |
diff --git a/src/gc/mark_sweep.c b/src/gc/mark_sweep.c
index 8c2b680..d482b6a 100644
a
|
b
|
|
771 | 771 | Arenas * const arena_base = interp->arena_base; |
772 | 772 | |
773 | 773 | /* TODO collect objects with finalizers */ |
774 | | if (PObj_needs_early_gc_TEST(p)) |
| 774 | if (unlikely(PObj_needs_early_gc_TEST(p))) |
775 | 775 | --arena_base->num_early_gc_PMCs; |
776 | 776 | |
777 | 777 | if (PObj_active_destroy_TEST(p)) |
diff --git a/src/hash.c b/src/hash.c
index 6d5dc0d..0bd7054 100644
a
|
b
|
|
1192 | 1192 | { |
1193 | 1193 | ASSERT_ARGS(parrot_hash_get_bucket) |
1194 | 1194 | |
1195 | | if (hash->entries <= 0) |
| 1195 | if (unlikely(hash->entries <= 0)) |
1196 | 1196 | return NULL; |
1197 | 1197 | |
1198 | 1198 | /* a very fast search for very small hashes */ |
… |
… |
|
1214 | 1214 | const UINTVAL hashval = (hash->hash_val)(interp, key, hash->seed); |
1215 | 1215 | HashBucket *bucket = hash->bi[hashval & hash->mask]; |
1216 | 1216 | |
1217 | | while (bucket) { |
| 1217 | while (likely(bucket)) { |
1218 | 1218 | /* key equality is always a match, so it's worth checking */ |
1219 | | if (bucket->key == key |
| 1219 | if (unlikely(bucket->key == key) |
1220 | 1220 | |
1221 | 1221 | /* ... but the slower comparison is more accurate */ |
1222 | 1222 | || ((hash->compare)(interp, key, bucket->key) == 0)) |