pg_query 2.2.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (895) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +57 -31
  4. data/Rakefile +5 -6
  5. data/ext/pg_query/ext_symbols_freebsd.sym +1 -0
  6. data/ext/pg_query/ext_symbols_freebsd_with_ruby_abi_version.sym +2 -0
  7. data/ext/pg_query/ext_symbols_openbsd.sym +1 -0
  8. data/ext/pg_query/ext_symbols_openbsd_with_ruby_abi_version.sym +2 -0
  9. data/ext/pg_query/ext_symbols_with_ruby_abi_version.sym +2 -0
  10. data/ext/pg_query/extconf.rb +33 -9
  11. data/ext/pg_query/include/pg_query.h +30 -4
  12. data/ext/pg_query/include/pg_query_enum_defs.c +839 -290
  13. data/ext/pg_query/include/pg_query_fingerprint_conds.c +638 -481
  14. data/ext/pg_query/include/pg_query_fingerprint_defs.c +6786 -4193
  15. data/ext/pg_query/include/pg_query_outfuncs_conds.c +450 -330
  16. data/ext/pg_query/include/pg_query_outfuncs_defs.c +1489 -1044
  17. data/ext/pg_query/include/pg_query_readfuncs_conds.c +157 -118
  18. data/ext/pg_query/include/pg_query_readfuncs_defs.c +1933 -1410
  19. data/ext/pg_query/include/postgres/access/amapi.h +303 -0
  20. data/ext/pg_query/include/postgres/access/attmap.h +54 -0
  21. data/ext/pg_query/include/postgres/access/attnum.h +64 -0
  22. data/ext/pg_query/include/postgres/access/brin_internal.h +116 -0
  23. data/ext/pg_query/include/postgres/access/brin_tuple.h +112 -0
  24. data/ext/pg_query/include/postgres/access/clog.h +62 -0
  25. data/ext/pg_query/include/postgres/access/commit_ts.h +73 -0
  26. data/ext/pg_query/include/postgres/access/detoast.h +82 -0
  27. data/ext/pg_query/include/postgres/access/genam.h +246 -0
  28. data/ext/pg_query/include/postgres/access/gin.h +91 -0
  29. data/ext/pg_query/include/postgres/access/htup.h +89 -0
  30. data/ext/pg_query/include/postgres/access/htup_details.h +811 -0
  31. data/ext/pg_query/include/postgres/access/itup.h +170 -0
  32. data/ext/pg_query/include/postgres/access/parallel.h +81 -0
  33. data/ext/pg_query/include/postgres/access/printtup.h +35 -0
  34. data/ext/pg_query/include/postgres/access/relation.h +28 -0
  35. data/ext/pg_query/include/postgres/access/relscan.h +191 -0
  36. data/ext/pg_query/include/postgres/access/rmgr.h +62 -0
  37. data/ext/pg_query/include/postgres/access/rmgrlist.h +49 -0
  38. data/ext/pg_query/include/postgres/access/sdir.h +67 -0
  39. data/ext/pg_query/include/postgres/access/skey.h +151 -0
  40. data/ext/pg_query/include/postgres/access/slru.h +218 -0
  41. data/ext/pg_query/include/postgres/access/stratnum.h +85 -0
  42. data/ext/pg_query/include/postgres/access/sysattr.h +29 -0
  43. data/ext/pg_query/include/postgres/access/table.h +28 -0
  44. data/ext/pg_query/include/postgres/access/tableam.h +2110 -0
  45. data/ext/pg_query/include/postgres/access/tidstore.h +50 -0
  46. data/ext/pg_query/include/postgres/access/toast_compression.h +73 -0
  47. data/ext/pg_query/include/postgres/access/transam.h +418 -0
  48. data/ext/pg_query/include/postgres/access/tsmapi.h +82 -0
  49. data/ext/pg_query/include/postgres/access/tupconvert.h +54 -0
  50. data/ext/pg_query/include/postgres/access/tupdesc.h +154 -0
  51. data/ext/pg_query/include/postgres/access/tupmacs.h +207 -0
  52. data/ext/pg_query/include/postgres/access/twophase.h +65 -0
  53. data/ext/pg_query/include/postgres/access/xact.h +530 -0
  54. data/ext/pg_query/include/postgres/access/xlog.h +310 -0
  55. data/ext/pg_query/include/postgres/access/xlog_internal.h +405 -0
  56. data/ext/pg_query/include/postgres/access/xlogbackup.h +43 -0
  57. data/ext/pg_query/include/postgres/access/xlogdefs.h +82 -0
  58. data/ext/pg_query/include/postgres/access/xlogprefetcher.h +55 -0
  59. data/ext/pg_query/include/postgres/access/xlogreader.h +444 -0
  60. data/ext/pg_query/include/postgres/access/xlogrecord.h +248 -0
  61. data/ext/pg_query/include/postgres/access/xlogrecovery.h +158 -0
  62. data/ext/pg_query/include/postgres/archive/archive_module.h +67 -0
  63. data/ext/pg_query/include/postgres/c.h +1374 -0
  64. data/ext/pg_query/include/postgres/catalog/catalog.h +47 -0
  65. data/ext/pg_query/include/postgres/catalog/catversion.h +62 -0
  66. data/ext/pg_query/include/postgres/catalog/dependency.h +228 -0
  67. data/ext/pg_query/include/postgres/catalog/genbki.h +149 -0
  68. data/ext/pg_query/include/postgres/catalog/index.h +218 -0
  69. data/ext/pg_query/include/postgres/catalog/indexing.h +54 -0
  70. data/ext/pg_query/include/postgres/catalog/namespace.h +189 -0
  71. data/ext/pg_query/include/postgres/catalog/objectaccess.h +267 -0
  72. data/ext/pg_query/include/postgres/catalog/objectaddress.h +93 -0
  73. data/ext/pg_query/include/postgres/catalog/pg_aggregate.h +182 -0
  74. data/ext/pg_query/include/postgres/catalog/pg_aggregate_d.h +78 -0
  75. data/ext/pg_query/include/postgres/catalog/pg_am.h +66 -0
  76. data/ext/pg_query/include/postgres/catalog/pg_am_d.h +47 -0
  77. data/ext/pg_query/include/postgres/catalog/pg_attribute.h +240 -0
  78. data/ext/pg_query/include/postgres/catalog/pg_attribute_d.h +62 -0
  79. data/ext/pg_query/include/postgres/catalog/pg_authid.h +66 -0
  80. data/ext/pg_query/include/postgres/catalog/pg_authid_d.h +60 -0
  81. data/ext/pg_query/include/postgres/catalog/pg_class.h +235 -0
  82. data/ext/pg_query/include/postgres/catalog/pg_class_d.h +134 -0
  83. data/ext/pg_query/include/postgres/catalog/pg_collation.h +106 -0
  84. data/ext/pg_query/include/postgres/catalog/pg_collation_d.h +66 -0
  85. data/ext/pg_query/include/postgres/catalog/pg_constraint.h +278 -0
  86. data/ext/pg_query/include/postgres/catalog/pg_constraint_d.h +74 -0
  87. data/ext/pg_query/include/postgres/catalog/pg_control.h +260 -0
  88. data/ext/pg_query/include/postgres/catalog/pg_conversion.h +79 -0
  89. data/ext/pg_query/include/postgres/catalog/pg_conversion_d.h +38 -0
  90. data/ext/pg_query/include/postgres/catalog/pg_database.h +129 -0
  91. data/ext/pg_query/include/postgres/catalog/pg_database_d.h +53 -0
  92. data/ext/pg_query/include/postgres/catalog/pg_depend.h +77 -0
  93. data/ext/pg_query/include/postgres/catalog/pg_depend_d.h +36 -0
  94. data/ext/pg_query/include/postgres/catalog/pg_event_trigger.h +60 -0
  95. data/ext/pg_query/include/postgres/catalog/pg_event_trigger_d.h +36 -0
  96. data/ext/pg_query/include/postgres/catalog/pg_index.h +92 -0
  97. data/ext/pg_query/include/postgres/catalog/pg_index_d.h +59 -0
  98. data/ext/pg_query/include/postgres/catalog/pg_language.h +75 -0
  99. data/ext/pg_query/include/postgres/catalog/pg_language_d.h +41 -0
  100. data/ext/pg_query/include/postgres/catalog/pg_namespace.h +67 -0
  101. data/ext/pg_query/include/postgres/catalog/pg_namespace_d.h +36 -0
  102. data/ext/pg_query/include/postgres/catalog/pg_opclass.h +91 -0
  103. data/ext/pg_query/include/postgres/catalog/pg_opclass_d.h +51 -0
  104. data/ext/pg_query/include/postgres/catalog/pg_operator.h +124 -0
  105. data/ext/pg_query/include/postgres/catalog/pg_operator_d.h +142 -0
  106. data/ext/pg_query/include/postgres/catalog/pg_opfamily.h +67 -0
  107. data/ext/pg_query/include/postgres/catalog/pg_opfamily_d.h +51 -0
  108. data/ext/pg_query/include/postgres/catalog/pg_partitioned_table.h +76 -0
  109. data/ext/pg_query/include/postgres/catalog/pg_partitioned_table_d.h +36 -0
  110. data/ext/pg_query/include/postgres/catalog/pg_proc.h +223 -0
  111. data/ext/pg_query/include/postgres/catalog/pg_proc_d.h +101 -0
  112. data/ext/pg_query/include/postgres/catalog/pg_publication.h +161 -0
  113. data/ext/pg_query/include/postgres/catalog/pg_publication_d.h +38 -0
  114. data/ext/pg_query/include/postgres/catalog/pg_replication_origin.h +65 -0
  115. data/ext/pg_query/include/postgres/catalog/pg_replication_origin_d.h +33 -0
  116. data/ext/pg_query/include/postgres/catalog/pg_statistic.h +288 -0
  117. data/ext/pg_query/include/postgres/catalog/pg_statistic_d.h +199 -0
  118. data/ext/pg_query/include/postgres/catalog/pg_statistic_ext.h +91 -0
  119. data/ext/pg_query/include/postgres/catalog/pg_statistic_ext_d.h +45 -0
  120. data/ext/pg_query/include/postgres/catalog/pg_transform.h +51 -0
  121. data/ext/pg_query/include/postgres/catalog/pg_transform_d.h +34 -0
  122. data/ext/pg_query/include/postgres/catalog/pg_trigger.h +153 -0
  123. data/ext/pg_query/include/postgres/catalog/pg_trigger_d.h +109 -0
  124. data/ext/pg_query/include/postgres/catalog/pg_ts_config.h +56 -0
  125. data/ext/pg_query/include/postgres/catalog/pg_ts_config_d.h +34 -0
  126. data/ext/pg_query/include/postgres/catalog/pg_ts_dict.h +62 -0
  127. data/ext/pg_query/include/postgres/catalog/pg_ts_dict_d.h +35 -0
  128. data/ext/pg_query/include/postgres/catalog/pg_ts_parser.h +63 -0
  129. data/ext/pg_query/include/postgres/catalog/pg_ts_parser_d.h +37 -0
  130. data/ext/pg_query/include/postgres/catalog/pg_ts_template.h +54 -0
  131. data/ext/pg_query/include/postgres/catalog/pg_ts_template_d.h +34 -0
  132. data/ext/pg_query/include/postgres/catalog/pg_type.h +407 -0
  133. data/ext/pg_query/include/postgres/catalog/pg_type_d.h +324 -0
  134. data/ext/pg_query/include/postgres/catalog/storage.h +50 -0
  135. data/ext/pg_query/include/postgres/catalog/syscache_ids.h +104 -0
  136. data/ext/pg_query/include/postgres/commands/async.h +49 -0
  137. data/ext/pg_query/include/postgres/commands/dbcommands.h +37 -0
  138. data/ext/pg_query/include/postgres/commands/defrem.h +161 -0
  139. data/ext/pg_query/include/postgres/commands/event_trigger.h +97 -0
  140. data/ext/pg_query/include/postgres/commands/explain.h +145 -0
  141. data/ext/pg_query/include/postgres/commands/prepare.h +61 -0
  142. data/ext/pg_query/include/postgres/commands/tablespace.h +69 -0
  143. data/ext/pg_query/include/postgres/commands/trigger.h +288 -0
  144. data/ext/pg_query/include/postgres/commands/user.h +43 -0
  145. data/ext/pg_query/include/postgres/commands/vacuum.h +388 -0
  146. data/ext/pg_query/include/postgres/common/cryptohash.h +39 -0
  147. data/ext/pg_query/include/postgres/common/file_perm.h +56 -0
  148. data/ext/pg_query/include/postgres/common/file_utils.h +65 -0
  149. data/ext/pg_query/include/postgres/common/hashfn.h +119 -0
  150. data/ext/pg_query/include/postgres/common/hashfn_unstable.h +407 -0
  151. data/ext/pg_query/include/postgres/common/int.h +512 -0
  152. data/ext/pg_query/include/postgres/common/keywords.h +29 -0
  153. data/ext/pg_query/include/postgres/common/kwlookup.h +44 -0
  154. data/ext/pg_query/include/postgres/common/pg_prng.h +62 -0
  155. data/ext/pg_query/include/postgres/common/relpath.h +97 -0
  156. data/ext/pg_query/include/postgres/common/scram-common.h +70 -0
  157. data/ext/pg_query/include/postgres/common/sha2.h +32 -0
  158. data/ext/pg_query/include/postgres/common/string.h +44 -0
  159. data/ext/pg_query/include/postgres/common/unicode_east_asian_fw_table.h +124 -0
  160. data/ext/pg_query/include/postgres/common/unicode_nonspacing_table.h +326 -0
  161. data/ext/pg_query/include/postgres/copyfuncs.funcs.c +5261 -0
  162. data/ext/pg_query/include/postgres/copyfuncs.switch.c +989 -0
  163. data/ext/pg_query/include/postgres/datatype/timestamp.h +269 -0
  164. data/ext/pg_query/include/postgres/equalfuncs.funcs.c +3310 -0
  165. data/ext/pg_query/include/postgres/equalfuncs.switch.c +836 -0
  166. data/ext/pg_query/include/postgres/executor/execdesc.h +70 -0
  167. data/ext/pg_query/include/postgres/executor/executor.h +681 -0
  168. data/ext/pg_query/include/postgres/executor/functions.h +56 -0
  169. data/ext/pg_query/include/postgres/executor/instrument.h +120 -0
  170. data/ext/pg_query/include/postgres/executor/spi.h +207 -0
  171. data/ext/pg_query/include/postgres/executor/tablefunc.h +67 -0
  172. data/ext/pg_query/include/postgres/executor/tuptable.h +523 -0
  173. data/ext/pg_query/include/postgres/fmgr.h +800 -0
  174. data/ext/pg_query/include/postgres/foreign/fdwapi.h +294 -0
  175. data/ext/pg_query/include/postgres/funcapi.h +360 -0
  176. data/ext/pg_query/include/postgres/gram.h +1168 -0
  177. data/ext/pg_query/include/postgres/gramparse.h +75 -0
  178. data/ext/pg_query/include/postgres/jit/jit.h +106 -0
  179. data/ext/pg_query/include/postgres/kwlist_d.h +1164 -0
  180. data/ext/pg_query/include/postgres/lib/dshash.h +130 -0
  181. data/ext/pg_query/include/postgres/lib/ilist.h +1159 -0
  182. data/ext/pg_query/include/postgres/lib/pairingheap.h +102 -0
  183. data/ext/pg_query/include/postgres/lib/simplehash.h +1206 -0
  184. data/ext/pg_query/include/postgres/lib/sort_template.h +445 -0
  185. data/ext/pg_query/include/postgres/lib/stringinfo.h +243 -0
  186. data/ext/pg_query/include/postgres/libpq/auth.h +37 -0
  187. data/ext/pg_query/include/postgres/libpq/crypt.h +47 -0
  188. data/ext/pg_query/include/postgres/libpq/hba.h +186 -0
  189. data/ext/pg_query/include/postgres/libpq/libpq-be.h +361 -0
  190. data/ext/pg_query/include/postgres/libpq/libpq.h +143 -0
  191. data/ext/pg_query/include/postgres/libpq/pqcomm.h +169 -0
  192. data/ext/pg_query/include/postgres/libpq/pqformat.h +209 -0
  193. data/ext/pg_query/include/postgres/libpq/pqsignal.h +54 -0
  194. data/ext/pg_query/include/postgres/libpq/protocol.h +89 -0
  195. data/ext/pg_query/include/postgres/libpq/sasl.h +136 -0
  196. data/ext/pg_query/include/postgres/libpq/scram.h +37 -0
  197. data/ext/pg_query/include/postgres/mb/pg_wchar.h +793 -0
  198. data/ext/pg_query/include/postgres/mb/stringinfo_mb.h +24 -0
  199. data/ext/pg_query/include/postgres/miscadmin.h +527 -0
  200. data/ext/pg_query/include/postgres/nodes/bitmapset.h +140 -0
  201. data/ext/pg_query/include/postgres/nodes/execnodes.h +2855 -0
  202. data/ext/pg_query/include/postgres/nodes/extensible.h +164 -0
  203. data/ext/pg_query/include/postgres/nodes/lockoptions.h +61 -0
  204. data/ext/pg_query/include/postgres/nodes/makefuncs.h +127 -0
  205. data/ext/pg_query/include/postgres/nodes/memnodes.h +152 -0
  206. data/ext/pg_query/include/postgres/nodes/miscnodes.h +56 -0
  207. data/ext/pg_query/include/postgres/nodes/nodeFuncs.h +222 -0
  208. data/ext/pg_query/include/postgres/nodes/nodes.h +435 -0
  209. data/ext/pg_query/include/postgres/nodes/nodetags.h +491 -0
  210. data/ext/pg_query/include/postgres/nodes/params.h +170 -0
  211. data/ext/pg_query/include/postgres/nodes/parsenodes.h +4233 -0
  212. data/ext/pg_query/include/postgres/nodes/pathnodes.h +3438 -0
  213. data/ext/pg_query/include/postgres/nodes/pg_list.h +686 -0
  214. data/ext/pg_query/include/postgres/nodes/plannodes.h +1593 -0
  215. data/ext/pg_query/include/postgres/nodes/primnodes.h +2339 -0
  216. data/ext/pg_query/include/postgres/nodes/print.h +34 -0
  217. data/ext/pg_query/include/postgres/nodes/queryjumble.h +86 -0
  218. data/ext/pg_query/include/postgres/nodes/replnodes.h +132 -0
  219. data/ext/pg_query/include/postgres/nodes/supportnodes.h +346 -0
  220. data/ext/pg_query/include/postgres/nodes/tidbitmap.h +75 -0
  221. data/ext/pg_query/include/postgres/nodes/value.h +90 -0
  222. data/ext/pg_query/include/postgres/optimizer/cost.h +216 -0
  223. data/ext/pg_query/include/postgres/optimizer/geqo.h +90 -0
  224. data/ext/pg_query/include/postgres/optimizer/geqo_gene.h +45 -0
  225. data/ext/pg_query/include/postgres/optimizer/optimizer.h +205 -0
  226. data/ext/pg_query/include/postgres/optimizer/paths.h +271 -0
  227. data/ext/pg_query/include/postgres/optimizer/planmain.h +123 -0
  228. data/ext/pg_query/include/postgres/parser/analyze.h +66 -0
  229. data/ext/pg_query/include/postgres/parser/kwlist.h +518 -0
  230. data/ext/pg_query/include/postgres/parser/parse_agg.h +65 -0
  231. data/ext/pg_query/include/postgres/parser/parse_coerce.h +105 -0
  232. data/ext/pg_query/include/postgres/parser/parse_expr.h +25 -0
  233. data/ext/pg_query/include/postgres/parser/parse_func.h +74 -0
  234. data/ext/pg_query/include/postgres/parser/parse_node.h +358 -0
  235. data/ext/pg_query/include/postgres/parser/parse_oper.h +68 -0
  236. data/ext/pg_query/include/postgres/parser/parse_relation.h +129 -0
  237. data/ext/pg_query/include/postgres/parser/parse_type.h +61 -0
  238. data/ext/pg_query/include/postgres/parser/parser.h +68 -0
  239. data/ext/pg_query/include/postgres/parser/parsetree.h +61 -0
  240. data/ext/pg_query/include/postgres/parser/scanner.h +152 -0
  241. data/ext/pg_query/include/postgres/parser/scansup.h +27 -0
  242. data/ext/pg_query/include/postgres/partitioning/partdefs.h +26 -0
  243. data/ext/pg_query/include/postgres/pg_config.h +985 -0
  244. data/ext/pg_query/include/postgres/pg_config_manual.h +385 -0
  245. data/ext/pg_query/include/postgres/pg_config_os.h +8 -0
  246. data/ext/pg_query/include/postgres/pg_getopt.h +56 -0
  247. data/ext/pg_query/include/postgres/pg_trace.h +17 -0
  248. data/ext/pg_query/include/postgres/pgstat.h +780 -0
  249. data/ext/pg_query/include/postgres/pgtime.h +94 -0
  250. data/ext/pg_query/include/postgres/pl_gram.h +385 -0
  251. data/ext/pg_query/include/postgres/pl_reserved_kwlist.h +52 -0
  252. data/ext/pg_query/include/postgres/pl_reserved_kwlist_d.h +114 -0
  253. data/ext/pg_query/include/postgres/pl_unreserved_kwlist.h +112 -0
  254. data/ext/pg_query/include/postgres/pl_unreserved_kwlist_d.h +246 -0
  255. data/ext/pg_query/include/postgres/plerrcodes.h +998 -0
  256. data/ext/pg_query/include/postgres/plpgsql.h +1342 -0
  257. data/ext/pg_query/include/postgres/port/atomics/arch-arm.h +32 -0
  258. data/ext/pg_query/include/postgres/port/atomics/arch-hppa.h +17 -0
  259. data/ext/pg_query/include/postgres/port/atomics/arch-ppc.h +256 -0
  260. data/ext/pg_query/include/postgres/port/atomics/arch-x86.h +254 -0
  261. data/ext/pg_query/include/postgres/port/atomics/fallback.h +170 -0
  262. data/ext/pg_query/include/postgres/port/atomics/generic-gcc.h +323 -0
  263. data/ext/pg_query/include/postgres/port/atomics/generic-msvc.h +119 -0
  264. data/ext/pg_query/include/postgres/port/atomics/generic-sunpro.h +121 -0
  265. data/ext/pg_query/include/postgres/port/atomics/generic.h +437 -0
  266. data/ext/pg_query/include/postgres/port/atomics.h +606 -0
  267. data/ext/pg_query/include/postgres/port/pg_bitutils.h +421 -0
  268. data/ext/pg_query/include/postgres/port/pg_bswap.h +161 -0
  269. data/ext/pg_query/include/postgres/port/pg_crc32c.h +110 -0
  270. data/ext/pg_query/include/postgres/port/pg_iovec.h +117 -0
  271. data/ext/pg_query/include/postgres/port/simd.h +422 -0
  272. data/ext/pg_query/include/postgres/port/win32/arpa/inet.h +3 -0
  273. data/ext/pg_query/include/postgres/port/win32/dlfcn.h +1 -0
  274. data/ext/pg_query/include/postgres/port/win32/grp.h +1 -0
  275. data/ext/pg_query/include/postgres/port/win32/netdb.h +7 -0
  276. data/ext/pg_query/include/postgres/port/win32/netinet/in.h +3 -0
  277. data/ext/pg_query/include/postgres/port/win32/netinet/tcp.h +7 -0
  278. data/ext/pg_query/include/postgres/port/win32/pwd.h +3 -0
  279. data/ext/pg_query/include/postgres/port/win32/sys/resource.h +20 -0
  280. data/ext/pg_query/include/postgres/port/win32/sys/select.h +3 -0
  281. data/ext/pg_query/include/postgres/port/win32/sys/socket.h +34 -0
  282. data/ext/pg_query/include/postgres/port/win32/sys/un.h +17 -0
  283. data/ext/pg_query/include/postgres/port/win32/sys/wait.h +3 -0
  284. data/ext/pg_query/include/postgres/port/win32.h +59 -0
  285. data/ext/pg_query/include/postgres/port/win32_msvc/dirent.h +34 -0
  286. data/ext/pg_query/include/postgres/port/win32_msvc/sys/file.h +1 -0
  287. data/ext/pg_query/include/postgres/port/win32_msvc/sys/param.h +1 -0
  288. data/ext/pg_query/include/postgres/port/win32_msvc/sys/time.h +1 -0
  289. data/ext/pg_query/include/postgres/port/win32_msvc/unistd.h +9 -0
  290. data/ext/pg_query/include/postgres/port/win32_msvc/utime.h +3 -0
  291. data/ext/pg_query/include/postgres/port/win32_port.h +582 -0
  292. data/ext/pg_query/include/postgres/port.h +555 -0
  293. data/ext/pg_query/include/postgres/portability/instr_time.h +197 -0
  294. data/ext/pg_query/include/postgres/postgres.h +579 -0
  295. data/ext/pg_query/include/postgres/postgres_ext.h +73 -0
  296. data/ext/pg_query/include/postgres/postmaster/autovacuum.h +69 -0
  297. data/ext/pg_query/include/postgres/postmaster/bgworker.h +164 -0
  298. data/ext/pg_query/include/postgres/postmaster/bgworker_internals.h +60 -0
  299. data/ext/pg_query/include/postgres/postmaster/bgwriter.h +45 -0
  300. data/ext/pg_query/include/postgres/postmaster/interrupt.h +32 -0
  301. data/ext/pg_query/include/postgres/postmaster/pgarch.h +36 -0
  302. data/ext/pg_query/include/postgres/postmaster/postmaster.h +101 -0
  303. data/ext/pg_query/include/postgres/postmaster/startup.h +41 -0
  304. data/ext/pg_query/include/postgres/postmaster/syslogger.h +101 -0
  305. data/ext/pg_query/include/postgres/postmaster/walsummarizer.h +35 -0
  306. data/ext/pg_query/include/postgres/postmaster/walwriter.h +23 -0
  307. data/ext/pg_query/include/postgres/regex/regex.h +272 -0
  308. data/ext/pg_query/include/postgres/replication/logicallauncher.h +34 -0
  309. data/ext/pg_query/include/postgres/replication/logicalproto.h +274 -0
  310. data/ext/pg_query/include/postgres/replication/logicalworker.h +33 -0
  311. data/ext/pg_query/include/postgres/replication/origin.h +73 -0
  312. data/ext/pg_query/include/postgres/replication/reorderbuffer.h +734 -0
  313. data/ext/pg_query/include/postgres/replication/slot.h +289 -0
  314. data/ext/pg_query/include/postgres/replication/slotsync.h +38 -0
  315. data/ext/pg_query/include/postgres/replication/syncrep.h +109 -0
  316. data/ext/pg_query/include/postgres/replication/walreceiver.h +504 -0
  317. data/ext/pg_query/include/postgres/replication/walsender.h +76 -0
  318. data/ext/pg_query/include/postgres/rewrite/prs2lock.h +46 -0
  319. data/ext/pg_query/include/postgres/rewrite/rewriteHandler.h +41 -0
  320. data/ext/pg_query/include/postgres/rewrite/rewriteManip.h +96 -0
  321. data/ext/pg_query/include/postgres/rewrite/rewriteSupport.h +26 -0
  322. data/ext/pg_query/include/postgres/storage/block.h +108 -0
  323. data/ext/pg_query/include/postgres/storage/buf.h +46 -0
  324. data/ext/pg_query/include/postgres/storage/bufmgr.h +411 -0
  325. data/ext/pg_query/include/postgres/storage/bufpage.h +510 -0
  326. data/ext/pg_query/include/postgres/storage/condition_variable.h +73 -0
  327. data/ext/pg_query/include/postgres/storage/dsm.h +61 -0
  328. data/ext/pg_query/include/postgres/storage/dsm_impl.h +79 -0
  329. data/ext/pg_query/include/postgres/storage/fd.h +219 -0
  330. data/ext/pg_query/include/postgres/storage/fileset.h +40 -0
  331. data/ext/pg_query/include/postgres/storage/ipc.h +87 -0
  332. data/ext/pg_query/include/postgres/storage/item.h +19 -0
  333. data/ext/pg_query/include/postgres/storage/itemid.h +184 -0
  334. data/ext/pg_query/include/postgres/storage/itemptr.h +245 -0
  335. data/ext/pg_query/include/postgres/storage/large_object.h +100 -0
  336. data/ext/pg_query/include/postgres/storage/latch.h +196 -0
  337. data/ext/pg_query/include/postgres/storage/lmgr.h +126 -0
  338. data/ext/pg_query/include/postgres/storage/lock.h +624 -0
  339. data/ext/pg_query/include/postgres/storage/lockdefs.h +61 -0
  340. data/ext/pg_query/include/postgres/storage/lwlock.h +228 -0
  341. data/ext/pg_query/include/postgres/storage/lwlocknames.h +47 -0
  342. data/ext/pg_query/include/postgres/storage/off.h +57 -0
  343. data/ext/pg_query/include/postgres/storage/pg_sema.h +61 -0
  344. data/ext/pg_query/include/postgres/storage/pg_shmem.h +93 -0
  345. data/ext/pg_query/include/postgres/storage/pmsignal.h +105 -0
  346. data/ext/pg_query/include/postgres/storage/predicate.h +83 -0
  347. data/ext/pg_query/include/postgres/storage/proc.h +488 -0
  348. data/ext/pg_query/include/postgres/storage/procarray.h +103 -0
  349. data/ext/pg_query/include/postgres/storage/proclist_types.h +53 -0
  350. data/ext/pg_query/include/postgres/storage/procnumber.h +43 -0
  351. data/ext/pg_query/include/postgres/storage/procsignal.h +75 -0
  352. data/ext/pg_query/include/postgres/storage/read_stream.h +65 -0
  353. data/ext/pg_query/include/postgres/storage/relfilelocator.h +100 -0
  354. data/ext/pg_query/include/postgres/storage/s_lock.h +847 -0
  355. data/ext/pg_query/include/postgres/storage/sharedfileset.h +37 -0
  356. data/ext/pg_query/include/postgres/storage/shm_mq.h +86 -0
  357. data/ext/pg_query/include/postgres/storage/shm_toc.h +58 -0
  358. data/ext/pg_query/include/postgres/storage/shmem.h +59 -0
  359. data/ext/pg_query/include/postgres/storage/sinval.h +153 -0
  360. data/ext/pg_query/include/postgres/storage/smgr.h +130 -0
  361. data/ext/pg_query/include/postgres/storage/spin.h +77 -0
  362. data/ext/pg_query/include/postgres/storage/standby.h +109 -0
  363. data/ext/pg_query/include/postgres/storage/standbydefs.h +74 -0
  364. data/ext/pg_query/include/postgres/storage/sync.h +66 -0
  365. data/ext/pg_query/include/postgres/tcop/cmdtag.h +62 -0
  366. data/ext/pg_query/include/postgres/tcop/cmdtaglist.h +219 -0
  367. data/ext/pg_query/include/postgres/tcop/deparse_utility.h +108 -0
  368. data/ext/pg_query/include/postgres/tcop/dest.h +148 -0
  369. data/ext/pg_query/include/postgres/tcop/fastpath.h +20 -0
  370. data/ext/pg_query/include/postgres/tcop/pquery.h +51 -0
  371. data/ext/pg_query/include/postgres/tcop/tcopprot.h +98 -0
  372. data/ext/pg_query/include/postgres/tcop/utility.h +112 -0
  373. data/ext/pg_query/include/postgres/tsearch/ts_cache.h +96 -0
  374. data/ext/pg_query/include/postgres/utils/acl.h +290 -0
  375. data/ext/pg_query/include/postgres/utils/aclchk_internal.h +45 -0
  376. data/ext/pg_query/include/postgres/utils/array.h +481 -0
  377. data/ext/pg_query/include/postgres/utils/ascii.h +84 -0
  378. data/ext/pg_query/include/postgres/utils/backend_progress.h +46 -0
  379. data/ext/pg_query/include/postgres/utils/backend_status.h +340 -0
  380. data/ext/pg_query/include/postgres/utils/builtins.h +139 -0
  381. data/ext/pg_query/include/postgres/utils/bytea.h +28 -0
  382. data/ext/pg_query/include/postgres/utils/catcache.h +231 -0
  383. data/ext/pg_query/include/postgres/utils/date.h +118 -0
  384. data/ext/pg_query/include/postgres/utils/datetime.h +367 -0
  385. data/ext/pg_query/include/postgres/utils/datum.h +76 -0
  386. data/ext/pg_query/include/postgres/utils/dsa.h +166 -0
  387. data/ext/pg_query/include/postgres/utils/elog.h +540 -0
  388. data/ext/pg_query/include/postgres/utils/errcodes.h +352 -0
  389. data/ext/pg_query/include/postgres/utils/expandeddatum.h +170 -0
  390. data/ext/pg_query/include/postgres/utils/expandedrecord.h +241 -0
  391. data/ext/pg_query/include/postgres/utils/float.h +357 -0
  392. data/ext/pg_query/include/postgres/utils/fmgroids.h +3347 -0
  393. data/ext/pg_query/include/postgres/utils/fmgrprotos.h +2904 -0
  394. data/ext/pg_query/include/postgres/utils/fmgrtab.h +49 -0
  395. data/ext/pg_query/include/postgres/utils/guc.h +456 -0
  396. data/ext/pg_query/include/postgres/utils/guc_hooks.h +184 -0
  397. data/ext/pg_query/include/postgres/utils/guc_tables.h +323 -0
  398. data/ext/pg_query/include/postgres/utils/hsearch.h +153 -0
  399. data/ext/pg_query/include/postgres/utils/injection_point.h +44 -0
  400. data/ext/pg_query/include/postgres/utils/inval.h +68 -0
  401. data/ext/pg_query/include/postgres/utils/logtape.h +77 -0
  402. data/ext/pg_query/include/postgres/utils/lsyscache.h +215 -0
  403. data/ext/pg_query/include/postgres/utils/memdebug.h +82 -0
  404. data/ext/pg_query/include/postgres/utils/memutils.h +193 -0
  405. data/ext/pg_query/include/postgres/utils/memutils_internal.h +176 -0
  406. data/ext/pg_query/include/postgres/utils/memutils_memorychunk.h +253 -0
  407. data/ext/pg_query/include/postgres/utils/numeric.h +110 -0
  408. data/ext/pg_query/include/postgres/utils/palloc.h +151 -0
  409. data/ext/pg_query/include/postgres/utils/partcache.h +103 -0
  410. data/ext/pg_query/include/postgres/utils/pg_locale.h +136 -0
  411. data/ext/pg_query/include/postgres/utils/pgstat_internal.h +827 -0
  412. data/ext/pg_query/include/postgres/utils/plancache.h +238 -0
  413. data/ext/pg_query/include/postgres/utils/portal.h +252 -0
  414. data/ext/pg_query/include/postgres/utils/probes.h +114 -0
  415. data/ext/pg_query/include/postgres/utils/ps_status.h +47 -0
  416. data/ext/pg_query/include/postgres/utils/queryenvironment.h +74 -0
  417. data/ext/pg_query/include/postgres/utils/regproc.h +39 -0
  418. data/ext/pg_query/include/postgres/utils/rel.h +711 -0
  419. data/ext/pg_query/include/postgres/utils/relcache.h +155 -0
  420. data/ext/pg_query/include/postgres/utils/reltrigger.h +81 -0
  421. data/ext/pg_query/include/postgres/utils/resowner.h +167 -0
  422. data/ext/pg_query/include/postgres/utils/ruleutils.h +52 -0
  423. data/ext/pg_query/include/postgres/utils/sharedtuplestore.h +61 -0
  424. data/ext/pg_query/include/postgres/utils/snapmgr.h +130 -0
  425. data/ext/pg_query/include/postgres/utils/snapshot.h +219 -0
  426. data/ext/pg_query/include/postgres/utils/sortsupport.h +391 -0
  427. data/ext/pg_query/include/postgres/utils/syscache.h +136 -0
  428. data/ext/pg_query/include/postgres/utils/timeout.h +96 -0
  429. data/ext/pg_query/include/postgres/utils/timestamp.h +147 -0
  430. data/ext/pg_query/include/postgres/utils/tuplesort.h +472 -0
  431. data/ext/pg_query/include/postgres/utils/tuplestore.h +88 -0
  432. data/ext/pg_query/include/postgres/utils/typcache.h +210 -0
  433. data/ext/pg_query/include/postgres/utils/varlena.h +53 -0
  434. data/ext/pg_query/include/postgres/utils/wait_event.h +108 -0
  435. data/ext/pg_query/include/postgres/utils/wait_event_types.h +218 -0
  436. data/ext/pg_query/include/postgres/utils/xml.h +94 -0
  437. data/ext/pg_query/include/postgres/varatt.h +358 -0
  438. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +8077 -6217
  439. data/ext/pg_query/include/protobuf/pg_query.pb.h +132024 -88124
  440. data/ext/pg_query/pg_query.c +10 -1
  441. data/ext/pg_query/pg_query.pb-c.c +24028 -17173
  442. data/ext/pg_query/pg_query_deparse.c +1 -9902
  443. data/ext/pg_query/pg_query_fingerprint.c +42 -18
  444. data/ext/pg_query/pg_query_fingerprint.h +1 -1
  445. data/ext/pg_query/pg_query_internal.h +1 -1
  446. data/ext/pg_query/pg_query_json_plpgsql.c +1 -25
  447. data/ext/pg_query/pg_query_normalize.c +44 -3
  448. data/ext/pg_query/pg_query_outfuncs_json.c +62 -16
  449. data/ext/pg_query/pg_query_outfuncs_protobuf.c +73 -12
  450. data/ext/pg_query/pg_query_parse.c +47 -5
  451. data/ext/pg_query/pg_query_parse_plpgsql.c +19 -18
  452. data/ext/pg_query/pg_query_readfuncs_protobuf.c +45 -10
  453. data/ext/pg_query/pg_query_ruby.c +5 -0
  454. data/ext/pg_query/pg_query_scan.c +4 -3
  455. data/ext/pg_query/pg_query_split.c +6 -5
  456. data/ext/pg_query/postgres_deparse.c +11496 -0
  457. data/ext/pg_query/postgres_deparse.h +9 -0
  458. data/ext/pg_query/src_backend_catalog_namespace.c +262 -71
  459. data/ext/pg_query/src_backend_catalog_pg_proc.c +3 -2
  460. data/ext/pg_query/src_backend_commands_define.c +12 -3
  461. data/ext/pg_query/src_backend_nodes_bitmapset.c +142 -156
  462. data/ext/pg_query/src_backend_nodes_copyfuncs.c +100 -5881
  463. data/ext/pg_query/src_backend_nodes_equalfuncs.c +102 -3831
  464. data/ext/pg_query/src_backend_nodes_extensible.c +6 -29
  465. data/ext/pg_query/src_backend_nodes_list.c +89 -18
  466. data/ext/pg_query/src_backend_nodes_makefuncs.c +138 -4
  467. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +433 -132
  468. data/ext/pg_query/src_backend_nodes_value.c +28 -19
  469. data/ext/pg_query/src_backend_parser_gram.c +45255 -38885
  470. data/ext/pg_query/src_backend_parser_parser.c +53 -8
  471. data/ext/pg_query/src_backend_parser_scan.c +6999 -3438
  472. data/ext/pg_query/src_backend_parser_scansup.c +5 -28
  473. data/ext/pg_query/src_backend_storage_ipc_ipc.c +13 -4
  474. data/ext/pg_query/src_backend_tcop_postgres.c +156 -114
  475. data/ext/pg_query/src_backend_utils_activity_pgstat_database.c +140 -0
  476. data/ext/pg_query/src_backend_utils_adt_datum.c +14 -2
  477. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +1 -1
  478. data/ext/pg_query/src_backend_utils_adt_format_type.c +6 -2
  479. data/ext/pg_query/src_backend_utils_adt_numutils.c +488 -0
  480. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +247 -34
  481. data/ext/pg_query/src_backend_utils_error_assert.c +17 -18
  482. data/ext/pg_query/src_backend_utils_error_elog.c +543 -343
  483. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +47 -18
  484. data/ext/pg_query/src_backend_utils_init_globals.c +22 -7
  485. data/ext/pg_query/src_backend_utils_mb_mbutils.c +84 -148
  486. data/ext/pg_query/src_backend_utils_misc_guc_tables.c +502 -0
  487. data/ext/pg_query/src_backend_utils_mmgr_alignedalloc.c +166 -0
  488. data/ext/pg_query/src_backend_utils_mmgr_aset.c +708 -499
  489. data/ext/pg_query/src_backend_utils_mmgr_bump.c +728 -0
  490. data/ext/pg_query/src_backend_utils_mmgr_generation.c +1115 -0
  491. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +710 -218
  492. data/ext/pg_query/src_backend_utils_mmgr_slab.c +1079 -0
  493. data/ext/pg_query/src_common_encnames.c +46 -44
  494. data/ext/pg_query/src_common_hashfn.c +3 -3
  495. data/ext/pg_query/src_common_keywords.c +15 -2
  496. data/ext/pg_query/src_common_kwlist_d.h +602 -510
  497. data/ext/pg_query/src_common_kwlookup.c +1 -1
  498. data/ext/pg_query/src_common_psprintf.c +3 -3
  499. data/ext/pg_query/src_common_stringinfo.c +21 -4
  500. data/ext/pg_query/src_common_wchar.c +754 -178
  501. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +143 -24
  502. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +3 -18
  503. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1295 -1255
  504. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +1 -1
  505. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +10 -10
  506. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +20 -2
  507. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +60 -60
  508. data/ext/pg_query/src_port_pg_bitutils.c +283 -54
  509. data/ext/pg_query/src_port_pgstrcasecmp.c +57 -1
  510. data/ext/pg_query/src_port_qsort.c +12 -224
  511. data/ext/pg_query/src_port_snprintf.c +56 -39
  512. data/ext/pg_query/src_port_strerror.c +9 -21
  513. data/ext/pg_query/src_port_strlcpy.c +79 -0
  514. data/lib/pg_query/filter_columns.rb +1 -1
  515. data/lib/pg_query/fingerprint.rb +10 -9
  516. data/lib/pg_query/node.rb +18 -13
  517. data/lib/pg_query/param_refs.rb +3 -3
  518. data/lib/pg_query/parse.rb +25 -15
  519. data/lib/pg_query/parse_error.rb +1 -0
  520. data/lib/pg_query/pg_query_pb.rb +181 -3038
  521. data/lib/pg_query/scan.rb +1 -0
  522. data/lib/pg_query/treewalker.rb +55 -8
  523. data/lib/pg_query/truncate.rb +19 -21
  524. data/lib/pg_query/version.rb +1 -1
  525. metadata +447 -436
  526. data/ext/pg_query/guc-file.c +0 -0
  527. data/ext/pg_query/include/access/amapi.h +0 -246
  528. data/ext/pg_query/include/access/attmap.h +0 -52
  529. data/ext/pg_query/include/access/attnum.h +0 -64
  530. data/ext/pg_query/include/access/clog.h +0 -61
  531. data/ext/pg_query/include/access/commit_ts.h +0 -77
  532. data/ext/pg_query/include/access/detoast.h +0 -92
  533. data/ext/pg_query/include/access/genam.h +0 -228
  534. data/ext/pg_query/include/access/gin.h +0 -78
  535. data/ext/pg_query/include/access/htup.h +0 -89
  536. data/ext/pg_query/include/access/htup_details.h +0 -819
  537. data/ext/pg_query/include/access/itup.h +0 -161
  538. data/ext/pg_query/include/access/parallel.h +0 -82
  539. data/ext/pg_query/include/access/printtup.h +0 -35
  540. data/ext/pg_query/include/access/relation.h +0 -28
  541. data/ext/pg_query/include/access/relscan.h +0 -176
  542. data/ext/pg_query/include/access/rmgr.h +0 -35
  543. data/ext/pg_query/include/access/rmgrlist.h +0 -49
  544. data/ext/pg_query/include/access/sdir.h +0 -58
  545. data/ext/pg_query/include/access/skey.h +0 -151
  546. data/ext/pg_query/include/access/stratnum.h +0 -83
  547. data/ext/pg_query/include/access/sysattr.h +0 -29
  548. data/ext/pg_query/include/access/table.h +0 -27
  549. data/ext/pg_query/include/access/tableam.h +0 -1825
  550. data/ext/pg_query/include/access/transam.h +0 -265
  551. data/ext/pg_query/include/access/tupconvert.h +0 -51
  552. data/ext/pg_query/include/access/tupdesc.h +0 -154
  553. data/ext/pg_query/include/access/tupmacs.h +0 -247
  554. data/ext/pg_query/include/access/twophase.h +0 -63
  555. data/ext/pg_query/include/access/xact.h +0 -469
  556. data/ext/pg_query/include/access/xlog.h +0 -398
  557. data/ext/pg_query/include/access/xlog_internal.h +0 -339
  558. data/ext/pg_query/include/access/xlogdefs.h +0 -109
  559. data/ext/pg_query/include/access/xloginsert.h +0 -64
  560. data/ext/pg_query/include/access/xlogreader.h +0 -337
  561. data/ext/pg_query/include/access/xlogrecord.h +0 -227
  562. data/ext/pg_query/include/bootstrap/bootstrap.h +0 -62
  563. data/ext/pg_query/include/c.h +0 -1334
  564. data/ext/pg_query/include/catalog/catalog.h +0 -42
  565. data/ext/pg_query/include/catalog/catversion.h +0 -58
  566. data/ext/pg_query/include/catalog/dependency.h +0 -277
  567. data/ext/pg_query/include/catalog/genbki.h +0 -64
  568. data/ext/pg_query/include/catalog/index.h +0 -199
  569. data/ext/pg_query/include/catalog/indexing.h +0 -366
  570. data/ext/pg_query/include/catalog/namespace.h +0 -188
  571. data/ext/pg_query/include/catalog/objectaccess.h +0 -197
  572. data/ext/pg_query/include/catalog/objectaddress.h +0 -84
  573. data/ext/pg_query/include/catalog/pg_aggregate.h +0 -176
  574. data/ext/pg_query/include/catalog/pg_aggregate_d.h +0 -77
  575. data/ext/pg_query/include/catalog/pg_am.h +0 -60
  576. data/ext/pg_query/include/catalog/pg_am_d.h +0 -45
  577. data/ext/pg_query/include/catalog/pg_attribute.h +0 -204
  578. data/ext/pg_query/include/catalog/pg_attribute_d.h +0 -59
  579. data/ext/pg_query/include/catalog/pg_authid.h +0 -58
  580. data/ext/pg_query/include/catalog/pg_authid_d.h +0 -49
  581. data/ext/pg_query/include/catalog/pg_class.h +0 -200
  582. data/ext/pg_query/include/catalog/pg_class_d.h +0 -103
  583. data/ext/pg_query/include/catalog/pg_collation.h +0 -73
  584. data/ext/pg_query/include/catalog/pg_collation_d.h +0 -45
  585. data/ext/pg_query/include/catalog/pg_constraint.h +0 -247
  586. data/ext/pg_query/include/catalog/pg_constraint_d.h +0 -67
  587. data/ext/pg_query/include/catalog/pg_control.h +0 -252
  588. data/ext/pg_query/include/catalog/pg_conversion.h +0 -72
  589. data/ext/pg_query/include/catalog/pg_conversion_d.h +0 -35
  590. data/ext/pg_query/include/catalog/pg_depend.h +0 -73
  591. data/ext/pg_query/include/catalog/pg_depend_d.h +0 -34
  592. data/ext/pg_query/include/catalog/pg_event_trigger.h +0 -51
  593. data/ext/pg_query/include/catalog/pg_event_trigger_d.h +0 -34
  594. data/ext/pg_query/include/catalog/pg_index.h +0 -80
  595. data/ext/pg_query/include/catalog/pg_index_d.h +0 -56
  596. data/ext/pg_query/include/catalog/pg_language.h +0 -67
  597. data/ext/pg_query/include/catalog/pg_language_d.h +0 -39
  598. data/ext/pg_query/include/catalog/pg_namespace.h +0 -59
  599. data/ext/pg_query/include/catalog/pg_namespace_d.h +0 -34
  600. data/ext/pg_query/include/catalog/pg_opclass.h +0 -85
  601. data/ext/pg_query/include/catalog/pg_opclass_d.h +0 -49
  602. data/ext/pg_query/include/catalog/pg_operator.h +0 -104
  603. data/ext/pg_query/include/catalog/pg_operator_d.h +0 -106
  604. data/ext/pg_query/include/catalog/pg_opfamily.h +0 -60
  605. data/ext/pg_query/include/catalog/pg_opfamily_d.h +0 -47
  606. data/ext/pg_query/include/catalog/pg_partitioned_table.h +0 -63
  607. data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +0 -35
  608. data/ext/pg_query/include/catalog/pg_proc.h +0 -211
  609. data/ext/pg_query/include/catalog/pg_proc_d.h +0 -99
  610. data/ext/pg_query/include/catalog/pg_publication.h +0 -118
  611. data/ext/pg_query/include/catalog/pg_publication_d.h +0 -36
  612. data/ext/pg_query/include/catalog/pg_replication_origin.h +0 -57
  613. data/ext/pg_query/include/catalog/pg_replication_origin_d.h +0 -29
  614. data/ext/pg_query/include/catalog/pg_statistic.h +0 -275
  615. data/ext/pg_query/include/catalog/pg_statistic_d.h +0 -194
  616. data/ext/pg_query/include/catalog/pg_statistic_ext.h +0 -74
  617. data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +0 -40
  618. data/ext/pg_query/include/catalog/pg_transform.h +0 -45
  619. data/ext/pg_query/include/catalog/pg_transform_d.h +0 -32
  620. data/ext/pg_query/include/catalog/pg_trigger.h +0 -137
  621. data/ext/pg_query/include/catalog/pg_trigger_d.h +0 -106
  622. data/ext/pg_query/include/catalog/pg_ts_config.h +0 -50
  623. data/ext/pg_query/include/catalog/pg_ts_config_d.h +0 -32
  624. data/ext/pg_query/include/catalog/pg_ts_dict.h +0 -54
  625. data/ext/pg_query/include/catalog/pg_ts_dict_d.h +0 -33
  626. data/ext/pg_query/include/catalog/pg_ts_parser.h +0 -57
  627. data/ext/pg_query/include/catalog/pg_ts_parser_d.h +0 -35
  628. data/ext/pg_query/include/catalog/pg_ts_template.h +0 -48
  629. data/ext/pg_query/include/catalog/pg_ts_template_d.h +0 -32
  630. data/ext/pg_query/include/catalog/pg_type.h +0 -373
  631. data/ext/pg_query/include/catalog/pg_type_d.h +0 -285
  632. data/ext/pg_query/include/catalog/storage.h +0 -48
  633. data/ext/pg_query/include/commands/async.h +0 -54
  634. data/ext/pg_query/include/commands/dbcommands.h +0 -35
  635. data/ext/pg_query/include/commands/defrem.h +0 -173
  636. data/ext/pg_query/include/commands/event_trigger.h +0 -88
  637. data/ext/pg_query/include/commands/explain.h +0 -127
  638. data/ext/pg_query/include/commands/prepare.h +0 -61
  639. data/ext/pg_query/include/commands/tablespace.h +0 -69
  640. data/ext/pg_query/include/commands/trigger.h +0 -285
  641. data/ext/pg_query/include/commands/user.h +0 -37
  642. data/ext/pg_query/include/commands/vacuum.h +0 -293
  643. data/ext/pg_query/include/commands/variable.h +0 -38
  644. data/ext/pg_query/include/common/file_perm.h +0 -56
  645. data/ext/pg_query/include/common/hashfn.h +0 -104
  646. data/ext/pg_query/include/common/ip.h +0 -37
  647. data/ext/pg_query/include/common/keywords.h +0 -33
  648. data/ext/pg_query/include/common/kwlookup.h +0 -44
  649. data/ext/pg_query/include/common/relpath.h +0 -90
  650. data/ext/pg_query/include/common/string.h +0 -19
  651. data/ext/pg_query/include/common/unicode_combining_table.h +0 -196
  652. data/ext/pg_query/include/datatype/timestamp.h +0 -197
  653. data/ext/pg_query/include/executor/execdesc.h +0 -70
  654. data/ext/pg_query/include/executor/executor.h +0 -620
  655. data/ext/pg_query/include/executor/functions.h +0 -41
  656. data/ext/pg_query/include/executor/instrument.h +0 -101
  657. data/ext/pg_query/include/executor/spi.h +0 -175
  658. data/ext/pg_query/include/executor/tablefunc.h +0 -67
  659. data/ext/pg_query/include/executor/tuptable.h +0 -487
  660. data/ext/pg_query/include/fmgr.h +0 -775
  661. data/ext/pg_query/include/funcapi.h +0 -348
  662. data/ext/pg_query/include/getaddrinfo.h +0 -162
  663. data/ext/pg_query/include/jit/jit.h +0 -105
  664. data/ext/pg_query/include/kwlist_d.h +0 -1072
  665. data/ext/pg_query/include/lib/ilist.h +0 -727
  666. data/ext/pg_query/include/lib/pairingheap.h +0 -102
  667. data/ext/pg_query/include/lib/simplehash.h +0 -1059
  668. data/ext/pg_query/include/lib/stringinfo.h +0 -161
  669. data/ext/pg_query/include/libpq/auth.h +0 -29
  670. data/ext/pg_query/include/libpq/crypt.h +0 -46
  671. data/ext/pg_query/include/libpq/hba.h +0 -140
  672. data/ext/pg_query/include/libpq/libpq-be.h +0 -326
  673. data/ext/pg_query/include/libpq/libpq.h +0 -134
  674. data/ext/pg_query/include/libpq/pqcomm.h +0 -208
  675. data/ext/pg_query/include/libpq/pqformat.h +0 -210
  676. data/ext/pg_query/include/libpq/pqsignal.h +0 -42
  677. data/ext/pg_query/include/mb/pg_wchar.h +0 -673
  678. data/ext/pg_query/include/mb/stringinfo_mb.h +0 -24
  679. data/ext/pg_query/include/miscadmin.h +0 -489
  680. data/ext/pg_query/include/nodes/bitmapset.h +0 -122
  681. data/ext/pg_query/include/nodes/execnodes.h +0 -2523
  682. data/ext/pg_query/include/nodes/extensible.h +0 -160
  683. data/ext/pg_query/include/nodes/lockoptions.h +0 -61
  684. data/ext/pg_query/include/nodes/makefuncs.h +0 -108
  685. data/ext/pg_query/include/nodes/memnodes.h +0 -108
  686. data/ext/pg_query/include/nodes/nodeFuncs.h +0 -162
  687. data/ext/pg_query/include/nodes/nodes.h +0 -842
  688. data/ext/pg_query/include/nodes/params.h +0 -170
  689. data/ext/pg_query/include/nodes/parsenodes.h +0 -3580
  690. data/ext/pg_query/include/nodes/pathnodes.h +0 -2557
  691. data/ext/pg_query/include/nodes/pg_list.h +0 -606
  692. data/ext/pg_query/include/nodes/plannodes.h +0 -1266
  693. data/ext/pg_query/include/nodes/primnodes.h +0 -1541
  694. data/ext/pg_query/include/nodes/print.h +0 -34
  695. data/ext/pg_query/include/nodes/tidbitmap.h +0 -75
  696. data/ext/pg_query/include/nodes/value.h +0 -61
  697. data/ext/pg_query/include/optimizer/cost.h +0 -206
  698. data/ext/pg_query/include/optimizer/geqo.h +0 -88
  699. data/ext/pg_query/include/optimizer/geqo_gene.h +0 -45
  700. data/ext/pg_query/include/optimizer/optimizer.h +0 -194
  701. data/ext/pg_query/include/optimizer/paths.h +0 -257
  702. data/ext/pg_query/include/optimizer/planmain.h +0 -119
  703. data/ext/pg_query/include/parser/analyze.h +0 -49
  704. data/ext/pg_query/include/parser/gram.h +0 -1067
  705. data/ext/pg_query/include/parser/gramparse.h +0 -75
  706. data/ext/pg_query/include/parser/kwlist.h +0 -477
  707. data/ext/pg_query/include/parser/parse_agg.h +0 -68
  708. data/ext/pg_query/include/parser/parse_clause.h +0 -54
  709. data/ext/pg_query/include/parser/parse_coerce.h +0 -98
  710. data/ext/pg_query/include/parser/parse_collate.h +0 -27
  711. data/ext/pg_query/include/parser/parse_expr.h +0 -26
  712. data/ext/pg_query/include/parser/parse_func.h +0 -73
  713. data/ext/pg_query/include/parser/parse_node.h +0 -327
  714. data/ext/pg_query/include/parser/parse_oper.h +0 -67
  715. data/ext/pg_query/include/parser/parse_relation.h +0 -123
  716. data/ext/pg_query/include/parser/parse_target.h +0 -46
  717. data/ext/pg_query/include/parser/parse_type.h +0 -60
  718. data/ext/pg_query/include/parser/parser.h +0 -41
  719. data/ext/pg_query/include/parser/parsetree.h +0 -61
  720. data/ext/pg_query/include/parser/scanner.h +0 -152
  721. data/ext/pg_query/include/parser/scansup.h +0 -30
  722. data/ext/pg_query/include/partitioning/partdefs.h +0 -26
  723. data/ext/pg_query/include/pg_config.h +0 -995
  724. data/ext/pg_query/include/pg_config_manual.h +0 -357
  725. data/ext/pg_query/include/pg_config_os.h +0 -8
  726. data/ext/pg_query/include/pg_getopt.h +0 -56
  727. data/ext/pg_query/include/pg_trace.h +0 -17
  728. data/ext/pg_query/include/pgstat.h +0 -1488
  729. data/ext/pg_query/include/pgtime.h +0 -84
  730. data/ext/pg_query/include/pl_gram.h +0 -385
  731. data/ext/pg_query/include/pl_reserved_kwlist.h +0 -52
  732. data/ext/pg_query/include/pl_reserved_kwlist_d.h +0 -114
  733. data/ext/pg_query/include/pl_unreserved_kwlist.h +0 -112
  734. data/ext/pg_query/include/pl_unreserved_kwlist_d.h +0 -246
  735. data/ext/pg_query/include/plerrcodes.h +0 -990
  736. data/ext/pg_query/include/plpgsql.h +0 -1347
  737. data/ext/pg_query/include/port/atomics/arch-arm.h +0 -26
  738. data/ext/pg_query/include/port/atomics/arch-ppc.h +0 -254
  739. data/ext/pg_query/include/port/atomics/arch-x86.h +0 -252
  740. data/ext/pg_query/include/port/atomics/fallback.h +0 -170
  741. data/ext/pg_query/include/port/atomics/generic-gcc.h +0 -286
  742. data/ext/pg_query/include/port/atomics/generic.h +0 -401
  743. data/ext/pg_query/include/port/atomics.h +0 -524
  744. data/ext/pg_query/include/port/pg_bitutils.h +0 -272
  745. data/ext/pg_query/include/port/pg_bswap.h +0 -161
  746. data/ext/pg_query/include/port/pg_crc32c.h +0 -101
  747. data/ext/pg_query/include/port.h +0 -528
  748. data/ext/pg_query/include/portability/instr_time.h +0 -256
  749. data/ext/pg_query/include/postgres.h +0 -764
  750. data/ext/pg_query/include/postgres_ext.h +0 -74
  751. data/ext/pg_query/include/postmaster/autovacuum.h +0 -83
  752. data/ext/pg_query/include/postmaster/bgworker.h +0 -161
  753. data/ext/pg_query/include/postmaster/bgworker_internals.h +0 -64
  754. data/ext/pg_query/include/postmaster/bgwriter.h +0 -45
  755. data/ext/pg_query/include/postmaster/fork_process.h +0 -17
  756. data/ext/pg_query/include/postmaster/interrupt.h +0 -32
  757. data/ext/pg_query/include/postmaster/pgarch.h +0 -39
  758. data/ext/pg_query/include/postmaster/postmaster.h +0 -77
  759. data/ext/pg_query/include/postmaster/syslogger.h +0 -98
  760. data/ext/pg_query/include/postmaster/walwriter.h +0 -21
  761. data/ext/pg_query/include/regex/regex.h +0 -184
  762. data/ext/pg_query/include/replication/logicallauncher.h +0 -31
  763. data/ext/pg_query/include/replication/logicalproto.h +0 -110
  764. data/ext/pg_query/include/replication/logicalworker.h +0 -19
  765. data/ext/pg_query/include/replication/origin.h +0 -73
  766. data/ext/pg_query/include/replication/reorderbuffer.h +0 -468
  767. data/ext/pg_query/include/replication/slot.h +0 -219
  768. data/ext/pg_query/include/replication/syncrep.h +0 -115
  769. data/ext/pg_query/include/replication/walreceiver.h +0 -340
  770. data/ext/pg_query/include/replication/walsender.h +0 -74
  771. data/ext/pg_query/include/rewrite/prs2lock.h +0 -46
  772. data/ext/pg_query/include/rewrite/rewriteHandler.h +0 -40
  773. data/ext/pg_query/include/rewrite/rewriteManip.h +0 -87
  774. data/ext/pg_query/include/rewrite/rewriteSupport.h +0 -26
  775. data/ext/pg_query/include/storage/backendid.h +0 -37
  776. data/ext/pg_query/include/storage/block.h +0 -121
  777. data/ext/pg_query/include/storage/buf.h +0 -46
  778. data/ext/pg_query/include/storage/bufmgr.h +0 -292
  779. data/ext/pg_query/include/storage/bufpage.h +0 -459
  780. data/ext/pg_query/include/storage/condition_variable.h +0 -62
  781. data/ext/pg_query/include/storage/dsm.h +0 -61
  782. data/ext/pg_query/include/storage/dsm_impl.h +0 -75
  783. data/ext/pg_query/include/storage/fd.h +0 -168
  784. data/ext/pg_query/include/storage/ipc.h +0 -81
  785. data/ext/pg_query/include/storage/item.h +0 -19
  786. data/ext/pg_query/include/storage/itemid.h +0 -184
  787. data/ext/pg_query/include/storage/itemptr.h +0 -206
  788. data/ext/pg_query/include/storage/large_object.h +0 -100
  789. data/ext/pg_query/include/storage/latch.h +0 -190
  790. data/ext/pg_query/include/storage/lmgr.h +0 -114
  791. data/ext/pg_query/include/storage/lock.h +0 -613
  792. data/ext/pg_query/include/storage/lockdefs.h +0 -59
  793. data/ext/pg_query/include/storage/lwlock.h +0 -233
  794. data/ext/pg_query/include/storage/lwlocknames.h +0 -51
  795. data/ext/pg_query/include/storage/off.h +0 -57
  796. data/ext/pg_query/include/storage/pg_sema.h +0 -61
  797. data/ext/pg_query/include/storage/pg_shmem.h +0 -90
  798. data/ext/pg_query/include/storage/pmsignal.h +0 -94
  799. data/ext/pg_query/include/storage/predicate.h +0 -87
  800. data/ext/pg_query/include/storage/proc.h +0 -347
  801. data/ext/pg_query/include/storage/proclist_types.h +0 -51
  802. data/ext/pg_query/include/storage/procsignal.h +0 -75
  803. data/ext/pg_query/include/storage/relfilenode.h +0 -99
  804. data/ext/pg_query/include/storage/s_lock.h +0 -1071
  805. data/ext/pg_query/include/storage/sharedfileset.h +0 -45
  806. data/ext/pg_query/include/storage/shm_mq.h +0 -85
  807. data/ext/pg_query/include/storage/shm_toc.h +0 -58
  808. data/ext/pg_query/include/storage/shmem.h +0 -81
  809. data/ext/pg_query/include/storage/sinval.h +0 -153
  810. data/ext/pg_query/include/storage/sinvaladt.h +0 -43
  811. data/ext/pg_query/include/storage/smgr.h +0 -109
  812. data/ext/pg_query/include/storage/spin.h +0 -77
  813. data/ext/pg_query/include/storage/standby.h +0 -91
  814. data/ext/pg_query/include/storage/standbydefs.h +0 -74
  815. data/ext/pg_query/include/storage/sync.h +0 -62
  816. data/ext/pg_query/include/tcop/cmdtag.h +0 -58
  817. data/ext/pg_query/include/tcop/cmdtaglist.h +0 -217
  818. data/ext/pg_query/include/tcop/deparse_utility.h +0 -108
  819. data/ext/pg_query/include/tcop/dest.h +0 -149
  820. data/ext/pg_query/include/tcop/fastpath.h +0 -21
  821. data/ext/pg_query/include/tcop/pquery.h +0 -51
  822. data/ext/pg_query/include/tcop/tcopprot.h +0 -89
  823. data/ext/pg_query/include/tcop/utility.h +0 -108
  824. data/ext/pg_query/include/tsearch/ts_cache.h +0 -98
  825. data/ext/pg_query/include/utils/acl.h +0 -312
  826. data/ext/pg_query/include/utils/aclchk_internal.h +0 -45
  827. data/ext/pg_query/include/utils/array.h +0 -459
  828. data/ext/pg_query/include/utils/builtins.h +0 -128
  829. data/ext/pg_query/include/utils/bytea.h +0 -27
  830. data/ext/pg_query/include/utils/catcache.h +0 -231
  831. data/ext/pg_query/include/utils/date.h +0 -90
  832. data/ext/pg_query/include/utils/datetime.h +0 -343
  833. data/ext/pg_query/include/utils/datum.h +0 -68
  834. data/ext/pg_query/include/utils/dsa.h +0 -123
  835. data/ext/pg_query/include/utils/dynahash.h +0 -19
  836. data/ext/pg_query/include/utils/elog.h +0 -439
  837. data/ext/pg_query/include/utils/errcodes.h +0 -352
  838. data/ext/pg_query/include/utils/expandeddatum.h +0 -159
  839. data/ext/pg_query/include/utils/expandedrecord.h +0 -231
  840. data/ext/pg_query/include/utils/float.h +0 -356
  841. data/ext/pg_query/include/utils/fmgroids.h +0 -2657
  842. data/ext/pg_query/include/utils/fmgrprotos.h +0 -2646
  843. data/ext/pg_query/include/utils/fmgrtab.h +0 -48
  844. data/ext/pg_query/include/utils/guc.h +0 -443
  845. data/ext/pg_query/include/utils/guc_tables.h +0 -272
  846. data/ext/pg_query/include/utils/hsearch.h +0 -149
  847. data/ext/pg_query/include/utils/inval.h +0 -65
  848. data/ext/pg_query/include/utils/lsyscache.h +0 -198
  849. data/ext/pg_query/include/utils/memdebug.h +0 -82
  850. data/ext/pg_query/include/utils/memutils.h +0 -225
  851. data/ext/pg_query/include/utils/numeric.h +0 -76
  852. data/ext/pg_query/include/utils/palloc.h +0 -136
  853. data/ext/pg_query/include/utils/partcache.h +0 -102
  854. data/ext/pg_query/include/utils/pg_locale.h +0 -119
  855. data/ext/pg_query/include/utils/pg_lsn.h +0 -29
  856. data/ext/pg_query/include/utils/pidfile.h +0 -56
  857. data/ext/pg_query/include/utils/plancache.h +0 -235
  858. data/ext/pg_query/include/utils/portal.h +0 -254
  859. data/ext/pg_query/include/utils/probes.h +0 -114
  860. data/ext/pg_query/include/utils/ps_status.h +0 -25
  861. data/ext/pg_query/include/utils/queryenvironment.h +0 -74
  862. data/ext/pg_query/include/utils/regproc.h +0 -28
  863. data/ext/pg_query/include/utils/rel.h +0 -643
  864. data/ext/pg_query/include/utils/relcache.h +0 -150
  865. data/ext/pg_query/include/utils/reltrigger.h +0 -81
  866. data/ext/pg_query/include/utils/resowner.h +0 -86
  867. data/ext/pg_query/include/utils/rls.h +0 -50
  868. data/ext/pg_query/include/utils/ruleutils.h +0 -44
  869. data/ext/pg_query/include/utils/sharedtuplestore.h +0 -61
  870. data/ext/pg_query/include/utils/snapmgr.h +0 -159
  871. data/ext/pg_query/include/utils/snapshot.h +0 -206
  872. data/ext/pg_query/include/utils/sortsupport.h +0 -276
  873. data/ext/pg_query/include/utils/syscache.h +0 -219
  874. data/ext/pg_query/include/utils/timeout.h +0 -88
  875. data/ext/pg_query/include/utils/timestamp.h +0 -116
  876. data/ext/pg_query/include/utils/tuplesort.h +0 -277
  877. data/ext/pg_query/include/utils/tuplestore.h +0 -91
  878. data/ext/pg_query/include/utils/typcache.h +0 -202
  879. data/ext/pg_query/include/utils/tzparser.h +0 -39
  880. data/ext/pg_query/include/utils/varlena.h +0 -39
  881. data/ext/pg_query/include/utils/xml.h +0 -84
  882. data/ext/pg_query/pg_query_ruby_freebsd.sym +0 -2
  883. data/ext/pg_query/src_backend_libpq_pqcomm.c +0 -659
  884. data/ext/pg_query/src_backend_parser_parse_expr.c +0 -313
  885. data/ext/pg_query/src_backend_postmaster_postmaster.c +0 -2230
  886. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +0 -370
  887. data/ext/pg_query/src_backend_utils_hash_dynahash.c +0 -1086
  888. data/ext/pg_query/src_backend_utils_misc_guc.c +0 -1832
  889. data/ext/pg_query/src_common_string.c +0 -86
  890. data/ext/pg_query/src_port_erand48.c +0 -127
  891. data/ext/pg_query/src_port_pgsleep.c +0 -69
  892. data/ext/pg_query/src_port_random.c +0 -31
  893. data/ext/pg_query/src_port_strnlen.c +0 -39
  894. /data/ext/pg_query/{pg_query_ruby.sym → ext_symbols.sym} +0 -0
  895. /data/ext/pg_query/include/{pg_config_ext.h → postgres/pg_config_ext.h} +0 -0
