summaryrefslogtreecommitdiff
path: root/nasmlib
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2017-04-29 13:28:12 -0700
committerH. Peter Anvin <hpa@zytor.com>2017-04-29 13:28:12 -0700
commit97408d67dd9de77743cdb0222ad4e6aeea2a635c (patch)
treec83e696a4fb4aeeac79386b08965862095558d72 /nasmlib
parentb84ac822499b367566d66266bf6a4c41f257248a (diff)
parent53cd7c7bf0a100d01fc31caf3c20987e66a9ed64 (diff)
downloadnasm-97408d67dd9de77743cdb0222ad4e6aeea2a635c.tar.gz
Merge remote-tracking branch 'origin/elf'
Diffstat (limited to 'nasmlib')
-rw-r--r--nasmlib/hashtbl.c26
-rw-r--r--nasmlib/ilog2.c16
-rw-r--r--nasmlib/srcfile.c8
3 files changed, 42 insertions, 8 deletions
diff --git a/nasmlib/hashtbl.c b/nasmlib/hashtbl.c
index 7f8fca63..bc0776b8 100644
--- a/nasmlib/hashtbl.c
+++ b/nasmlib/hashtbl.c
@@ -222,7 +222,9 @@ void *hash_iterate(const struct hash_table *head,
/*
* Free the hash itself. Doesn't free the data elements; use
- * hash_iterate() to do that first, if needed.
+ * hash_iterate() to do that first, if needed. This function is normally
+ * used when the hash data entries are either freed separately, or
+ * compound objects which can't be freed in a single operation.
*/
void hash_free(struct hash_table *head)
{
@@ -230,3 +232,25 @@ void hash_free(struct hash_table *head)
head->table = NULL;
nasm_free(p);
}
+
+/*
+ * Frees the hash *and* all data elements. This is applicable only in
+ * the case where the data element is a single allocation. If the
+ * second argument is false, the key string is part of the data
+ * allocation or belongs to an allocation which will be freed
+ * separately, if it is true the keys are also freed.
+ */
+void hash_free_all(struct hash_table *head, bool free_keys)
+{
+ struct hash_tbl_node *iter = NULL;
+ const char *keyp;
+ void *d;
+
+ while ((d = hash_iterate(head, &iter, &keyp))) {
+ nasm_free(d);
+ if (free_keys)
+ nasm_free((void *)keyp);
+ }
+
+ hash_free(head);
+}
diff --git a/nasmlib/ilog2.c b/nasmlib/ilog2.c
index 1bd24dba..7f4624f5 100644
--- a/nasmlib/ilog2.c
+++ b/nasmlib/ilog2.c
@@ -85,6 +85,14 @@ int ilog2_32(uint32_t v)
return __builtin_clz(v) ^ 31;
}
+#elif defined(HAVE__BITSCANREVERSE)
+
+int ilog2_32(uint32_t v)
+{
+ unsigned long ix;
+ return _BitScanReverse(&ix, v) ? v : 0;
+}
+
#else
int ilog2_32(uint32_t v)
@@ -124,6 +132,14 @@ int ilog2_64(uint64_t v)
return __builtin_clzll(v) ^ 63;
}
+#elif defined(HAVE__BITSCANREVERSE64)
+
+int ilog2_64(uint64_t v)
+{
+ unsigned long ix;
+ return _BitScanReverse64(&ix, v) ? ix : 0;
+}
+
#else
int ilog2_64(uint64_t vv)
diff --git a/nasmlib/srcfile.c b/nasmlib/srcfile.c
index 7bee0176..6fbe763f 100644
--- a/nasmlib/srcfile.c
+++ b/nasmlib/srcfile.c
@@ -55,13 +55,7 @@ void src_init(void)
void src_free(void)
{
- struct hash_tbl_node *iter = NULL;
- void *dp;
-
- while ((dp = hash_iterate(&filename_hash, &iter, NULL)) != NULL)
- nasm_free(dp);
-
- hash_free(&filename_hash);
+ hash_free_all(&filename_hash, false);
}
/*