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