@@ -1,18 +1,21 @@
1
1
  /*--------------------------------------------------------------------
2
2
  * Symbols referenced in this file:
3
- * - AllocSetContextCreateInternal
4
- * - context_freelists
5
- * - AllocSetMethods
6
3
  * - AllocSetAlloc
4
+ * - AllocSetAllocLarge
7
5
  * - AllocSetFreeIndex
6
+ * - AllocSetAllocFromNewBlock
7
+ * - AllocSetAllocChunkFromBlock
8
8
  * - AllocSetFree
9
9
  * - AllocSetRealloc
10
10
  * - AllocSetReset
11
11
  * - AllocSetDelete
12
+ * - context_freelists
13
+ * - AllocSetGetChunkContext
12
14
  * - AllocSetGetChunkSpace
13
15
  * - AllocSetIsEmpty
14
16
  * - AllocSetStats
15
17
  * - AllocSetCheck
18
+ * - AllocSetContextCreateInternal
16
19
  * - AllocSetDeleteFreeList
17
20
  *--------------------------------------------------------------------
18
21
  */
@@ -26,7 +29,7 @@
26
29
  * type.
27
30
  *
28
31
  *
29
- * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
32
+ * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
30
33
  * Portions Copyright (c) 1994, Regents of the University of California
31
34
  *
