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