summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-05 03:44:05 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-05 03:44:05 +0000
commit4a8c531a26f2e6b33b6910731869488f93c77775 (patch)
treed36c52a255a2810ef4f0ad9b8cf3c46f72c9931e
parent5bd91964b2ca867579a9e243e8545872700e200c (diff)
* st.c (unpack_entries): use union instead of casted pointer.
patched by Sokolov Yura <funny.falcon AT gmail.com>. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34902 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--include/ruby/st.h9
-rw-r--r--st.c20
3 files changed, 24 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 86f008dc59..74276b70d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
-Mon Mar 5 12:43:53 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Mon Mar 5 12:44:03 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * st.c (unpack_entries): use union instead of casted pointer.
+ patched by Sokolov Yura <funny.falcon AT gmail.com>.
* st.c: use PACKED_ENT and FIND_ENTRY. patched by Sokolov
Yura <funny.falcon AT gmail.com>.
diff --git a/include/ruby/st.h b/include/ruby/st.h
index 695fbf9cb9..dbb0de45a8 100644
--- a/include/ruby/st.h
+++ b/include/ruby/st.h
@@ -91,8 +91,13 @@ struct st_table {
__extension__
#endif
st_index_t num_entries : ST_INDEX_BITS - 1;
- struct st_table_entry **bins;
- struct st_table_entry *head, *tail;
+ union {
+ struct {
+ struct st_table_entry **bins;
+ struct st_table_entry *head, *tail;
+ } big;
+ struct st_packed_bins *packed;
+ } as;
};
#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
diff --git a/st.c b/st.c
index 9c494ee632..2e89756330 100644
--- a/st.c
+++ b/st.c
@@ -38,7 +38,7 @@ typedef struct st_packed_entry {
#define PACKED_UNIT (int)(sizeof(st_packed_entry) / sizeof(st_table_entry*))
#define MAX_PACKED_HASH (int)(ST_DEFAULT_PACKED_TABLE_SIZE * sizeof(st_table_entry*) / sizeof(st_packed_entry))
-typedef struct {
+typedef struct st_packed_bins {
st_packed_entry kv[MAX_PACKED_HASH];
} st_packed_bins;
@@ -105,14 +105,20 @@ st_realloc_bins(st_table_entry **bins, st_index_t newsize, st_index_t oldsize)
return bins;
}
+/* Shortage */
+#define bins as.big.bins
+#define head as.big.head
+#define tail as.big.tail
+
/* preparation for possible packing improvements */
-#define PACKED_BINS(table) (*(st_packed_bins *)(table)->bins)
+#define PACKED_BINS(table) (*(table)->as.packed)
#define PACKED_ENT(table, i) PACKED_BINS(table).kv[i]
#define PKEY(table, i) PACKED_ENT((table), (i)).key
#define PVAL(table, i) PACKED_ENT((table), (i)).val
#define PHASH(table, i) PKEY((table), (i))
#define PKEY_SET(table, i, v) (PKEY((table), (i)) = (v))
#define PVAL_SET(table, i, v) (PVAL((table), (i)) = (v))
+
/* this function depends much on packed layout, so that it placed here */
static inline void
remove_packed_entry(st_table *table, st_index_t i)
@@ -475,7 +481,7 @@ unpack_entries(register st_table *table)
st_table tmp_table = *table;
packed_bins = PACKED_BINS(table);
- table->bins = (st_table_entry **)&packed_bins;
+ table->as.packed = &packed_bins;
tmp_table.entries_packed = 0;
tmp_table.num_entries = 0;
#if ST_DEFAULT_INIT_TABLE_SIZE == ST_DEFAULT_PACKED_TABLE_SIZE
@@ -607,7 +613,7 @@ st_table*
st_copy(st_table *old_table)
{
st_table *new_table;
- st_table_entry *ptr, *entry, *prev, **tail;
+ st_table_entry *ptr, *entry, *prev, **tailp;
st_index_t num_bins = old_table->num_bins;
st_index_t hash_val;
@@ -631,7 +637,7 @@ st_copy(st_table *old_table)
if ((ptr = old_table->head) != 0) {
prev = 0;
- tail = &new_table->head;
+ tailp = &new_table->head;
do {
entry = st_alloc_entry();
if (entry == 0) {
@@ -643,8 +649,8 @@ st_copy(st_table *old_table)
entry->next = new_table->bins[hash_val];
new_table->bins[hash_val] = entry;
entry->back = prev;
- *tail = prev = entry;
- tail = &entry->fore;
+ *tailp = prev = entry;
+ tailp = &entry->fore;
} while ((ptr = ptr->fore) != 0);
new_table->tail = prev;
}