32
35
  * IDENTIFICATION
@@ -68,6 +71,8 @@
68
71
  #include "port/pg_bitutils.h"
69
72
  #include "utils/memdebug.h"
70
73
  #include "utils/memutils.h"
74
+ #include "utils/memutils_internal.h"
75
+ #include "utils/memutils_memorychunk.h"
71
76
 
72
77
  /*--------------------
73
78
  * Chunk freelist k holds chunks of size 1 << (k + ALLOC_MINBITS),
@@ -85,7 +90,9 @@
85
90
  * CAUTION: ALLOC_MINBITS must be large enough so that
86
91
  * 1<<ALLOC_MINBITS is at least MAXALIGN,
87
92
  * or we may fail to align the smallest chunks adequately.
88
- * 8-byte alignment is enough on all currently known machines.
93
+ * 8-byte alignment is enough on all currently known machines. This 8-byte
94
+ * minimum also allows us to store a pointer to the next freelist item within
95
+ * the chunk of memory itself.
89
96
  *
90
97
  * With the current parameters, request sizes up to 8K are treated as chunks,
91
98
  * larger requests go into dedicated blocks. Change ALLOCSET_NUM_FREELISTS
@@ -117,10 +124,9 @@
117
124
  */
118
125
 
119
126
  #define ALLOC_BLOCKHDRSZ MAXALIGN(sizeof(AllocBlockData))
