slide_hash_c.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. /* slide_hash.c -- slide hash table C implementation
  2. *
  3. * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
  4. * For conditions of distribution and use, see copyright notice in zlib.h
  5. */
  6. #include "zbuild.h"
  7. #include "deflate.h"
  8. /* ===========================================================================
  9. * Slide the hash table when sliding the window down (could be avoided with 32
  10. * bit values at the expense of memory usage). We slide even when level == 0 to
  11. * keep the hash table consistent if we switch back to level > 0 later.
  12. */
  13. static inline void slide_hash_c_chain(Pos *table, uint32_t entries, uint16_t wsize) {
  14. #ifdef NOT_TWEAK_COMPILER
  15. table += entries;
  16. do {
  17. unsigned m;
  18. m = *--table;
  19. *table = (Pos)(m >= wsize ? m-wsize : 0);
  20. /* If entries is not on any hash chain, prev[entries] is garbage but
  21. * its value will never be used.
  22. */
  23. } while (--entries);
  24. #else
  25. {
  26. /* As of I make this change, gcc (4.8.*) isn't able to vectorize
  27. * this hot loop using saturated-subtraction on x86-64 architecture.
  28. * To avoid this defect, we can change the loop such that
  29. * o. the pointer advance forward, and
  30. * o. demote the variable 'm' to be local to the loop, and
  31. * choose type "Pos" (instead of 'unsigned int') for the
  32. * variable to avoid unnecessary zero-extension.
  33. */
  34. unsigned int i;
  35. Pos *q = table;
  36. for (i = 0; i < entries; i++) {
  37. Pos m = *q;
  38. Pos t = (Pos)wsize;
  39. *q++ = (Pos)(m >= t ? m-t: 0);
  40. }
  41. }
  42. #endif /* NOT_TWEAK_COMPILER */
  43. }
  44. Z_INTERNAL void slide_hash_c(deflate_state *s) {
  45. uint16_t wsize = (uint16_t)s->w_size;
  46. slide_hash_c_chain(s->head, HASH_SIZE, wsize);
  47. slide_hash_c_chain(s->prev, wsize, wsize);
  48. }