diff -rpU3 save2/regex_internal.h ./regex_internal.h --- save2/regex_internal.h Wed Oct 23 08:46:28 2002 +++ ./regex_internal.h Wed Oct 23 09:35:13 2002 @@ -400,8 +400,8 @@ struct re_state_table_entry struct re_backref_cache_entry { - int node, dst_node; - int str_idx; + int node, str_idx, hash; + int dst_node; int subexp_from; int subexp_to; int subexp_len; diff -rpU3 save2/regexec.c ./regexec.c --- save2/regexec.c Wed Oct 23 08:46:28 2002 +++ ./regexec.c Wed Oct 23 09:38:29 2002 @@ -1901,7 +1901,7 @@ sift_states_bkref (preg, mctx, sctx, str { reg_errcode_t err; re_dfa_t *dfa = (re_dfa_t *)preg->buffer; - int node_idx, node; + int node_idx, node, hash; re_sift_context_t local_sctx; const re_node_set *candidates; candidates = ((mctx->state_log[str_idx] == NULL) ? &empty_set @@ -1920,15 +1920,36 @@ sift_states_bkref (preg, mctx, sctx, str continue; type = dfa->nodes[node].type; + hash = str_idx + (node << 16); if (type == OP_BACK_REF) { int enabled_idx; - for (enabled_idx = 0; enabled_idx < mctx->nbkref_ents; ++enabled_idx) + static int last_node = -1, last_str_idx = -1, last_first_enabled_idx = 0; + + if (node == last_node && str_idx == last_str_idx) + enabled_idx = last_first_enabled_idx; + else + for (enabled_idx = 0; enabled_idx < mctx->nbkref_ents; ++enabled_idx) + { + struct re_backref_cache_entry *entry; + entry = mctx->bkref_ents + enabled_idx; + if (entry->hash == hash && entry->node == node && entry->str_idx == str_idx) + { + last_node = node; + last_str_idx = str_idx; + last_first_enabled_idx = enabled_idx; + break; + } + } + + for (; enabled_idx < mctx->nbkref_ents; ++enabled_idx) { int disabled_idx, subexp_len, to_idx, dst_node; struct re_backref_cache_entry *entry; entry = mctx->bkref_ents + enabled_idx; - if (entry->node != node || entry->str_idx != str_idx) + if (entry->hash != hash + || BE(entry->node != node, 0) + || BE(entry->str_idx != str_idx, 0)) continue; subexp_len = entry->subexp_len; @@ -1970,7 +1991,9 @@ sift_states_bkref (preg, mctx, sctx, str { struct re_backref_cache_entry *entry2; entry2 = mctx->bkref_ents + disabled_idx; - if (entry2->node != node || entry2->str_idx != str_idx) + if (entry2->hash != hash + || BE(entry2->node != node, 0) + || BE(entry2->str_idx != str_idx, 0)) continue; entry2->flag = 1; } @@ -2007,11 +2030,14 @@ sift_states_bkref (preg, mctx, sctx, str mctx->bkref_ents[enabled_idx].flag = 1; } } - for (enabled_idx = 0; enabled_idx < mctx->nbkref_ents; ++enabled_idx) + for (enabled_idx = last_first_enabled_idx; + enabled_idx < mctx->nbkref_ents; ++enabled_idx) { struct re_backref_cache_entry *entry; entry = mctx->bkref_ents + enabled_idx; - if (entry->node == node && entry->str_idx == str_idx) + if (entry->hash == hash + && BE(entry->node == node, 1) + && BE(entry->str_idx == str_idx, 1)) entry->flag = 0; } } @@ -3140,6 +3166,7 @@ match_ctx_add_entry (mctx, dfa, node, st } mctx->bkref_ents[mctx->nbkref_ents].node = node; mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx; + mctx->bkref_ents[mctx->nbkref_ents].hash = str_idx + (node << 16); mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from; mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to; mctx->bkref_ents[mctx->nbkref_ents].subexp_len = to - from;