120
- #define ALLOC_CHUNKHDRSZ sizeof(struct AllocChunkData)
127
+ #define ALLOC_CHUNKHDRSZ sizeof(MemoryChunk)
121
128
 
122
129
  typedef struct AllocBlockData *AllocBlock; /* forward reference */
123
- typedef struct AllocChunkData *AllocChunk;
124
130
 
125
131
  /*
126
132
  * AllocPointer
@@ -128,6 +134,34 @@ typedef struct AllocChunkData *AllocChunk;
128
134
  */
129
135
  typedef void *AllocPointer;
130
136
 
137
+ /*
138
+ * AllocFreeListLink
139
+ * When pfreeing memory, if we maintain a freelist for the given chunk's
140
+ * size then we use a AllocFreeListLink to point to the current item in
141
+ * the AllocSetContext's freelist and then set the given freelist element
142
+ * to point to the chunk being freed.
143
+ */
144
+ typedef struct AllocFreeListLink
145
+ {
146
+ MemoryChunk *next;
147
+ } AllocFreeListLink;
148
+
149
+ /*
150
+ * Obtain a AllocFreeListLink for the given chunk. Allocation sizes are
151
+ * always at least sizeof(AllocFreeListLink), so we reuse the pointer's memory
152
+ * itself to store the freelist link.
153
+ */
154
+ #define GetFreeListLink(chkptr) \
155
+ (AllocFreeListLink *) ((char *) (chkptr) + ALLOC_CHUNKHDRSZ)
156
+
157
+ /* Validate a freelist index retrieved from a chunk header */
158
+ #define FreeListIdxIsValid(fidx) \
159
+ ((fidx) >= 0 && (fidx) < ALLOCSET_NUM_FREELISTS)
160
+
161
+ /* Determine the size of the chunk based on the freelist index */
162
+ #define GetChunkSizeFromFreeListIdx(fidx) \
163
+ ((((Size) 1) << ALLOC_MINBITS) << (fidx))
164
+
131
165
  /*
132
166
  * AllocSetContext is our standard implementation of MemoryContext.
133
167
  *
@@ -142,13 +176,12 @@ typedef struct AllocSetContext
142
176
  MemoryContextData header; /* Standard memory-context fields */
