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