raa.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 1996-2018 The NASM Authors - All Rights Reserved
  4. * See the file AUTHORS included with the NASM distribution for
  5. * the specific copyright holders.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following
  9. * conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  20. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * ----------------------------------------------------------------------- */
  33. #include "nasmlib.h"
  34. #include "raa.h"
  35. /*
  36. * Routines to manage a dynamic random access array of int64_ts which
  37. * may grow in size to be more than the largest single malloc'able
  38. * chunk.
  39. */
  40. #define RAA_BLKSHIFT 15 /* 2**this many longs allocated at once */
  41. #define RAA_BLKSIZE (1 << RAA_BLKSHIFT)
  42. #define RAA_LAYERSHIFT 15 /* 2**this many _pointers_ allocated */
  43. #define RAA_LAYERSIZE (1 << RAA_LAYERSHIFT)
  44. typedef union RAA_UNION RAA_UNION;
  45. typedef struct RAA_LEAF RAA_LEAF;
  46. typedef struct RAA_BRANCH RAA_BRANCH;
  47. struct real_raa {
  48. /*
  49. * Number of layers below this one to get to the real data. 0
  50. * means this structure is a leaf, holding RAA_BLKSIZE real
  51. * data items; 1 and above mean it's a branch, holding
  52. * RAA_LAYERSIZE pointers to the next level branch or leaf
  53. * structures.
  54. */
  55. int layers;
  56. /*
  57. * Number of real data items spanned by one position in the
  58. * `data' array at this level. This number is 0 trivially, for
  59. * a leaf (level 0): for a level 1 branch it should be
  60. * RAA_BLKSHIFT, and for a level 2 branch it's
  61. * RAA_LAYERSHIFT+RAA_BLKSHIFT.
  62. */
  63. int shift;
  64. union RAA_UNION {
  65. struct RAA_LEAF {
  66. union intorptr data[RAA_BLKSIZE];
  67. } l;
  68. struct RAA_BRANCH {
  69. struct real_raa *data[RAA_LAYERSIZE];
  70. } b;
  71. } u;
  72. };
  73. struct RAA {
  74. struct real_raa raa;
  75. };
  76. struct RAAPTR {
  77. struct real_raa raa;
  78. };
  79. #define LEAFSIZ (sizeof(struct real_raa)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
  80. #define BRANCHSIZ (sizeof(struct real_raa)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
  81. #define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
  82. static struct real_raa *raa_init_layer(int layers)
  83. {
  84. struct real_raa *r;
  85. if (layers == 0) {
  86. r = nasm_zalloc(LEAFSIZ);
  87. r->shift = 0;
  88. } else {
  89. r = nasm_zalloc(BRANCHSIZ);
  90. r->layers = layers;
  91. r->shift = (RAA_BLKSHIFT - RAA_LAYERSHIFT) + layers * RAA_LAYERSHIFT;
  92. }
  93. return r;
  94. }
  95. struct real_raa *real_raa_init(void)
  96. {
  97. return raa_init_layer(0);
  98. }
  99. void real_raa_free(struct real_raa *r)
  100. {
  101. if (r->layers) {
  102. struct real_raa **p;
  103. for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
  104. if (*p)
  105. real_raa_free(*p);
  106. }
  107. nasm_free(r);
  108. }
  109. static const union intorptr *real_raa_read(struct real_raa *r, int32_t posn)
  110. {
  111. if ((uint32_t) posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r))))
  112. return NULL; /* Beyond the end */
  113. while (r->layers > 0) {
  114. int32_t l = posn >> r->shift;
  115. posn &= (UINT32_C(1) << r->shift) - 1;
  116. r = r->u.b.data[l];
  117. if (!r)
  118. return NULL; /* Not present */
  119. }
  120. return &r->u.l.data[posn];
  121. }
  122. int64_t raa_read(struct RAA *r, int32_t pos)
  123. {
  124. const union intorptr *ip;
  125. ip = real_raa_read((struct real_raa *)r, pos);
  126. return ip ? ip->i : 0;
  127. }
  128. void *raa_read_ptr(struct RAAPTR *r, int32_t pos)
  129. {
  130. const union intorptr *ip;
  131. ip = real_raa_read((struct real_raa *)r, pos);
  132. return ip ? ip->p : NULL;
  133. }
  134. struct real_raa *
  135. real_raa_write(struct real_raa *r, int32_t posn, union intorptr value)
  136. {
  137. struct real_raa *result;
  138. nasm_assert(posn >= 0);
  139. while ((UINT32_C(1) << (r->shift + LAYERSHIFT(r))) <= (uint32_t) posn) {
  140. /*
  141. * Must add a layer.
  142. */
  143. struct real_raa *s;
  144. s = nasm_zalloc(BRANCHSIZ);
  145. s->layers = r->layers + 1;
  146. s->shift = LAYERSHIFT(r) + r->shift;
  147. s->u.b.data[0] = r;
  148. r = s;
  149. }
  150. result = r;
  151. while (r->layers > 0) {
  152. struct real_raa **s;
  153. int32_t l = posn >> r->shift;
  154. posn &= (UINT32_C(1) << r->shift) - 1;
  155. s = &r->u.b.data[l];
  156. if (!*s)
  157. *s = raa_init_layer(r->layers - 1);
  158. r = *s;
  159. }
  160. r->u.l.data[posn] = value;
  161. return result;
  162. }