143
177
  /* Info about storage allocated in this context: */
144
178
  AllocBlock blocks; /* head of list of blocks in this set */
145
- AllocChunk freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */
179
+ MemoryChunk *freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */
146
180
  /* Allocation parameters for this context: */
147
- Size initBlockSize; /* initial block size */
148
- Size maxBlockSize; /* maximum block size */
149
- Size nextBlockSize; /* next block size to allocate */
150
- Size allocChunkLimit; /* effective chunk size limit */
151
- AllocBlock keeper; /* keep this block over resets */
181
+ uint32 initBlockSize; /* initial block size */
182
+ uint32 maxBlockSize; /* maximum block size */
183
+ uint32 nextBlockSize; /* next block size to allocate */
184
+ uint32 allocChunkLimit; /* effective chunk size limit */
152
185
  /* freelist this context could be put in, or -1 if not a candidate: */
153
186
  int freeListIndex; /* index in context_freelists[], or -1 */
154
187
  } AllocSetContext;
@@ -158,8 +191,8 @@ typedef AllocSetContext *AllocSet;
158
191
  /*
159
192
  * AllocBlock
160
193
  * An AllocBlock is the unit of memory that is obtained by aset.c
161
- * from malloc(). It contains one or more AllocChunks, which are
162
- * the units requested by palloc() and freed by pfree(). AllocChunks
194
+ * from malloc(). It contains one or more MemoryChunks, which are
195
+ * the units requested by palloc() and freed by pfree(). MemoryChunks
163
196
  * cannot be returned to malloc() individually, instead they are put
164
197
  * on freelists by pfree() and re-used by the next palloc() that has
165
198
  * a matching request size.
@@ -176,50 +209,6 @@ typedef struct AllocBlockData
176
209
  char *endptr; /* end of space in this block */
177
210
  } AllocBlockData;
178
211
 
179
- /*
180
- * AllocChunk
181
- * The prefix of each piece of memory in an AllocBlock
182
- *
183
- * Note: to meet the memory context APIs, the payload area of the chunk must
184
- * be maxaligned, and the "aset" link must be immediately adjacent to the
185
- * payload area (cf. GetMemoryChunkContext). We simplify matters for this
186
- * module by requiring sizeof(AllocChunkData) to be maxaligned, and then
187
- * we can ensure things work by adding any required alignment padding before
188
- * the "aset" field. There is a static assertion below that the alignment
189
- * is done correctly.
190
- */
191
- typedef struct AllocChunkData
192
- {
193
- /* size is always the size of the usable space in the chunk */
194
- Size size;
195
- #ifdef MEMORY_CONTEXT_CHECKING
196
- /* when debugging memory usage, also store actual requested size */
197
- /* this is zero in a free chunk */
198
- Size requested_size;
199
-
200
- #define ALLOCCHUNK_RAWSIZE (SIZEOF_SIZE_T * 2 + SIZEOF_VOID_P)
201
- #else
202
- #define ALLOCCHUNK_RAWSIZE (SIZEOF_SIZE_T + SIZEOF_VOID_P)
203
- #endif /* MEMORY_CONTEXT_CHECKING */
204
-
205
- /* ensure proper alignment by adding padding if needed */
206
- #if (ALLOCCHUNK_RAWSIZE % MAXIMUM_ALIGNOF) != 0
207
- char padding[MAXIMUM_ALIGNOF - ALLOCCHUNK_RAWSIZE % MAXIMUM_ALIGNOF];
208
- #endif
209
-
210
- /* aset is the owning aset if allocated, or the freelist link if free */
211
- void *aset;
212
- /* there must not be any padding to reach a MAXALIGN boundary here! */
213
- } AllocChunkData;
214
-
215
- /*
216
- * Only the "aset" field should be accessed outside this module.
217
- * We keep the rest of an allocated chunk's header marked NOACCESS when using
218
- * valgrind. But note that chunk headers that are in a freelist are kept
219
- * accessible, for simplicity.
220
- */
221
- #define ALLOCCHUNK_PRIVATE_LEN offsetof(AllocChunkData, aset)
222
-
223
212
  /*
224
213
  * AllocPointerIsValid
225
214
  * True iff pointer is valid allocation pointer.
@@ -230,12 +219,23 @@ typedef struct AllocChunkData
230
219
  * AllocSetIsValid
231
220
  * True iff set is valid allocation set.
232
221
  */
233
- #define AllocSetIsValid(set) PointerIsValid(set)
222
+ #define AllocSetIsValid(set) \
223
+ (PointerIsValid(set) && IsA(set, AllocSetContext))
234
224
 
235
- #define AllocPointerGetChunk(ptr) \
236
- ((AllocChunk)(((char *)(ptr)) - ALLOC_CHUNKHDRSZ))
237
- #define AllocChunkGetPointer(chk) \
238
- ((AllocPointer)(((char *)(chk)) + ALLOC_CHUNKHDRSZ))
225
+ /*
226
+ * AllocBlockIsValid
227
+ * True iff block is valid block of allocation set.
228
+ */
229
+ #define AllocBlockIsValid(block) \
230
+ (PointerIsValid(block) && AllocSetIsValid((block)->aset))
231
+
232
+ /*
233
+ * We always store external chunks on a dedicated block. This makes fetching
234
+ * the block from an external chunk easy since it's always the first and only
235
+ * chunk on the block.
236
+ */
237
+ #define ExternalChunkGetBlock(chunk) \
238
+ (AllocBlock) ((char *) chunk - ALLOC_BLOCKHDRSZ)
239
239
 
240
240
  /*
241
241
  * Rather than repeatedly creating and deleting memory contexts, we keep some
@@ -262,6 +262,13 @@ typedef struct AllocChunkData
262
262
  */
263
263
  #define MAX_FREE_CONTEXTS 100 /* arbitrary limit on freelist length */
264
264
 
265
+ /* Obtain the keeper block for an allocation set */
266
+ #define KeeperBlock(set) \
267
+ ((AllocBlock) (((char *) set) + MAXALIGN(sizeof(AllocSetContext))))
268
+
269
+ /* Check if the block is the keeper block of the given allocation set */
270
+ #define IsKeeperBlock(set, block) ((block) == (KeeperBlock(set)))
271
+
265
272
  typedef struct AllocSetFreeList
266
273
  {
267
274
  int num_free; /* current list length */
@@ -280,41 +287,6 @@ static __thread AllocSetFreeList context_freelists[2] =
280
287
  };
281
288
 
282
289
 
283
- /*
284
- * These functions implement the MemoryContext API for AllocSet contexts.
285
- */
286
- static void *AllocSetAlloc(MemoryContext context, Size size);
287
- static void AllocSetFree(MemoryContext context, void *pointer);
288
- static void *AllocSetRealloc(MemoryContext context, void *pointer, Size size);
289
- static void AllocSetReset(MemoryContext context);
290
- static void AllocSetDelete(MemoryContext context);
291
- static Size AllocSetGetChunkSpace(MemoryContext context, void *pointer);
292
- static bool AllocSetIsEmpty(MemoryContext context);
293
- static void AllocSetStats(MemoryContext context,
294
- MemoryStatsPrintFunc printfunc, void *passthru,
295
- MemoryContextCounters *totals);
296
-
297
- #ifdef MEMORY_CONTEXT_CHECKING
298
- static void AllocSetCheck(MemoryContext context);
299
- #endif
300
-
301
- /*
302
- * This is the virtual function table for AllocSet contexts.
303
- */
304
- static const MemoryContextMethods AllocSetMethods = {
305
- AllocSetAlloc,
306
- AllocSetFree,
307
- AllocSetRealloc,
308
- AllocSetReset,
309
- AllocSetDelete,
310
- AllocSetGetChunkSpace,
311
- AllocSetIsEmpty,
312
- AllocSetStats
313
- #ifdef MEMORY_CONTEXT_CHECKING
314
- ,AllocSetCheck
315
- #endif
316
- };
317
-
318
290
 
319
291
  /* ----------
320
292
  * AllocSetFreeIndex -
@@ -338,7 +310,7 @@ AllocSetFreeIndex(Size size)
338
310
  * or equivalently
339
311
  * pg_leftmost_one_pos32(size - 1) - ALLOC_MINBITS + 1
340
312
  *
341
- * However, rather than just calling that function, we duplicate the
313
+ * However, for platforms without intrinsic support, we duplicate the
342
314
  * logic here, allowing an additional optimization. It's reasonable
343
315
  * to assume that ALLOC_CHUNK_LIMIT fits in 16 bits, so we can unroll
344
316
  * the byte-at-a-time loop in pg_leftmost_one_pos32 and just handle
@@ -348,14 +320,14 @@ AllocSetFreeIndex(Size size)
348
320
  * much trouble.
349
321
  *----------
350
322
  */
351
- #ifdef HAVE__BUILTIN_CLZ
352
- idx = 31 - __builtin_clz((uint32) size - 1) - ALLOC_MINBITS + 1;
323
+ #ifdef HAVE_BITSCAN_REVERSE
324
+ idx = pg_leftmost_one_pos32((uint32) size - 1) - ALLOC_MINBITS + 1;
353
325
  #else
354
326
  uint32 t,
355
327
  tsize;
356
328
 
357
329
  /* Statically assert that we only have a 16-bit input value. */
358
- StaticAssertStmt(ALLOC_CHUNK_LIMIT < (1 << 16),
330
+ StaticAssertDecl(ALLOC_CHUNK_LIMIT < (1 << 16),
359
331
  "ALLOC_CHUNK_LIMIT must be less than 64kB");
360
332
 
361
333
  tsize = size - 1;
@@ -406,18 +378,24 @@ AllocSetContextCreateInternal(MemoryContext parent,
406
378
  AllocSet set;
407
379
  AllocBlock block;
408
380
 
409
- /* Assert we padded AllocChunkData properly */
410
- StaticAssertStmt(ALLOC_CHUNKHDRSZ == MAXALIGN(ALLOC_CHUNKHDRSZ),
411
- "sizeof(AllocChunkData) is not maxaligned");
412
- StaticAssertStmt(offsetof(AllocChunkData, aset) + sizeof(MemoryContext) ==
413
- ALLOC_CHUNKHDRSZ,
414
- "padding calculation in AllocChunkData is wrong");
381
+ /* ensure MemoryChunk's size is properly maxaligned */
382
+ StaticAssertDecl(ALLOC_CHUNKHDRSZ == MAXALIGN(ALLOC_CHUNKHDRSZ),
383
+ "sizeof(MemoryChunk) is not maxaligned");
384
+ /* check we have enough space to store the freelist link */
385
+ StaticAssertDecl(sizeof(AllocFreeListLink) <= (1 << ALLOC_MINBITS),
386
+ "sizeof(AllocFreeListLink) larger than minimum allocation size");
415
387
 
416
388
  /*
417
389
  * First, validate allocation parameters. Once these were regular runtime
418
- * test and elog's, but in practice Asserts seem sufficient because nobody
419
- * varies their parameters at runtime. We somewhat arbitrarily enforce a
420
- * minimum 1K block size.
390
+ * tests and elog's, but in practice Asserts seem sufficient because
391
+ * nobody varies their parameters at runtime. We somewhat arbitrarily
392
+ * enforce a minimum 1K block size. We restrict the maximum block size to
393
+ * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
394
+ * regards to addressing the offset between the chunk and the block that
395
+ * the chunk is stored on. We would be unable to store the offset between
396
+ * the chunk and block for any chunks that were beyond
397
+ * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
398
+ * larger than this.
421
399
  */
422
400
  Assert(initBlockSize == MAXALIGN(initBlockSize) &&
423
401
  initBlockSize >= 1024);
@@ -428,6 +406,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
428
406
  (minContextSize == MAXALIGN(minContextSize) &&
429
407
  minContextSize >= 1024 &&
430
408
  minContextSize <= maxBlockSize));
409
+ Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
431
410
 
432
411
  /*
433
412
  * Check whether the parameters match either available freelist. We do
@@ -462,12 +441,12 @@ AllocSetContextCreateInternal(MemoryContext parent,
462
441
  /* Reinitialize its header, installing correct name and parent */
463
442
  MemoryContextCreate((MemoryContext) set,
464
443
  T_AllocSetContext,
465
- &AllocSetMethods,
444
+ MCTX_ASET_ID,
466
445
  parent,
467
446
  name);
468
447
 
469
448
  ((MemoryContext) set)->mem_allocated =
470
- set->keeper->endptr - ((char *) set);
449
+ KeeperBlock(set)->endptr - ((char *) set);
471
450
 
472
451
  return (MemoryContext) set;
473
452
  }
@@ -503,7 +482,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
503
482
  */
504
483
 
505
484
  /* Fill in the initial block's block header */
506
- block = (AllocBlock) (((char *) set) + MAXALIGN(sizeof(AllocSetContext)));
485
+ block = KeeperBlock(set);
507
486
  block->aset = set;
508
487
  block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
509
488
  block->endptr = ((char *) set) + firstBlockSize;
