From f24325648c601d4b0835074f271072f4832e4478 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 1 Nov 2018 13:05:06 +0100 Subject: [PATCH] cpp: avoid a gazillion calls to memcpy/memmove --- src/cpp.c | 42 ++++---- src/cpp.h | 13 ++- src/cpp_tokiter.c | 242 ++++++++++++++++++++++++++------------------ src/parser.c | 2 +- src/plist.c | 8 ++ src/plist.h | 2 + src/token.c | 21 ++-- src/types/cpp_exp.c | 2 + 8 files changed, 205 insertions(+), 127 deletions(-) diff --git a/src/cpp.c b/src/cpp.c index 2a53df8..64a1b55 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -73,7 +73,8 @@ static int dump_def(zval *p) struct psi_cpp_macro_decl *decl = Z_PTR_P(p); if (decl) { - dprintf(2, "#define "); + fflush(stderr); + dprintf(2, "PSI: CPP decl -> #define "); psi_cpp_macro_decl_dump(2, decl); dprintf(2, "\n"); } @@ -87,7 +88,6 @@ void psi_cpp_free(struct psi_cpp **cpp_ptr) struct psi_cpp *cpp = *cpp_ptr; #if PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP decls:\n"); zend_hash_apply(&cpp->defs, dump_def); #endif *cpp_ptr = NULL; @@ -117,8 +117,8 @@ static bool psi_cpp_stage1(struct psi_cpp *cpp) /* line continuations */ if (token->type == PSI_T_EOL) { if (esc) { - psi_cpp_tokiter_del_range(cpp, psi_cpp_tokiter_index(cpp) - 1, 2, true); - psi_cpp_tokiter_prev(cpp); + psi_cpp_tokiter_del_prev(cpp, true); + psi_cpp_tokiter_del_cur(cpp, true); esc = false; continue; } @@ -174,7 +174,7 @@ static bool psi_cpp_stage1(struct psi_cpp *cpp) no_ws->type = PSI_T_NO_WHITESPACE; zend_string_release(no_ws->text); no_ws->text = zend_string_init("\xA0", 1, 1); - psi_cpp_tokiter_ins_cur(cpp, no_ws); + psi_cpp_tokiter_add(cpp, no_ws); continue; } } @@ -185,6 +185,7 @@ static bool psi_cpp_stage1(struct psi_cpp *cpp) } ws = false; + psi_cpp_tokiter_add_cur(cpp); psi_cpp_tokiter_next(cpp); } @@ -266,7 +267,6 @@ static bool psi_cpp_stage2(struct psi_cpp *cpp) } if (cpp->skip) { - /* FIXME: del_range */ if (!do_cpp) { #if PSI_CPP_DEBUG fprintf(stderr, "PSI: CPP skip "); @@ -317,6 +317,7 @@ static bool psi_cpp_stage2(struct psi_cpp *cpp) continue; } + psi_cpp_tokiter_add_cur(cpp); psi_cpp_tokiter_next(cpp); } @@ -330,14 +331,24 @@ bool psi_cpp_process(struct psi_cpp *cpp, struct psi_plist **tokens) bool parsed = false; struct psi_cpp temp = *cpp; - cpp->tokens = *tokens; + cpp->tokens.iter = *tokens; + cpp->tokens.next = NULL; + if (psi_cpp_stage1(cpp) && psi_cpp_stage2(cpp)) { parsed = true; } - *tokens = cpp->tokens; - if (temp.tokens) { - cpp->tokens = temp.tokens; + if (cpp->tokens.next) { + free(cpp->tokens.iter); + cpp->tokens.iter = cpp->tokens.next; + cpp->tokens.next = NULL; + } + + *tokens = cpp->tokens.iter; + + if (temp.tokens.iter) { + cpp->tokens.iter = temp.tokens.iter; + cpp->tokens.next = temp.tokens.next; cpp->index = temp.index; } @@ -378,9 +389,9 @@ void psi_cpp_define(struct psi_cpp *cpp, struct psi_cpp_macro_decl *decl) } #if PSI_CPP_DEBUG if (decl->exp) { - fprintf(stderr, "MACRO: num_exp: ", decl->token->text); - } else if (decl->tokens) { - fprintf(stderr, "MACRO: decl : ", decl->token->text); + fprintf(stderr, "PSI: CPP MACRO num_exp -> %s ", decl->token->text->val); + } else { + fprintf(stderr, "PSI: CPP MACRO decl -> %s ", decl->token->text->val); } psi_cpp_macro_decl_dump(2, decl); fprintf(stderr, "\n"); @@ -427,10 +438,7 @@ static inline bool try_include(struct psi_cpp *cpp, const char *path, bool *pars size_t num_tokens = psi_plist_count(tokens); ++cpp->expanded; - psi_cpp_tokiter_ins_range(cpp, cpp->index, - num_tokens, psi_plist_eles(tokens)); - /* skip already processed tokens */ - cpp->index += num_tokens; + psi_cpp_tokiter_add_range(cpp, num_tokens, psi_plist_eles(tokens)); free(tokens); } else { psi_plist_free(tokens); diff --git a/src/cpp.h b/src/cpp.h index 49bdd31..5ace4bf 100644 --- a/src/cpp.h +++ b/src/cpp.h @@ -36,7 +36,10 @@ struct psi_cpp { HashTable defs; HashTable once; struct psi_parser *parser; - struct psi_plist *tokens; + struct { + struct psi_plist *iter; + struct psi_plist *next; + } tokens; const char *search; size_t index; unsigned level; @@ -72,10 +75,14 @@ void psi_cpp_tokiter_next(struct psi_cpp *cpp); void psi_cpp_tokiter_prev(struct psi_cpp *cpp); bool psi_cpp_tokiter_valid(struct psi_cpp *cpp); bool psi_cpp_tokiter_del_cur(struct psi_cpp *cpp, bool free_token); +bool psi_cpp_tokiter_del_prev(struct psi_cpp *cpp, bool free_token); bool psi_cpp_tokiter_del_range(struct psi_cpp *cpp, size_t offset, size_t num_eles, bool free_tokens); -bool psi_cpp_tokiter_ins_cur(struct psi_cpp *cpp, struct psi_token *tok); -bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t offset, +bool psi_cpp_tokiter_add(struct psi_cpp *cpp, struct psi_token *tok); +bool psi_cpp_tokiter_add_cur(struct psi_cpp *cpp); +bool psi_cpp_tokiter_add_range(struct psi_cpp *cpp, + size_t num_eles, void **eles); +bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t num_eles, void **eles); bool psi_cpp_tokiter_defined(struct psi_cpp *cpp); bool psi_cpp_tokiter_expand(struct psi_cpp *cpp); diff --git a/src/cpp_tokiter.c b/src/cpp_tokiter.c index 8073281..f2b468e 100644 --- a/src/cpp_tokiter.c +++ b/src/cpp_tokiter.c @@ -28,44 +28,54 @@ #include "cpp.h" #include "parser.h" -#if PSI_CPP_DEBUG > 1 void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp) { size_t i = cpp->index; struct psi_token *T; - if (i > 20) { - i -= 20; + if (i > 40) { + i -= 40; } else { i = 0; } - while (psi_plist_get(cpp->tokens, i, &T)) { + while (psi_plist_get(cpp->tokens.iter, i, &T)) { dprintf(fd, "PSI: CPP tokens %5zu %c ", i, cpp->index == i ? '*' : ' '); - psi_token_dump(fd, T); - if (i >= cpp->index + 10) { + if (T) { + psi_token_dump(fd, T); + } else { + dprintf(fd, "TOKEN deleted\n"); + } + if (i >= cpp->index + 40) { dprintf(fd, "PSI: CPP tokens .....\n"); break; } ++i; } } -#endif void psi_cpp_tokiter_reset(struct psi_cpp *cpp) { #if PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP reset (%zu tokens)\n", psi_plist_count(cpp->tokens)); + fprintf(stderr, "PSI: CPP reset -> iter.count=%zu, next.count=%zu\n", + psi_plist_count(cpp->tokens.iter), + psi_plist_count(cpp->tokens.next)); # if PSI_CPP_DEBUG > 1 psi_cpp_tokiter_dump(2, cpp); # endif #endif cpp->index = 0; cpp->expanded = 0; + + if (cpp->tokens.next) { + free(cpp->tokens.iter); + cpp->tokens.iter = cpp->tokens.next; + } + cpp->tokens.next = psi_plist_init((psi_plist_dtor) psi_token_free); } bool psi_cpp_tokiter_seek(struct psi_cpp *cpp, size_t index) { - if (index < psi_plist_count(cpp->tokens)) { + if (index < psi_plist_count(cpp->tokens.iter)) { cpp->index = index; return true; } @@ -75,7 +85,7 @@ bool psi_cpp_tokiter_seek(struct psi_cpp *cpp, size_t index) struct psi_token *psi_cpp_tokiter_current(struct psi_cpp *cpp) { struct psi_token *current = NULL; - bool found = psi_plist_get(cpp->tokens, cpp->index, ¤t); + bool found = psi_plist_get(cpp->tokens.iter, cpp->index, ¤t); assert(found); @@ -87,118 +97,161 @@ size_t psi_cpp_tokiter_index(struct psi_cpp *cpp) return cpp->index; } -void psi_cpp_tokiter_next(struct psi_cpp *cpp) +bool psi_cpp_tokiter_add_cur(struct psi_cpp *cpp) { -#if 0 && PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP next -> index=%zu -> index=%zu\n", cpp->index, cpp->index+1); + struct psi_token *cur = NULL; + + if (psi_plist_get(cpp->tokens.iter, cpp->index, &cur)) { + struct psi_plist *tokens = psi_plist_add(cpp->tokens.next, &cur); + + if (tokens) { + cpp->tokens.next = tokens; + +#if PSI_CPP_DEBUG + fprintf(stderr, "PSI: CPP add_cur -> index=%zu, iter.count=%zu, next.count=%zu ", + cpp->index, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next)); + psi_token_dump(2, cur); #endif - ++cpp->index; + + return true; + } + } + + return false; } -void psi_cpp_tokiter_prev(struct psi_cpp *cpp) +bool psi_cpp_tokiter_add(struct psi_cpp *cpp, struct psi_token *tok) { -#if 0 && PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP prev -> index=%zu -> index=%zu\n", cpp->index, cpp->index-1); + struct psi_plist *tokens = psi_plist_add(cpp->tokens.next, &tok); + + if (!tokens) { + return false; + } + cpp->tokens.next = tokens; + +#if PSI_CPP_DEBUG + fprintf(stderr, "PSI: CPP add -> index=%zu, iter.count=%zu, next.count=%zu ", + cpp->index, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next)); + psi_token_dump(2, tok); #endif - if (cpp->index) { - --cpp->index; + + return true; +} + + +bool psi_cpp_tokiter_add_range(struct psi_cpp *cpp, size_t num_eles, void **eles) +{ + struct psi_plist *tokens; + + if (!num_eles) { + return true; + } + + tokens = psi_plist_add_r(cpp->tokens.next, num_eles, eles); + if (!tokens) { + return false; } + cpp->tokens.next = tokens; + +#if PSI_CPP_DEBUG + fprintf(stderr, "PSI: CPP add_range -> index=%zu, num_eles=%zu, iter.count=%zu, next.count=%zu\n", + cpp->index, num_eles, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next)); +#endif + + return true; +} + + +void psi_cpp_tokiter_next(struct psi_cpp *cpp) +{ +#if 0 && PSI_CPP_DEBUG + fprintf(stderr, "PSI: CPP next -> index=%zu -> index=%zu\n", + cpp->index, cpp->index+1); +#endif + ++cpp->index; } bool psi_cpp_tokiter_valid(struct psi_cpp *cpp) { #if 0 && PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP valid -> index=%zu -> %d\n", cpp->index, cpp->index < psi_plist_count(cpp->tokens)); + fprintf(stderr, "PSI: CPP valid -> index=%zu -> %d\n", + cpp->index, cpp->index < psi_plist_count(cpp->tokens.iter)); #endif - return cpp->index < psi_plist_count(cpp->tokens); + return cpp->index < psi_plist_count(cpp->tokens.iter); } -bool psi_cpp_tokiter_del_cur(struct psi_cpp *cpp, bool free_token) +bool psi_cpp_tokiter_del_prev(struct psi_cpp *cpp, bool free_token) { struct psi_token *cur = NULL; - bool deleted = psi_plist_del(cpp->tokens, cpp->index, &cur); - size_t count; #if PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP del_cur -> index=%zu, del=%d, free=%d, count=%zu ", - cpp->index, (int) deleted, (int) free_token, psi_plist_count(cpp->tokens)); - if (cur) { - psi_token_dump(2, cur); - } else { - fprintf(stderr, "NULL\n"); - } + fprintf(stderr, "PSI: CPP del_prev -> index=%zu, iter.count=%zu, next.count\n", + cpp->index, psi_plist_count(cpp->tokens.iter)); #endif - if (free_token) { - psi_token_free(&cur); - } - count = psi_plist_count(cpp->tokens); - if (deleted && cpp->index >= count) { - if (count > 0) { - cpp->index = count - 1; - } else { - cpp->index = 0; + + if (psi_plist_pop(cpp->tokens.next, NULL) && psi_plist_get(cpp->tokens.iter, cpp->index - 1, &cur)) { + psi_plist_unset(cpp->tokens.iter, cpp->index - 1); + if (free_token && cur) { + psi_token_free(&cur); } + return true; } - return deleted; -} -bool psi_cpp_tokiter_del_range(struct psi_cpp *cpp, size_t offset, size_t num_eles, bool free_tokens) + return false; +} +bool psi_cpp_tokiter_del_cur(struct psi_cpp *cpp, bool free_token) { - struct psi_token **ptr; - bool deleted; - - if (free_tokens) { - ptr = calloc(num_eles, sizeof(*ptr)); - } else { - ptr = NULL; - } + struct psi_token *cur = NULL; #if PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP del_range -> index=%zu, offset=%zu, num_eles=%zu, count=%zu\n", - cpp->index, offset, num_eles, psi_plist_count(cpp->tokens)); + fprintf(stderr, "PSI: CPP del_cur -> index=%zu, iter.count=%zu, next.count=%zu ", + cpp->index, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next)); #endif - deleted = psi_plist_del_r(cpp->tokens, offset, num_eles, (void *) ptr); - - if (deleted) { - size_t count = psi_plist_count(cpp->tokens); - - if (cpp->index >= count) { - if (count > 0) { - cpp->index = count - 1; - } else { - cpp->index = 0; - } - } - - if (free_tokens) { - while (num_eles--) { - psi_token_free(&ptr[num_eles]); - } - free(ptr); + if (psi_plist_get(cpp->tokens.iter, cpp->index, &cur)) { +#if PSI_CPP_DEBUG + psi_token_dump(2, cur); +#endif + psi_plist_unset(cpp->tokens.iter, cpp->index); + if (free_token && cur) { + psi_token_free(&cur); } + ++cpp->index; + return true; } - return deleted; + + return false; } -bool psi_cpp_tokiter_ins_cur(struct psi_cpp *cpp, struct psi_token *tok) +bool psi_cpp_tokiter_del_range(struct psi_cpp *cpp, size_t offset, size_t num_eles, bool free_tokens) { - struct psi_plist *tokens = psi_plist_ins(cpp->tokens, cpp->index, &tok); + struct psi_token *ptr; + size_t i; #if PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP ins_cur -> index=%zu ", cpp->index); - psi_token_dump(2, tok); + fprintf(stderr, "PSI: CPP del_range -> index=%zu, offset=%zu, num_eles=%zu, iter.count=%zu, next.count=%zu\n", + cpp->index, offset, num_eles, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next)); #endif - if (!tokens) { - return false; + for (i = offset; i < offset + num_eles; ++i) { + if (!psi_plist_get(cpp->tokens.iter, i, &ptr)) { + return false; + } +#if PSI_CPP_DEBUG + fprintf(stderr, "PSI: CPP del_range -> "); + psi_token_dump(2, ptr); +#endif + psi_plist_unset(cpp->tokens.iter, i); + if (free_tokens && ptr) { + psi_token_free(&ptr); + } } - cpp->tokens = tokens; + + cpp->index = i; return true; } -bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t offset, - size_t num_eles, void **eles) +bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t num_eles, void **eles) { struct psi_plist *tokens; @@ -206,17 +259,17 @@ bool psi_cpp_tokiter_ins_range(struct psi_cpp *cpp, size_t offset, return true; } - tokens = psi_plist_ins_r(cpp->tokens, offset, num_eles, eles); + tokens = psi_plist_ins_r(cpp->tokens.iter, cpp->index, num_eles, eles); + if (!tokens) { + return false; + } + cpp->tokens.iter = tokens; #if PSI_CPP_DEBUG - fprintf(stderr, "PSI: CPP ins_range -> index=%zu, offset=%zu, num_eles=%zu, count=%zu\n", - cpp->index, offset, num_eles, psi_plist_count(tokens)); + fprintf(stderr, "PSI: CPP ins_range -> index=%zu, num_eles=%zu, iter.count=%zu, next.count=%zu\n", + cpp->index, num_eles, psi_plist_count(cpp->tokens.iter), psi_plist_count(cpp->tokens.next)); #endif - if (!tokens) { - return false; - } - cpp->tokens = tokens; return true; } @@ -282,7 +335,7 @@ static size_t psi_cpp_tokiter_expand_tokens(struct psi_cpp *cpp, paste = false; stringify = false; } - psi_cpp_tokiter_ins_range(cpp, psi_cpp_tokiter_index(cpp), n, (void *) exp_tokens); + psi_cpp_tokiter_ins_range(cpp, n, (void *) exp_tokens); free(exp_tokens); return n; @@ -432,15 +485,11 @@ static bool psi_cpp_tokiter_expand_call(struct psi_cpp *cpp, /* ditch arg tokens */ psi_cpp_tokiter_del_range(cpp, start, psi_cpp_tokiter_index(cpp) - start + 1, false); - psi_cpp_tokiter_seek(cpp, start); /* insert and expand macro tokens */ psi_cpp_tokiter_expand_call_tokens(cpp, target, macro, arg_tokens_list); psi_cpp_tokiter_free_call_tokens(arg_tokens_list, psi_plist_count(macro->sig), true); - /* back to where we took off */ - psi_cpp_tokiter_seek(cpp, start); - psi_token_free(&target); ++cpp->expanded; return true; @@ -449,15 +498,8 @@ static bool psi_cpp_tokiter_expand_call(struct psi_cpp *cpp, static bool psi_cpp_tokiter_expand_def(struct psi_cpp *cpp, struct psi_token *target, struct psi_cpp_macro_decl *macro) { - size_t index = psi_cpp_tokiter_index(cpp); - /* delete current token from stream */ psi_cpp_tokiter_del_cur(cpp, false); - - if (index != psi_cpp_tokiter_index(cpp)) { - /* might have been last token */ - psi_cpp_tokiter_next(cpp); - } /* replace with tokens from macro */ psi_cpp_tokiter_expand_tokens(cpp, target, macro->tokens); diff --git a/src/parser.c b/src/parser.c index af5d7fd..dfeb970 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,4 +1,4 @@ -/* Generated by re2c 1.1.1 on Wed Oct 31 09:21:44 2018 */ +/* Generated by re2c 1.1.1 on Thu Nov 1 08:10:31 2018 */ #line 1 "src/parser.re" /******************************************************************************* Copyright (c) 2016, Michael Wallner . diff --git a/src/plist.c b/src/plist.c index 58f7898..699db2c 100644 --- a/src/plist.c +++ b/src/plist.c @@ -140,6 +140,14 @@ bool psi_plist_get(struct psi_plist *list, size_t index, void *ptr) { return false; } +bool psi_plist_unset(struct psi_plist *list, size_t index) { + if (list && list->count > index) { + memset(PLIST_ELE(list, index), 0, list->size); + return true; + } + return false; +} + bool psi_plist_del(struct psi_plist *list, size_t index, void *ptr) { if (list && list->count > index) { if (ptr) { diff --git a/src/plist.h b/src/plist.h index b4187a4..e119ead 100644 --- a/src/plist.h +++ b/src/plist.h @@ -47,6 +47,8 @@ bool psi_plist_del_r(struct psi_plist *list, size_t offset_start, size_t offset_ struct psi_plist *psi_plist_ins(struct psi_plist *list, size_t index, void *ptr); struct psi_plist *psi_plist_ins_r(struct psi_plist *list, size_t offset_start, size_t num_eles, void **eles); +bool psi_plist_unset(struct psi_plist *list, size_t index); + bool psi_plist_shift(struct psi_plist *list, void *ptr); bool psi_plist_pop(struct psi_plist *list, void *ptr); bool psi_plist_top(struct psi_plist *list, void *ptr); diff --git a/src/token.c b/src/token.c index df7d2e8..5dbb2ec 100644 --- a/src/token.c +++ b/src/token.c @@ -32,9 +32,9 @@ #include "token.h" #include "parser.h" -size_t psi_token_alloc_size(size_t token_len, size_t fname_len) { - return sizeof(struct psi_token) + token_len + fname_len + 2; -} +#ifndef PSI_DEBUG_TOKEN_ALLOC +# define PSI_DEBUG_TOKEN_ALLOC 0 +#endif struct psi_token *psi_token_init(token_t token_typ, const char *token_txt, size_t token_len, unsigned col, unsigned line, zend_string *file) @@ -47,14 +47,18 @@ struct psi_token *psi_token_init(token_t token_typ, const char *token_txt, T->line = line; T->file = zend_string_copy(file); T->text = zend_string_init(token_txt, token_len, 1); - +#if PSI_DEBUG_TOKEN_ALLOC + fprintf(stderr, "PSI: token_init %p\n", T); +#endif return T; } void psi_token_free(struct psi_token **token_ptr) { if (*token_ptr) { struct psi_token *token = *token_ptr; - +#if PSI_DEBUG_TOKEN_ALLOC + fprintf(stderr, "PSI: token_free %p\n", token); +#endif *token_ptr = NULL; zend_string_release(token->text); zend_string_release(token->file); @@ -66,7 +70,9 @@ struct psi_token *psi_token_copy(struct psi_token *src) { struct psi_token *ptr = malloc(sizeof(*ptr)); *ptr = *src; - +#if PSI_DEBUG_TOKEN_ALLOC + fprintf(stderr, "PSI: token_copy %p <= %p\n", ptr, src); +#endif ptr->text = zend_string_copy(ptr->text); ptr->file = zend_string_copy(ptr->file); @@ -103,6 +109,9 @@ struct psi_token *psi_token_cat(const char *sep, unsigned argc, ...) { T->text = smart_str_extract(&text); +#if PSI_DEBUG_TOKEN_ALLOC + fprintf(stderr, "PSI: token_cat %p\n", T); +#endif return T; } diff --git a/src/types/cpp_exp.c b/src/types/cpp_exp.c index ded4db5..6f0fff0 100644 --- a/src/types/cpp_exp.c +++ b/src/types/cpp_exp.c @@ -184,6 +184,8 @@ void psi_cpp_exp_exec(struct psi_cpp_exp *exp, struct psi_cpp *cpp, struct psi_d exp->token->text->val, cpp->level, cpp->skip); #if PSI_CPP_DEBUG + fflush(stderr); + dprintf(2, "PSI: CPP exec -> "); psi_cpp_exp_dump(2, exp); #endif -- 2.30.2