[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)) |