@@ -515,15 +494,13 @@ AllocSetContextCreateInternal(MemoryContext parent,
515
494
 
516
495
  /* Remember block as part of block list */
517
496
  set->blocks = block;
518
- /* Mark block as not to be released at reset time */
519
- set->keeper = block;
520
497
 
521
498
  /* Finish filling in aset-specific parts of the context header */
522
499
  MemSetAligned(set->freelist, 0, sizeof(set->freelist));
523
500
 
524
- set->initBlockSize = initBlockSize;
525
- set->maxBlockSize = maxBlockSize;
526
- set->nextBlockSize = initBlockSize;
501
+ set->initBlockSize = (uint32) initBlockSize;
502
+ set->maxBlockSize = (uint32) maxBlockSize;
503
+ set->nextBlockSize = (uint32) initBlockSize;
527
504
  set->freeListIndex = freeListIndex;
528
505
 
529
506
  /*
@@ -536,15 +513,20 @@ AllocSetContextCreateInternal(MemoryContext parent,
536
513
  * requests that are all the maximum chunk size we will waste at most
537
514
  * 1/8th of the allocated space.
538
515
  *
539
- * We have to have allocChunkLimit a power of two, because the requested
540
- * and actually-allocated sizes of any chunk must be on the same side of
541
- * the limit, else we get confused about whether the chunk is "big".
542
- *
543
516
  * Also, allocChunkLimit must not exceed ALLOCSET_SEPARATE_THRESHOLD.
544
517
  */
545
518
  StaticAssertStmt(ALLOC_CHUNK_LIMIT == ALLOCSET_SEPARATE_THRESHOLD,
546
519
  "ALLOC_CHUNK_LIMIT != ALLOCSET_SEPARATE_THRESHOLD");
547
520
 
521
+ /*
522
+ * Determine the maximum size that a chunk can be before we allocate an
523
+ * entire AllocBlock dedicated for that chunk. We set the absolute limit
524
+ * of that size as ALLOC_CHUNK_LIMIT but we reduce it further so that we
525
+ * can fit about ALLOC_CHUNK_FRACTION chunks this size on a maximally
526
+ * sized block. (We opt to keep allocChunkLimit a power-of-2 value
527
+ * primarily for legacy reasons rather than calculating it so that exactly
528
+ * ALLOC_CHUNK_FRACTION chunks fit on a maximally sized block.)
529
+ */
548
530
  set->allocChunkLimit = ALLOC_CHUNK_LIMIT;
549
531
  while ((Size) (set->allocChunkLimit + ALLOC_CHUNKHDRSZ) >
550
532
  (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))
@@ -553,7 +535,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
553
535
  /* Finally, do the type-independent part of context creation */
554
536
  MemoryContextCreate((MemoryContext) set,
555
537
  T_AllocSetContext,
556
- &AllocSetMethods,
538
+ MCTX_ASET_ID,
557
539
  parent,
558
540
  name);
559
541
 
@@ -574,34 +556,36 @@ AllocSetContextCreateInternal(MemoryContext parent,
574
556
  * thrash malloc() when a context is repeatedly reset after small allocations,
575
557
  * which is typical behavior for per-tuple contexts.
576
558
  */
577
- static void
559
+ void
578
560
  AllocSetReset(MemoryContext context)
579
561
  {
580
562
  AllocSet set = (AllocSet) context;
581
563
  AllocBlock block;
582
- Size keepersize PG_USED_FOR_ASSERTS_ONLY
583
- = set->keeper->endptr - ((char *) set);
564
+ Size keepersize PG_USED_FOR_ASSERTS_ONLY;
584
565
 
585
- AssertArg(AllocSetIsValid(set));
566
+ Assert(AllocSetIsValid(set));
586
567
 
587
568
  #ifdef MEMORY_CONTEXT_CHECKING
588
569
  /* Check for corruption and leaks before freeing */
589
570
  AllocSetCheck(context);
590
571
  #endif
591
572
 
573
+ /* Remember keeper block size for Assert below */
574
+ keepersize = KeeperBlock(set)->endptr - ((char *) set);
575
+
592
576
  /* Clear chunk freelists */
593
577
  MemSetAligned(set->freelist, 0, sizeof(set->freelist));
594
578
 
595
579
  block = set->blocks;
596
580
 
597
581
  /* New blocks list will be just the keeper block */
598
- set->blocks = set->keeper;
582
+ set->blocks = KeeperBlock(set);
599
583
 
600
584
  while (block != NULL)
601
585
  {
602
586
  AllocBlock next = block->next;
603
587
 
604
- if (block == set->keeper)
588
+ if (IsKeeperBlock(set, block))
605
589
  {
606
590
  /* Reset the block, but don't return it to malloc */
607
591
  char *datastart = ((char *) block) + ALLOC_BLOCKHDRSZ;
@@ -642,21 +626,23 @@ AllocSetReset(MemoryContext context)
642
626
  *
643
627
  * Unlike AllocSetReset, this *must* free all resources of the set.
644
628
  */
645
- static void
629
+ void
646
630
  AllocSetDelete(MemoryContext context)
647
631
  {
648
632
  AllocSet set = (AllocSet) context;
649
633
  AllocBlock block = set->blocks;
650
- Size keepersize PG_USED_FOR_ASSERTS_ONLY
651
- = set->keeper->endptr - ((char *) set);
634
+ Size keepersize PG_USED_FOR_ASSERTS_ONLY;
652
635
 
653
- AssertArg(AllocSetIsValid(set));
636
+ Assert(AllocSetIsValid(set));
654
637
 
655
638
  #ifdef MEMORY_CONTEXT_CHECKING
656
639
  /* Check for corruption and leaks before freeing */
657
640
  AllocSetCheck(context);
658
641
  #endif
659
642
 
643
+ /* Remember keeper block size for Assert below */
644
+ keepersize = KeeperBlock(set)->endptr - ((char *) set);
645
+
660
646
  /*
661
647
  * If the context is a candidate for a freelist, put it into that freelist
662
648
  * instead of destroying it.
@@ -704,14 +690,14 @@ AllocSetDelete(MemoryContext context)
704
690
  {
705
691
  AllocBlock next = block->next;
706
692
 
707
- if (block != set->keeper)
693
+ if (!IsKeeperBlock(set, block))
708
694
  context->mem_allocated -= block->endptr - ((char *) block);
709
695
 
710
696
  #ifdef CLOBBER_FREED_MEMORY
711
697
  wipe_mem(block, block->freeptr - ((char *) block));
712
698
  #endif
713
699
 
714
- if (block != set->keeper)
700
+ if (!IsKeeperBlock(set, block))
715
701
  free(block);
716
702
 
717
703
  block = next;
@@ -724,326 +710,410 @@ AllocSetDelete(MemoryContext context)
724
710
  }
725
711
 
726
712
  /*
727
- * AllocSetAlloc
728
- * Returns pointer to allocated memory of given size or NULL if
729
- * request could not be completed; memory is added to the set.
713
+ * Helper for AllocSetAlloc() that allocates an entire block for the chunk.
730
714
  *
731
- * No request may exceed:
732
- * MAXALIGN_DOWN(SIZE_MAX) - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ
733
- * All callers use a much-lower limit.
734
- *
735
- * Note: when using valgrind, it doesn't matter how the returned allocation
736
- * is marked, as mcxt.c will set it to UNDEFINED. In some paths we will
737
- * return space that is marked NOACCESS - AllocSetRealloc has to beware!
715
+ * AllocSetAlloc()'s comment explains why this is separate.
738
716
  */
717
+ pg_noinline
739
718
  static void *
740
- AllocSetAlloc(MemoryContext context, Size size)
719
+ AllocSetAllocLarge(MemoryContext context, Size size, int flags)
741
720
  {
742
721
  AllocSet set = (AllocSet) context;
743
722
  AllocBlock block;
744
- AllocChunk chunk;
745
- int fidx;
723
+ MemoryChunk *chunk;
746
724
  Size chunk_size;
747
725
  Size blksize;
748
726
 
749
- AssertArg(AllocSetIsValid(set));
727
+ /* validate 'size' is within the limits for the given 'flags' */
728
+ MemoryContextCheckSize(context, size, flags);
750
729
 
751
- /*
752
- * If requested size exceeds maximum for chunks, allocate an entire block
753
- * for this request.
754
- */
755
- if (size > set->allocChunkLimit)
756
- {
757
- chunk_size = MAXALIGN(size);
758
- blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
759
- block = (AllocBlock) malloc(blksize);
760
- if (block == NULL)
761
- return NULL;
730
+ #ifdef MEMORY_CONTEXT_CHECKING
731
+ /* ensure there's always space for the sentinel byte */
732
+ chunk_size = MAXALIGN(size + 1);
733
+ #else
734
+ chunk_size = MAXALIGN(size);
735
+ #endif
762
736
 
763
- context->mem_allocated += blksize;
737
+ blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
738
+ block = (AllocBlock) malloc(blksize);
739
+ if (block == NULL)
740
+ return MemoryContextAllocationFailure(context, size, flags);
764
741
 
765
- block->aset = set;
766
- block->freeptr = block->endptr = ((char *) block) + blksize;
742
+ context->mem_allocated += blksize;
743
+
744
+ block->aset = set;
745
+ block->freeptr = block->endptr = ((char *) block) + blksize;
746
+
747
+ chunk = (MemoryChunk *) (((char *) block) + ALLOC_BLOCKHDRSZ);
748
+
749
+ /* mark the MemoryChunk as externally managed */
750
+ MemoryChunkSetHdrMaskExternal(chunk, MCTX_ASET_ID);
767
751
 
768
- chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
769
- chunk->aset = set;
770
- chunk->size = chunk_size;
771
752
  #ifdef MEMORY_CONTEXT_CHECKING
772
- chunk->requested_size = size;
773
- /* set mark to catch clobber of "unused" space */
774
- if (size < chunk_size)
775
- set_sentinel(AllocChunkGetPointer(chunk), size);
753
+ chunk->requested_size = size;
754
+ /* set mark to catch clobber of "unused" space */
755
+ Assert(size < chunk_size);
756
+ set_sentinel(MemoryChunkGetPointer(chunk), size);
776
757
  #endif
777
758
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
778
- /* fill the allocated space with junk */
779
- randomize_mem((char *) AllocChunkGetPointer(chunk), size);
759
+ /* fill the allocated space with junk */
760
+ randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
780
761
  #endif
781
762
 
782
- /*
783
- * Stick the new block underneath the active allocation block, if any,
784
- * so that we don't lose the use of the space remaining therein.
785
- */
786
- if (set->blocks != NULL)
787
- {
788
- block->prev = set->blocks;
789
- block->next = set->blocks->next;
790
- if (block->next)
791
- block->next->prev = block;
792
- set->blocks->next = block;
793
- }
794
- else
795
- {
796
- block->prev = NULL;
797
- block->next = NULL;
798
- set->blocks = block;
799
- }
763
+ /*
764
+ * Stick the new block underneath the active allocation block, if any, so
765
+ * that we don't lose the use of the space remaining therein.
766
+ */
767
+ if (set->blocks != NULL)
768
+ {
769
+ block->prev = set->blocks;
770
+ block->next = set->blocks->next;
771
+ if (block->next)
772
+ block->next->prev = block;
773
+ set->blocks->next = block;
774
+ }
775
+ else
776
+ {
777
+ block->prev = NULL;
778
+ block->next = NULL;
779
+ set->blocks = block;
780
+ }
800
781
 
801
- /* Ensure any padding bytes are marked NOACCESS. */
802
- VALGRIND_MAKE_MEM_NOACCESS((char *) AllocChunkGetPointer(chunk) + size,
803
- chunk_size - size);
782
+ /* Ensure any padding bytes are marked NOACCESS. */
783
+ VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
784
+ chunk_size - size);
804
785
 
805
- /* Disallow external access to private part of chunk header. */
806
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
786
+ /* Disallow access to the chunk header. */
787
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
807
788
 
808
- return AllocChunkGetPointer(chunk);
809
- }
789
+ return MemoryChunkGetPointer(chunk);
790
+ }
810
791
 
811
- /*
812
- * Request is small enough to be treated as a chunk. Look in the
813
- * corresponding free list to see if there is a free chunk we could reuse.
814
- * If one is found, remove it from the free list, make it again a member
815
- * of the alloc set and return its data address.
816
- */
817
- fidx = AllocSetFreeIndex(size);
818
- chunk = set->freelist[fidx];
819
- if (chunk != NULL)
820
- {
821
- Assert(chunk->size >= size);
792
+ /*
793
+ * Small helper for allocating a new chunk from a chunk, to avoid duplicating
794
+ * the code between AllocSetAlloc() and AllocSetAllocFromNewBlock().
795
+ */
796
+ static inline void *
797
+ AllocSetAllocChunkFromBlock(MemoryContext context, AllocBlock block,
798
+ Size size, Size chunk_size, int fidx)
799
+ {
800
+ MemoryChunk *chunk;
801
+
802
+ chunk = (MemoryChunk *) (block->freeptr);
803
+
804
+ /* Prepare to initialize the chunk header. */
805
+ VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNKHDRSZ);
822
806
 
823
- set->freelist[fidx] = (AllocChunk) chunk->aset;
807
+ block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
808
+ Assert(block->freeptr <= block->endptr);
824
809
 
825
- chunk->aset = (void *) set;
810
+ /* store the free list index in the value field */
811
+ MemoryChunkSetHdrMask(chunk, block, fidx, MCTX_ASET_ID);
826
812
 
827
813
  #ifdef MEMORY_CONTEXT_CHECKING
828
- chunk->requested_size = size;
829
- /* set mark to catch clobber of "unused" space */
830
- if (size < chunk->size)
831
- set_sentinel(AllocChunkGetPointer(chunk), size);
814
+ chunk->requested_size = size;
815
+ /* set mark to catch clobber of "unused" space */
816
+ if (size < chunk_size)
817
+ set_sentinel(MemoryChunkGetPointer(chunk), size);
832
818
  #endif
833
819
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
834
- /* fill the allocated space with junk */
835
- randomize_mem((char *) AllocChunkGetPointer(chunk), size);
820
+ /* fill the allocated space with junk */
821
+ randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
836
822
  #endif
837
823
 
838
- /* Ensure any padding bytes are marked NOACCESS. */
839
- VALGRIND_MAKE_MEM_NOACCESS((char *) AllocChunkGetPointer(chunk) + size,
840
- chunk->size - size);
824
+ /* Ensure any padding bytes are marked NOACCESS. */
825
+ VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
826
+ chunk_size - size);
841
827
 
842
- /* Disallow external access to private part of chunk header. */
843
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
828
+ /* Disallow access to the chunk header. */
829
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
844
830
 
845
- return AllocChunkGetPointer(chunk);
846
- }
831
+ return MemoryChunkGetPointer(chunk);
832
+ }
847
833
 
848
- /*
849
- * Choose the actual chunk size to allocate.
850
- */
851
- chunk_size = (1 << ALLOC_MINBITS) << fidx;
852
- Assert(chunk_size >= size);
834
+ /*
835
+ * Helper for AllocSetAlloc() that allocates a new block and returns a chunk
836
+ * allocated from it.
837
+ *
838
+ * AllocSetAlloc()'s comment explains why this is separate.
839
+ */
840
+ pg_noinline
841
+ static void *
842
+ AllocSetAllocFromNewBlock(MemoryContext context, Size size, int flags,
843
+ int fidx)
844
+ {
845
+ AllocSet set = (AllocSet) context;
846
+ AllocBlock block;
847
+ Size availspace;
848
+ Size blksize;
849
+ Size required_size;
850
+ Size chunk_size;
851
+
852
+ /* due to the keeper block set->blocks should always be valid */
853
+ Assert(set->blocks != NULL);
854
+ block = set->blocks;
855
+ availspace = block->endptr - block->freeptr;
853
856
 
854
857
  /*
855
- * If there is enough room in the active allocation block, we will put the
856
- * chunk into that block. Else must start a new one.
858
+ * The existing active (top) block does not have enough room for the
859
+ * requested allocation, but it might still have a useful amount of space
860
+ * in it. Once we push it down in the block list, we'll never try to
861
+ * allocate more space from it. So, before we do that, carve up its free
862
+ * space into chunks that we can put on the set's freelists.
863
+ *
864
+ * Because we can only get here when there's less than ALLOC_CHUNK_LIMIT
865
+ * left in the block, this loop cannot iterate more than
866
+ * ALLOCSET_NUM_FREELISTS-1 times.
857
867
  */
858
- if ((block = set->blocks) != NULL)
868
+ while (availspace >= ((1 << ALLOC_MINBITS) + ALLOC_CHUNKHDRSZ))
859
869
  {
860
- Size availspace = block->endptr - block->freeptr;
870
+ AllocFreeListLink *link;
871
+ MemoryChunk *chunk;
872
+ Size availchunk = availspace - ALLOC_CHUNKHDRSZ;
873
+ int a_fidx = AllocSetFreeIndex(availchunk);
861
874
 
862
- if (availspace < (chunk_size + ALLOC_CHUNKHDRSZ))
875
+ /*
876
+ * In most cases, we'll get back the index of the next larger freelist
877
+ * than the one we need to put this chunk on. The exception is when
878
+ * availchunk is exactly a power of 2.
879
+ */
880
+ if (availchunk != GetChunkSizeFromFreeListIdx(a_fidx))
863
881
  {
864
- /*
865
- * The existing active (top) block does not have enough room for
866
- * the requested allocation, but it might still have a useful
867
- * amount of space in it. Once we push it down in the block list,
868
- * we'll never try to allocate more space from it. So, before we
869
- * do that, carve up its free space into chunks that we can put on
870
- * the set's freelists.
871
- *
872
- * Because we can only get here when there's less than
873
- * ALLOC_CHUNK_LIMIT left in the block, this loop cannot iterate
874
- * more than ALLOCSET_NUM_FREELISTS-1 times.
875
- */
876
- while (availspace >= ((1 << ALLOC_MINBITS) + ALLOC_CHUNKHDRSZ))
877
- {
878
- Size availchunk = availspace - ALLOC_CHUNKHDRSZ;
879
- int a_fidx = AllocSetFreeIndex(availchunk);
880
-
881
- /*
882
- * In most cases, we'll get back the index of the next larger
883
- * freelist than the one we need to put this chunk on. The
884
- * exception is when availchunk is exactly a power of 2.
885
- */
886
- if (availchunk != ((Size) 1 << (a_fidx + ALLOC_MINBITS)))
887
- {
888
- a_fidx--;
889
- Assert(a_fidx >= 0);
890
- availchunk = ((Size) 1 << (a_fidx + ALLOC_MINBITS));
891
- }
892
-
893
- chunk = (AllocChunk) (block->freeptr);
882
+ a_fidx--;
883
+ Assert(a_fidx >= 0);
884
+ availchunk = GetChunkSizeFromFreeListIdx(a_fidx);
885
+ }
894
886
 
895
- /* Prepare to initialize the chunk header. */
896
- VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNKHDRSZ);
887
+ chunk = (MemoryChunk *) (block->freeptr);
897
888
 
898
- block->freeptr += (availchunk + ALLOC_CHUNKHDRSZ);
899
- availspace -= (availchunk + ALLOC_CHUNKHDRSZ);
889
+ /* Prepare to initialize the chunk header. */
890
+ VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNKHDRSZ);
891
+ block->freeptr += (availchunk + ALLOC_CHUNKHDRSZ);
892
+ availspace -= (availchunk + ALLOC_CHUNKHDRSZ);
900
893
 
901
- chunk->size = availchunk;
894
+ /* store the freelist index in the value field */
895
+ MemoryChunkSetHdrMask(chunk, block, a_fidx, MCTX_ASET_ID);
902
896
  #ifdef MEMORY_CONTEXT_CHECKING
903
- chunk->requested_size = 0; /* mark it free */
897
+ chunk->requested_size = InvalidAllocSize; /* mark it free */
904
898
  #endif
905
- chunk->aset = (void *) set->freelist[a_fidx];
906
- set->freelist[a_fidx] = chunk;
907
- }
899
+ /* push this chunk onto the free list */
900
+ link = GetFreeListLink(chunk);
908
901
 
909
- /* Mark that we need to create a new block */
910
- block = NULL;
911
- }
902
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
903
+ link->next = set->freelist[a_fidx];
904
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
905
+
906
+ set->freelist[a_fidx] = chunk;
912
907
  }
913
908
 
914
909
  /*
915
- * Time to create a new regular (multi-chunk) block?
910
+ * The first such block has size initBlockSize, and we double the space in
911
+ * each succeeding block, but not more than maxBlockSize.
916
912
  */
917
- if (block == NULL)
918
- {
919
- Size required_size;
913
+ blksize = set->nextBlockSize;
914
+ set->nextBlockSize <<= 1;
915
+ if (set->nextBlockSize > set->maxBlockSize)
916
+ set->nextBlockSize = set->maxBlockSize;
920
917
 
921
- /*
922
- * The first such block has size initBlockSize, and we double the
923
- * space in each succeeding block, but not more than maxBlockSize.
924
- */
925
- blksize = set->nextBlockSize;
926
- set->nextBlockSize <<= 1;
927
- if (set->nextBlockSize > set->maxBlockSize)
928
- set->nextBlockSize = set->maxBlockSize;
918
+ /* Choose the actual chunk size to allocate */
919
+ chunk_size = GetChunkSizeFromFreeListIdx(fidx);
920
+ Assert(chunk_size >= size);
929
921
 
930
- /*
931
- * If initBlockSize is less than ALLOC_CHUNK_LIMIT, we could need more
932
- * space... but try to keep it a power of 2.
933
- */
934
- required_size = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
935
- while (blksize < required_size)
936
- blksize <<= 1;
922
+ /*
923
+ * If initBlockSize is less than ALLOC_CHUNK_LIMIT, we could need more
924
+ * space... but try to keep it a power of 2.
925
+ */
926
+ required_size = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
927
+ while (blksize < required_size)
928
+ blksize <<= 1;
929
+
930
+ /* Try to allocate it */
931
+ block = (AllocBlock) malloc(blksize);
937
932
 
938
- /* Try to allocate it */
933
+ /*
934
+ * We could be asking for pretty big blocks here, so cope if malloc fails.
935
+ * But give up if there's less than 1 MB or so available...
936
+ */
937
+ while (block == NULL && blksize > 1024 * 1024)
938
+ {
939
+ blksize >>= 1;
940
+ if (blksize < required_size)
941
+ break;
939
942
  block = (AllocBlock) malloc(blksize);
943
+ }
940
944
 
941
- /*
942
- * We could be asking for pretty big blocks here, so cope if malloc
943
- * fails. But give up if there's less than 1 MB or so available...
944
- */
945
- while (block == NULL && blksize > 1024 * 1024)
946
- {
947
- blksize >>= 1;
948
- if (blksize < required_size)
949
- break;
950
- block = (AllocBlock) malloc(blksize);
951
- }
945
+ if (block == NULL)
946
+ return MemoryContextAllocationFailure(context, size, flags);
952
947
 
953
- if (block == NULL)
954
- return NULL;
948
+ context->mem_allocated += blksize;
955
949
 
956
- context->mem_allocated += blksize;
950
+ block->aset = set;
951
+ block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
952
+ block->endptr = ((char *) block) + blksize;
957
953
 
958
- block->aset = set;
959
- block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
960
- block->endptr = ((char *) block) + blksize;
954
+ /* Mark unallocated space NOACCESS. */
955
+ VALGRIND_MAKE_MEM_NOACCESS(block->freeptr,
956
+ blksize - ALLOC_BLOCKHDRSZ);
961
957
 
962
- /* Mark unallocated space NOACCESS. */
963
- VALGRIND_MAKE_MEM_NOACCESS(block->freeptr,
964
- blksize - ALLOC_BLOCKHDRSZ);
958
+ block->prev = NULL;
959
+ block->next = set->blocks;
960
+ if (block->next)
961
+ block->next->prev = block;
962
+ set->blocks = block;
965
963
 
966
- block->prev = NULL;
967
- block->next = set->blocks;
968
- if (block->next)
969
- block->next->prev = block;
970
- set->blocks = block;
971
- }
964
+ return AllocSetAllocChunkFromBlock(context, block, size, chunk_size, fidx);
965
+ }
966
+
967
+ /*
968
+ * AllocSetAlloc
969
+ * Returns a pointer to allocated memory of given size or raises an ERROR
970
+ * on allocation failure, or returns NULL when flags contains
971
+ * MCXT_ALLOC_NO_OOM.
972
+ *
973
+ * No request may exceed:
974
+ * MAXALIGN_DOWN(SIZE_MAX) - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ
975
+ * All callers use a much-lower limit.
976
+ *
977
+ * Note: when using valgrind, it doesn't matter how the returned allocation
978
+ * is marked, as mcxt.c will set it to UNDEFINED. In some paths we will
979
+ * return space that is marked NOACCESS - AllocSetRealloc has to beware!
980
+ *
981
+ * This function should only contain the most common code paths. Everything
982
+ * else should be in pg_noinline helper functions, thus avoiding the overhead
983
+ * of creating a stack frame for the common cases. Allocating memory is often
984
+ * a bottleneck in many workloads, so avoiding stack frame setup is
985
+ * worthwhile. Helper functions should always directly return the newly
986
+ * allocated memory so that we can just return that address directly as a tail
987
+ * call.
988
+ */
989
+ void *
990
+ AllocSetAlloc(MemoryContext context, Size size, int flags)
991
+ {
992
+ AllocSet set = (AllocSet) context;
993
+ AllocBlock block;
994
+ MemoryChunk *chunk;
995
+ int fidx;
996
+ Size chunk_size;
997
+ Size availspace;
998
+
999
+ Assert(AllocSetIsValid(set));
1000
+
1001
+ /* due to the keeper block set->blocks should never be NULL */
1002
+ Assert(set->blocks != NULL);
972
1003
 
973
1004
  /*
974
- * OK, do the allocation
1005
+ * If requested size exceeds maximum for chunks we hand the request off to
1006
+ * AllocSetAllocLarge().
975
1007
  */
976
- chunk = (AllocChunk) (block->freeptr);
1008
+ if (size > set->allocChunkLimit)
1009
+ return AllocSetAllocLarge(context, size, flags);
977
1010
 
978
- /* Prepare to initialize the chunk header. */
979
- VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNKHDRSZ);
1011
+ /*
1012
+ * Request is small enough to be treated as a chunk. Look in the
1013
+ * corresponding free list to see if there is a free chunk we could reuse.
1014
+ * If one is found, remove it from the free list, make it again a member
1015
+ * of the alloc set and return its data address.
1016
+ *
1017
+ * Note that we don't attempt to ensure there's space for the sentinel
1018
+ * byte here. We expect a large proportion of allocations to be for sizes
1019
+ * which are already a power of 2. If we were to always make space for a
1020
+ * sentinel byte in MEMORY_CONTEXT_CHECKING builds, then we'd end up
1021
+ * doubling the memory requirements for such allocations.
1022
+ */
1023
+ fidx = AllocSetFreeIndex(size);
1024
+ chunk = set->freelist[fidx];
1025
+ if (chunk != NULL)
1026
+ {
1027
+ AllocFreeListLink *link = GetFreeListLink(chunk);
980
1028
 
981
- block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
982
- Assert(block->freeptr <= block->endptr);
1029
+ /* Allow access to the chunk header. */
1030
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1031
+
1032
+ Assert(fidx == MemoryChunkGetValue(chunk));
1033
+
1034
+ /* pop this chunk off the freelist */
1035
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
1036
+ set->freelist[fidx] = link->next;
1037
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
983
1038
 
984
- chunk->aset = (void *) set;
985
- chunk->size = chunk_size;
986
1039
  #ifdef MEMORY_CONTEXT_CHECKING
987
- chunk->requested_size = size;
988
- /* set mark to catch clobber of "unused" space */
989
- if (size < chunk->size)
990
- set_sentinel(AllocChunkGetPointer(chunk), size);
1040
+ chunk->requested_size = size;
1041
+ /* set mark to catch clobber of "unused" space */
1042
+ if (size < GetChunkSizeFromFreeListIdx(fidx))
1043
+ set_sentinel(MemoryChunkGetPointer(chunk), size);
991
1044
  #endif
992
1045
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
993
- /* fill the allocated space with junk */
994
- randomize_mem((char *) AllocChunkGetPointer(chunk), size);
1046
+ /* fill the allocated space with junk */
1047
+ randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
995
1048
  #endif
996
1049
 
997
- /* Ensure any padding bytes are marked NOACCESS. */
998
- VALGRIND_MAKE_MEM_NOACCESS((char *) AllocChunkGetPointer(chunk) + size,
999
- chunk_size - size);
1050
+ /* Ensure any padding bytes are marked NOACCESS. */
1051
+ VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
1052
+ GetChunkSizeFromFreeListIdx(fidx) - size);
1000
1053
 
1001
- /* Disallow external access to private part of chunk header. */
1002
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1054
+ /* Disallow access to the chunk header. */
1055
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1003
1056
 
1004
- return AllocChunkGetPointer(chunk);
1057
+ return MemoryChunkGetPointer(chunk);
1058
+ }
1059
+
1060
+ /*
1061
+ * Choose the actual chunk size to allocate.
1062
+ */
1063
+ chunk_size = GetChunkSizeFromFreeListIdx(fidx);
1064
+ Assert(chunk_size >= size);
1065
+
1066
+ block = set->blocks;
1067
+ availspace = block->endptr - block->freeptr;
1068
+
1069
+ /*
1070
+ * If there is enough room in the active allocation block, we will put the
1071
+ * chunk into that block. Else must start a new one.
1072
+ */
1073
+ if (unlikely(availspace < (chunk_size + ALLOC_CHUNKHDRSZ)))
1074
+ return AllocSetAllocFromNewBlock(context, size, flags, fidx);
1075
+
1076
+ /* There's enough space on the current block, so allocate from that */
1077
+ return AllocSetAllocChunkFromBlock(context, block, size, chunk_size, fidx);
1005
1078
  }
1006
1079
 
1007
1080
  /*
1008
1081
  * AllocSetFree
1009
1082
  * Frees allocated memory; memory is removed from the set.
1010
1083
  */
1011
- static void
1012
- AllocSetFree(MemoryContext context, void *pointer)
1084
+ void
1085
+ AllocSetFree(void *pointer)
1013
1086
  {
1014
- AllocSet set = (AllocSet) context;
1015
- AllocChunk chunk = AllocPointerGetChunk(pointer);
1016
-
1017
- /* Allow access to private part of chunk header. */
1018
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1087
+ AllocSet set;
1088
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1019
1089
 
1020
- #ifdef MEMORY_CONTEXT_CHECKING
1021
- /* Test for someone scribbling on unused space in chunk */
1022
- if (chunk->requested_size < chunk->size)
1023
- if (!sentinel_ok(pointer, chunk->requested_size))
1024
- elog(WARNING, "detected write past chunk end in %s %p",
1025
- set->header.name, chunk);
1026
- #endif
1090
+ /* Allow access to the chunk header. */
1091
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1027
1092
 
1028
- if (chunk->size > set->allocChunkLimit)
1093
+ if (MemoryChunkIsExternal(chunk))
1029
1094
  {
1030
- /*
1031
- * Big chunks are certain to have been allocated as single-chunk
1032
- * blocks. Just unlink that block and return it to malloc().
1033
- */
1034
- AllocBlock block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ);
1095
+ /* Release single-chunk block. */
1096
+ AllocBlock block = ExternalChunkGetBlock(chunk);
1035
1097
 
1036
1098
  /*
1037
- * Try to verify that we have a sane block pointer: it should
1038
- * reference the correct aset, and freeptr and endptr should point
1039
- * just past the chunk.
1099
+ * Try to verify that we have a sane block pointer: the block header
1100
+ * should reference an aset and the freeptr should match the endptr.
1040
1101
  */
1041
- if (block->aset != set ||
1042
- block->freeptr != block->endptr ||
1043
- block->freeptr != ((char *) block) +
1044
- (chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ))
1102
+ if (!AllocBlockIsValid(block) || block->freeptr != block->endptr)
1045
1103
  elog(ERROR, "could not find block containing chunk %p", chunk);
1046
1104
 
1105
+ set = block->aset;
1106
+
1107
+ #ifdef MEMORY_CONTEXT_CHECKING
1108
+ {
1109
+ /* Test for someone scribbling on unused space in chunk */
1110
+ Assert(chunk->requested_size < (block->endptr - (char *) pointer));
1111
+ if (!sentinel_ok(pointer, chunk->requested_size))
1112
+ elog(WARNING, "detected write past chunk end in %s %p",
1113
+ set->header.name, chunk);
1114
+ }
1115
+ #endif
1116
+
1047
1117
  /* OK, remove block from aset's list and free it */
1048
1118
  if (block->prev)
1049
1119
  block->prev->next = block->next;
@@ -1052,7 +1122,7 @@ AllocSetFree(MemoryContext context, void *pointer)
1052
1122
  if (block->next)
1053
1123
  block->next->prev = block->prev;
1054
1124
 
1055
- context->mem_allocated -= block->endptr - ((char *) block);
1125
+ set->header.mem_allocated -= block->endptr - ((char *) block);
1056
1126
 
1057
1127
  #ifdef CLOBBER_FREED_MEMORY
1058
1128
  wipe_mem(block, block->freeptr - ((char *) block));
@@ -1061,20 +1131,48 @@ AllocSetFree(MemoryContext context, void *pointer)
1061
1131
  }
1062
1132
  else
1063
1133
  {
1064
- /* Normal case, put the chunk into appropriate freelist */
1065
- int fidx = AllocSetFreeIndex(chunk->size);
1134
+ AllocBlock block = MemoryChunkGetBlock(chunk);
1135
+ int fidx;
1136
+ AllocFreeListLink *link;
1137
+
1138
+ /*
1139
+ * In this path, for speed reasons we just Assert that the referenced
1140
+ * block is good. We can also Assert that the value field is sane.
1141
+ * Future field experience may show that these Asserts had better
1142
+ * become regular runtime test-and-elog checks.
1143
+ */
1144
+ Assert(AllocBlockIsValid(block));
1145
+ set = block->aset;
1146
+
1147
+ fidx = MemoryChunkGetValue(chunk);
1148
+ Assert(FreeListIdxIsValid(fidx));
1149
+ link = GetFreeListLink(chunk);
1066
1150
 
1067
- chunk->aset = (void *) set->freelist[fidx];
1151
+ #ifdef MEMORY_CONTEXT_CHECKING
1152
+ /* Test for someone scribbling on unused space in chunk */
1153
+ if (chunk->requested_size < GetChunkSizeFromFreeListIdx(fidx))
1154
+ if (!sentinel_ok(pointer, chunk->requested_size))
1155
+ elog(WARNING, "detected write past chunk end in %s %p",
1156
+ set->header.name, chunk);
1157
+ #endif
1068
1158
 
1069
1159
  #ifdef CLOBBER_FREED_MEMORY
1070
- wipe_mem(pointer, chunk->size);
1160
+ wipe_mem(pointer, GetChunkSizeFromFreeListIdx(fidx));
1071
1161
  #endif
1162
+ /* push this chunk onto the top of the free list */
1163
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
1164
+ link->next = set->freelist[fidx];
1165
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
1166
+ set->freelist[fidx] = chunk;
1072
1167
 
1073
1168
  #ifdef MEMORY_CONTEXT_CHECKING
1074
- /* Reset requested_size to 0 in chunks that are on freelist */
1075
- chunk->requested_size = 0;
1169
+
1170
+ /*
1171
+ * Reset requested_size to InvalidAllocSize in chunks that are on free
1172
+ * list.
1173
+ */
1174
+ chunk->requested_size = InvalidAllocSize;
1076
1175
  #endif
1077
- set->freelist[fidx] = chunk;
1078
1176
  }
1079
1177
  }
1080
1178
 
@@ -1090,57 +1188,59 @@ AllocSetFree(MemoryContext context, void *pointer)
1090
1188
  * (In principle, we could use VALGRIND_GET_VBITS() to rediscover the old
1091
1189
  * request size.)
1092
1190
  */
1093
- static void *
1094
- AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1191
+ void *
1192
+ AllocSetRealloc(void *pointer, Size size, int flags)
1095
1193
  {
1096
- AllocSet set = (AllocSet) context;
1097
- AllocChunk chunk = AllocPointerGetChunk(pointer);
1098
- Size oldsize;
1099
-
1100
- /* Allow access to private part of chunk header. */
1101
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1102
-
1103
- oldsize = chunk->size;
1194
+ AllocBlock block;
1195
+ AllocSet set;
1196
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1197
+ Size oldchksize;
1198
+ int fidx;
1104
1199
 
1105
- #ifdef MEMORY_CONTEXT_CHECKING
1106
- /* Test for someone scribbling on unused space in chunk */
1107
- if (chunk->requested_size < oldsize)
1108
- if (!sentinel_ok(pointer, chunk->requested_size))
1109
- elog(WARNING, "detected write past chunk end in %s %p",
1110
- set->header.name, chunk);
1111
- #endif
1200
+ /* Allow access to the chunk header. */
1201
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1112
1202
 
1113
- if (oldsize > set->allocChunkLimit)
1203
+ if (MemoryChunkIsExternal(chunk))
1114
1204
  {
1115
1205
  /*
1116
1206
  * The chunk must have been allocated as a single-chunk block. Use
1117
1207
  * realloc() to make the containing block bigger, or smaller, with
1118
1208
  * minimum space wastage.
1119
1209
  */
1120
- AllocBlock block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ);
1121
1210
  Size chksize;
1122
1211
  Size blksize;
1123
1212
  Size oldblksize;
1124
1213
 
1214
+ block = ExternalChunkGetBlock(chunk);
1215
+
1125
1216
  /*
1126
- * Try to verify that we have a sane block pointer: it should
1127
- * reference the correct aset, and freeptr and endptr should point
1128
- * just past the chunk.
1217
+ * Try to verify that we have a sane block pointer: the block header
1218
+ * should reference an aset and the freeptr should match the endptr.
1129
1219
  */
1130
- if (block->aset != set ||
1131
- block->freeptr != block->endptr ||
1132
- block->freeptr != ((char *) block) +
1133
- (oldsize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ))
1220
+ if (!AllocBlockIsValid(block) || block->freeptr != block->endptr)
1134
1221
  elog(ERROR, "could not find block containing chunk %p", chunk);
1135
1222
 
1136
- /*
1137
- * Even if the new request is less than set->allocChunkLimit, we stick
1138
- * with the single-chunk block approach. Therefore we need
1139
- * chunk->size to be bigger than set->allocChunkLimit, so we don't get
1140
- * confused about the chunk's status in future calls.
1141
- */
1142
- chksize = Max(size, set->allocChunkLimit + 1);
1143
- chksize = MAXALIGN(chksize);
1223
+ set = block->aset;
1224
+
1225
+ /* only check size in paths where the limits could be hit */
1226
+ MemoryContextCheckSize((MemoryContext) set, size, flags);
1227
+
1228
+ oldchksize = block->endptr - (char *) pointer;
1229
+
1230
+ #ifdef MEMORY_CONTEXT_CHECKING
1231
+ /* Test for someone scribbling on unused space in chunk */
1232
+ Assert(chunk->requested_size < oldchksize);
1233
+ if (!sentinel_ok(pointer, chunk->requested_size))
1234
+ elog(WARNING, "detected write past chunk end in %s %p",
1235
+ set->header.name, chunk);
1236
+ #endif
1237
+
1238
+ #ifdef MEMORY_CONTEXT_CHECKING
1239
+ /* ensure there's always space for the sentinel byte */
1240
+ chksize = MAXALIGN(size + 1);
1241
+ #else
1242
+ chksize = MAXALIGN(size);
1243
+ #endif
1144
1244
 
1145
1245
  /* Do the realloc */
1146
1246
  blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
@@ -1149,77 +1249,109 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1149
1249
  block = (AllocBlock) realloc(block, blksize);
1150
1250
  if (block == NULL)
1151
1251
  {
1152
- /* Disallow external access to private part of chunk header. */
1153
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1154
- return NULL;
1252
+ /* Disallow access to the chunk header. */
1253
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1254
+ return MemoryContextAllocationFailure(&set->header, size, flags);
1155
1255
  }
1156
1256
 
1157
1257
  /* updated separately, not to underflow when (oldblksize > blksize) */
1158
- context->mem_allocated -= oldblksize;
1159
- context->mem_allocated += blksize;
1258
+ set->header.mem_allocated -= oldblksize;
1259
+ set->header.mem_allocated += blksize;
1160
1260
 
1161
1261
  block->freeptr = block->endptr = ((char *) block) + blksize;
1162
1262
 
1163
1263
  /* Update pointers since block has likely been moved */
1164
- chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
1165
- pointer = AllocChunkGetPointer(chunk);
1264
+ chunk = (MemoryChunk *) (((char *) block) + ALLOC_BLOCKHDRSZ);
1265
+ pointer = MemoryChunkGetPointer(chunk);
1166
1266
  if (block->prev)
1167
1267
  block->prev->next = block;
1168
1268
  else
1169
1269
  set->blocks = block;
1170
1270
  if (block->next)
1171
1271
  block->next->prev = block;
1172
- chunk->size = chksize;
1173
1272
 
1174
1273
  #ifdef MEMORY_CONTEXT_CHECKING
1175
1274
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
1176
- /* We can only fill the extra space if we know the prior request */
1275
+
1276
+ /*
1277
+ * We can only randomize the extra space if we know the prior request.
1278
+ * When using Valgrind, randomize_mem() also marks memory UNDEFINED.
1279
+ */
1177
1280
  if (size > chunk->requested_size)
1178
1281
  randomize_mem((char *) pointer + chunk->requested_size,
1179
1282
  size - chunk->requested_size);
1180
- #endif
1283
+ #else
1181
1284
 
1182
1285
  /*
1183
- * realloc() (or randomize_mem()) will have left any newly-allocated
1184
- * part UNDEFINED, but we may need to adjust trailing bytes from the
1185
- * old allocation.
1286
+ * If this is an increase, realloc() will have marked any
1287
+ * newly-allocated part (from oldchksize to chksize) UNDEFINED, but we
1288
+ * also need to adjust trailing bytes from the old allocation (from
1289
+ * chunk->requested_size to oldchksize) as they are marked NOACCESS.
1290
+ * Make sure not to mark too many bytes in case chunk->requested_size
1291
+ * < size < oldchksize.
1186
1292
  */
1187
1293
  #ifdef USE_VALGRIND
1188
- if (oldsize > chunk->requested_size)
1294
+ if (Min(size, oldchksize) > chunk->requested_size)
1189
1295
  VALGRIND_MAKE_MEM_UNDEFINED((char *) pointer + chunk->requested_size,
1190
- oldsize - chunk->requested_size);
1296
+ Min(size, oldchksize) - chunk->requested_size);
1297
+ #endif
1191
1298
  #endif
1192
1299
 
1193
1300
  chunk->requested_size = size;
1194
-
1195
1301
  /* set mark to catch clobber of "unused" space */
1196
- if (size < chunk->size)
1197
- set_sentinel(pointer, size);
1302
+ Assert(size < chksize);
1303
+ set_sentinel(pointer, size);
1198
1304
  #else /* !MEMORY_CONTEXT_CHECKING */
1199
1305
 
1200
1306
  /*
1201
- * We don't know how much of the old chunk size was the actual
1202
- * allocation; it could have been as small as one byte. We have to be
1203
- * conservative and just mark the entire old portion DEFINED.
1307
+ * We may need to adjust marking of bytes from the old allocation as
1308
+ * some of them may be marked NOACCESS. We don't know how much of the
1309
+ * old chunk size was the requested size; it could have been as small
1310
+ * as one byte. We have to be conservative and just mark the entire
1311
+ * old portion DEFINED. Make sure not to mark memory beyond the new
1312
+ * allocation in case it's smaller than the old one.
1204
1313
  */
1205
- VALGRIND_MAKE_MEM_DEFINED(pointer, oldsize);
1314
+ VALGRIND_MAKE_MEM_DEFINED(pointer, Min(size, oldchksize));
1206
1315
  #endif
1207
1316
 
1208
1317
  /* Ensure any padding bytes are marked NOACCESS. */
1209
1318
  VALGRIND_MAKE_MEM_NOACCESS((char *) pointer + size, chksize - size);
1210
1319
 
1211
- /* Disallow external access to private part of chunk header. */
1212
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1320
+ /* Disallow access to the chunk header . */
1321
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1213
1322
 
1214
1323
  return pointer;
1215
1324
  }
1216
1325
 
1326
+ block = MemoryChunkGetBlock(chunk);
1327
+
1328
+ /*
1329
+ * In this path, for speed reasons we just Assert that the referenced
1330
+ * block is good. We can also Assert that the value field is sane. Future
1331
+ * field experience may show that these Asserts had better become regular
1332
+ * runtime test-and-elog checks.
1333
+ */
1334
+ Assert(AllocBlockIsValid(block));
1335
+ set = block->aset;
1336
+
1337
+ fidx = MemoryChunkGetValue(chunk);
1338
+ Assert(FreeListIdxIsValid(fidx));
1339
+ oldchksize = GetChunkSizeFromFreeListIdx(fidx);
1340
+
1341
+ #ifdef MEMORY_CONTEXT_CHECKING
1342
+ /* Test for someone scribbling on unused space in chunk */
1343
+ if (chunk->requested_size < oldchksize)
1344
+ if (!sentinel_ok(pointer, chunk->requested_size))
1345
+ elog(WARNING, "detected write past chunk end in %s %p",
1346
+ set->header.name, chunk);
1347
+ #endif
1348
+
1217
1349
  /*
1218
1350
  * Chunk sizes are aligned to power of 2 in AllocSetAlloc(). Maybe the
1219
1351
  * allocated area already is >= the new size. (In particular, we will
1220
1352
  * fall out here if the requested size is a decrease.)
1221
1353
  */
1222
- else if (oldsize >= size)
1354
+ if (oldchksize >= size)
1223
1355
  {
1224
1356
  #ifdef MEMORY_CONTEXT_CHECKING
1225
1357
  Size oldrequest = chunk->requested_size;
@@ -1242,10 +1374,10 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1242
1374
  size - oldrequest);
1243
1375
  else
1244
1376
  VALGRIND_MAKE_MEM_NOACCESS((char *) pointer + size,
1245
- oldsize - size);
1377
+ oldchksize - size);
1246
1378
 
1247
1379
  /* set mark to catch clobber of "unused" space */
1248
- if (size < oldsize)
1380
+ if (size < oldchksize)
1249
1381
  set_sentinel(pointer, size);
1250
1382
  #else /* !MEMORY_CONTEXT_CHECKING */
1251
1383
 
@@ -1254,12 +1386,12 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1254
1386
  * the old request or shrinking it, so we conservatively mark the
1255
1387
  * entire new allocation DEFINED.
1256
1388
  */
1257
- VALGRIND_MAKE_MEM_NOACCESS(pointer, oldsize);
1389
+ VALGRIND_MAKE_MEM_NOACCESS(pointer, oldchksize);
1258
1390
  VALGRIND_MAKE_MEM_DEFINED(pointer, size);
1259
1391
  #endif
1260
1392
 
1261
- /* Disallow external access to private part of chunk header. */
1262
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1393
+ /* Disallow access to the chunk header. */
1394
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1263
1395
 
1264
1396
  return pointer;
1265
1397
  }
@@ -1277,16 +1409,17 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1277
1409
  * memory indefinitely. See pgsql-hackers archives for 2007-08-11.)
1278
1410
  */
1279
1411
  AllocPointer newPointer;
1412
+ Size oldsize;
1280
1413
 
1281
- /* allocate new chunk */
1282
- newPointer = AllocSetAlloc((MemoryContext) set, size);
1414
+ /* allocate new chunk (this also checks size is valid) */
1415
+ newPointer = AllocSetAlloc((MemoryContext) set, size, flags);
1283
1416
 
1284
1417
  /* leave immediately if request was not completed */
1285
1418
  if (newPointer == NULL)
1286
1419
  {
1287
- /* Disallow external access to private part of chunk header. */
1288
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1289
- return NULL;
1420
+ /* Disallow access to the chunk header. */
1421
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1422
+ return MemoryContextAllocationFailure((MemoryContext) set, size, flags);
1290
1423
  }
1291
1424
 
1292
1425
  /*
@@ -1301,6 +1434,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1301
1434
  #ifdef MEMORY_CONTEXT_CHECKING
1302
1435
  oldsize = chunk->requested_size;
1303
1436
  #else
1437
+ oldsize = oldchksize;
1304
1438
  VALGRIND_MAKE_MEM_DEFINED(pointer, oldsize);
1305
1439
  #endif
1306
1440
 
@@ -1308,36 +1442,84 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1308
1442
  memcpy(newPointer, pointer, oldsize);
1309
1443
 
1310
1444
  /* free old chunk */
1311
- AllocSetFree((MemoryContext) set, pointer);
1445
+ AllocSetFree(pointer);
1312
1446
 
1313
1447
  return newPointer;
1314
1448
  }
1315
1449
  }
1316
1450
 
1451
+ /*
1452
+ * AllocSetGetChunkContext
1453
+ * Return the MemoryContext that 'pointer' belongs to.
1454
+ */
1455
+ MemoryContext
1456
+ AllocSetGetChunkContext(void *pointer)
1457
+ {
1458
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1459
+ AllocBlock block;
1460
+ AllocSet set;
1461
+
1462
+ /* Allow access to the chunk header. */
1463
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1464
+
1465
+ if (MemoryChunkIsExternal(chunk))
1466
+ block = ExternalChunkGetBlock(chunk);
1467
+ else
1468
+ block = (AllocBlock) MemoryChunkGetBlock(chunk);
1469
+
1470
+ /* Disallow access to the chunk header. */
1471
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1472
+
1473
+ Assert(AllocBlockIsValid(block));
1474
+ set = block->aset;
1475
+
1476
+ return &set->header;
1477
+ }
1478
+
1317
1479
  /*
1318
1480
  * AllocSetGetChunkSpace
1319
1481
  * Given a currently-allocated chunk, determine the total space
1320
1482
  * it occupies (including all memory-allocation overhead).
1321
1483
  */
1322
- static Size
1323
- AllocSetGetChunkSpace(MemoryContext context, void *pointer)
1484
+ Size
1485
+ AllocSetGetChunkSpace(void *pointer)
1324
1486
  {
1325
- AllocChunk chunk = AllocPointerGetChunk(pointer);
1326
- Size result;
1487
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1488
+ int fidx;
1489
+
1490
+ /* Allow access to the chunk header. */
1491
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1492
+
1493
+ if (MemoryChunkIsExternal(chunk))
1494
+ {
1495
+ AllocBlock block = ExternalChunkGetBlock(chunk);
1327
1496
 
1328
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1329
- result = chunk->size + ALLOC_CHUNKHDRSZ;
1330
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1331
- return result;
1497
+ /* Disallow access to the chunk header. */
1498
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1499
+
1500
+ Assert(AllocBlockIsValid(block));
1501
+
1502
+ return block->endptr - (char *) chunk;
1503
+ }
1504
+
1505
+ fidx = MemoryChunkGetValue(chunk);
1506
+ Assert(FreeListIdxIsValid(fidx));
1507
+
1508
+ /* Disallow access to the chunk header. */
1509
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1510
+
1511
+ return GetChunkSizeFromFreeListIdx(fidx) + ALLOC_CHUNKHDRSZ;
1332
1512
  }
1333
1513
 
1334
1514
  /*
1335
1515
  * AllocSetIsEmpty
1336
1516
  * Is an allocset empty of any allocated space?
1337
1517
  */
1338
- static bool
1518
+ bool
1339
1519
  AllocSetIsEmpty(MemoryContext context)
1340
1520
  {
1521
+ Assert(AllocSetIsValid(context));
1522
+
1341
1523
  /*
1342
1524
  * For now, we say "empty" only if the context is new or just reset. We
1343
1525
  * could examine the freelists to determine if all space has been freed,
@@ -1356,11 +1538,12 @@ AllocSetIsEmpty(MemoryContext context)
1356
1538
  * printfunc: if not NULL, pass a human-readable stats string to this.
1357
1539
  * passthru: pass this pointer through to printfunc.
1358
1540
  * totals: if not NULL, add stats about this context into *totals.
1541
+ * print_to_stderr: print stats to stderr if true, elog otherwise.
1359
1542
  */
1360
- static void
1543
+ void
1361
1544
  AllocSetStats(MemoryContext context,
1362
1545
  MemoryStatsPrintFunc printfunc, void *passthru,
1363
- MemoryContextCounters *totals)
1546
+ MemoryContextCounters *totals, bool print_to_stderr)
1364
1547
  {
1365
1548
  AllocSet set = (AllocSet) context;
1366
1549
  Size nblocks = 0;
@@ -1370,6 +1553,8 @@ AllocSetStats(MemoryContext context,
1370
1553
  AllocBlock block;
1371
1554
  int fidx;
1372
1555
 
1556
+ Assert(AllocSetIsValid(set));
1557
+
1373
1558
  /* Include context header in totalspace */
1374
1559
  totalspace = MAXALIGN(sizeof(AllocSetContext));
1375
1560
 
@@ -1381,13 +1566,24 @@ AllocSetStats(MemoryContext context,
1381
1566
  }
1382
1567
  for (fidx = 0; fidx < ALLOCSET_NUM_FREELISTS; fidx++)
1383
1568
  {
1384
- AllocChunk chunk;
1569
+ Size chksz = GetChunkSizeFromFreeListIdx(fidx);
1570
+ MemoryChunk *chunk = set->freelist[fidx];
1385
1571
 
1386
- for (chunk = set->freelist[fidx]; chunk != NULL;
1387
- chunk = (AllocChunk) chunk->aset)
1572
+ while (chunk != NULL)
1388
1573
  {
1574
+ AllocFreeListLink *link = GetFreeListLink(chunk);
1575
+
1576
+ /* Allow access to the chunk header. */
1577
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1578
+ Assert(MemoryChunkGetValue(chunk) == fidx);
1579
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1580
+
1389
1581
  freechunks++;
1390
- freespace += chunk->size + ALLOC_CHUNKHDRSZ;
1582
+ freespace += chksz + ALLOC_CHUNKHDRSZ;
1583
+
1584
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
1585
+ chunk = link->next;
1586
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
1391
1587
  }
1392
1588
  }
1393
1589
 
@@ -1396,10 +1592,10 @@ AllocSetStats(MemoryContext context,
1396
1592
  char stats_string[200];
1397
1593
 
1398
1594
  snprintf(stats_string, sizeof(stats_string),
1399
- "%zu total in %zd blocks; %zu free (%zd chunks); %zu used",
1595
+ "%zu total in %zu blocks; %zu free (%zu chunks); %zu used",
1400
1596
  totalspace, nblocks, freespace, freechunks,
1401
1597
  totalspace - freespace);
1402
- printfunc(context, passthru, stats_string);
1598
+ printfunc(context, passthru, stats_string, print_to_stderr);
1403
1599
  }
1404
1600
 
1405
1601
  if (totals)
@@ -1422,7 +1618,7 @@ AllocSetStats(MemoryContext context,
1422
1618
  * find yourself in an infinite loop when trouble occurs, because this
1423
1619
  * routine will be entered again when elog cleanup tries to release memory!
1424
1620
  */
1425
- static void
1621
+ void
1426
1622
  AllocSetCheck(MemoryContext context)
1427
1623
  {
1428
1624
  AllocSet set = (AllocSet) context;
@@ -1439,8 +1635,9 @@ AllocSetCheck(MemoryContext context)
1439
1635
  long blk_used = block->freeptr - bpoz;
1440
1636
  long blk_data = 0;
1441
1637
  long nchunks = 0;
1638
+ bool has_external_chunk = false;
1442
1639
 
1443
- if (set->keeper == block)
1640
+ if (IsKeeperBlock(set, block))
1444
1641
  total_allocated += block->endptr - ((char *) set);
1445
1642
  else
1446
1643
  total_allocated += block->endptr - ((char *) block);
@@ -1450,7 +1647,7 @@ AllocSetCheck(MemoryContext context)
1450
1647
  */
1451
1648
  if (!blk_used)
1452
1649
  {
1453
- if (set->keeper != block)
1650
+ if (!IsKeeperBlock(set, block))
1454
1651
  elog(WARNING, "problem in alloc set %s: empty block %p",
1455
1652
  name, block);
1456
1653
  }
@@ -1470,56 +1667,64 @@ AllocSetCheck(MemoryContext context)
1470
1667
  */
1471
1668
  while (bpoz < block->freeptr)
1472
1669
  {
1473
- AllocChunk chunk = (AllocChunk) bpoz;
1670
+ MemoryChunk *chunk = (MemoryChunk *) bpoz;
1474
1671
  Size chsize,
1475
1672
  dsize;
1476
1673
 
1477
- /* Allow access to private part of chunk header. */
1478
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1674
+ /* Allow access to the chunk header. */
1675
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1676
+
1677
+ if (MemoryChunkIsExternal(chunk))
1678
+ {
1679
+ chsize = block->endptr - (char *) MemoryChunkGetPointer(chunk); /* aligned chunk size */
1680
+ has_external_chunk = true;
1681
+
1682
+ /* make sure this chunk consumes the entire block */
1683
+ if (chsize + ALLOC_CHUNKHDRSZ != blk_used)
1684
+ elog(WARNING, "problem in alloc set %s: bad single-chunk %p in block %p",
1685
+ name, chunk, block);
1686
+ }
1687
+ else
1688
+ {
1689
+ int fidx = MemoryChunkGetValue(chunk);
1690
+
1691
+ if (!FreeListIdxIsValid(fidx))
1692
+ elog(WARNING, "problem in alloc set %s: bad chunk size for chunk %p in block %p",
1693
+ name, chunk, block);
1694
+
1695
+ chsize = GetChunkSizeFromFreeListIdx(fidx); /* aligned chunk size */
1479
1696
 
1480
- chsize = chunk->size; /* aligned chunk size */
1697
+ /*
1698
+ * Check the stored block offset correctly references this
1699
+ * block.
1700
+ */
1701
+ if (block != MemoryChunkGetBlock(chunk))
1702
+ elog(WARNING, "problem in alloc set %s: bad block offset for chunk %p in block %p",
1703
+ name, chunk, block);
1704
+ }
1481
1705
  dsize = chunk->requested_size; /* real data */
1482
1706
 
1483
- /*
1484
- * Check chunk size
1485
- */
1486
- if (dsize > chsize)
1707
+ /* an allocated chunk's requested size must be <= the chsize */
1708
+ if (dsize != InvalidAllocSize && dsize > chsize)
1487
1709
  elog(WARNING, "problem in alloc set %s: req size > alloc size for chunk %p in block %p",
1488
1710
  name, chunk, block);
1711
+
1712
+ /* chsize must not be smaller than the first freelist's size */
1489
1713
  if (chsize < (1 << ALLOC_MINBITS))
1490
1714
  elog(WARNING, "problem in alloc set %s: bad size %zu for chunk %p in block %p",
1491
1715
  name, chsize, chunk, block);
1492
1716
 
1493
- /* single-chunk block? */
1494
- if (chsize > set->allocChunkLimit &&
1495
- chsize + ALLOC_CHUNKHDRSZ != blk_used)
1496
- elog(WARNING, "problem in alloc set %s: bad single-chunk %p in block %p",
1497
- name, chunk, block);
1498
-
1499
- /*
1500
- * If chunk is allocated, check for correct aset pointer. (If it's
1501
- * free, the aset is the freelist pointer, which we can't check as
1502
- * easily...) Note this is an incomplete test, since palloc(0)
1503
- * produces an allocated chunk with requested_size == 0.
1504
- */
1505
- if (dsize > 0 && chunk->aset != (void *) set)
1506
- elog(WARNING, "problem in alloc set %s: bogus aset link in block %p, chunk %p",
1507
- name, block, chunk);
1508
-
1509
1717
  /*
1510
1718
  * Check for overwrite of padding space in an allocated chunk.
1511
1719
  */
1512
- if (chunk->aset == (void *) set && dsize < chsize &&
1720
+ if (dsize != InvalidAllocSize && dsize < chsize &&
1513
1721
  !sentinel_ok(chunk, ALLOC_CHUNKHDRSZ + dsize))
1514
1722
  elog(WARNING, "problem in alloc set %s: detected write past chunk end in block %p, chunk %p",
1515
1723
  name, block, chunk);
1516
1724
 
1517
- /*
1518
- * If chunk is allocated, disallow external access to private part
1519
- * of chunk header.
1520
- */
1521
- if (chunk->aset == (void *) set)
1522
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1725
+ /* if chunk is allocated, disallow access to the chunk header */
1726
+ if (dsize != InvalidAllocSize)
1727
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1523
1728
 
1524
1729
  blk_data += chsize;
1525
1730
  nchunks++;
@@ -1530,6 +1735,10 @@ AllocSetCheck(MemoryContext context)
1530
1735
  if ((blk_data + (nchunks * ALLOC_CHUNKHDRSZ)) != blk_used)
1531
1736
  elog(WARNING, "problem in alloc set %s: found inconsistent memory block %p",
1532
1737
  name, block);
1738
+
1739
+ if (has_external_chunk && nchunks > 1)
1740
+ elog(WARNING, "problem in alloc set %s: external chunk on non-dedicated block %p",
1741
+ name, block);
1533
1742
  }
1534
1743
 
1535
1744
  Assert(total_allocated == context->mem_allocated);