From b4b8efbd3826ac0af2d1c2e7c40fcf80a4bfba45 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:18:03 +0200 Subject: Adding upstream version 15.6. Signed-off-by: Daniel Baumann --- src/include/access/genam.h | 1 + src/include/access/tableam.h | 4 +-- src/include/common/int.h | 6 ++++- src/include/jit/llvmjit.h | 8 ++++++ src/include/jit/llvmjit_emit.h | 30 ++++++++++++--------- src/include/mb/pg_wchar.h | 53 ------------------------------------- src/include/optimizer/optimizer.h | 2 ++ src/include/pg_config.h.in | 3 --- src/include/port/atomics/generic.h | 2 +- src/include/storage/buf_internals.h | 2 +- src/include/storage/lwlock.h | 8 ++++++ src/include/storage/proc.h | 2 +- src/include/utils/ascii.h | 52 ++++++++++++++++++++++++++++++++++++ src/include/utils/wait_event.h | 3 ++- 14 files changed, 101 insertions(+), 75 deletions(-) (limited to 'src/include') diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 134b20f..f6ad7c3 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -138,6 +138,7 @@ typedef struct IndexOrderByDistance #define IndexScanIsValid(scan) PointerIsValid(scan) extern Relation index_open(Oid relationId, LOCKMODE lockmode); +extern Relation try_index_open(Oid relationId, LOCKMODE lockmode); extern void index_close(Relation relation, LOCKMODE lockmode); extern bool index_insert(Relation indexRelation, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index fe869c6..5d0431a 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -1455,8 +1455,8 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, * TM_BeingModified (the last only possible if wait == false). * * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, - * t_xmax, and, if possible, and, if possible, t_cmax. See comments for - * struct TM_FailureData for additional info. + * t_xmax, and, if possible, t_cmax. See comments for struct + * TM_FailureData for additional info. */ static inline TM_Result table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, diff --git a/src/include/common/int.h b/src/include/common/int.h index 12a269d..e2617fb 100644 --- a/src/include/common/int.h +++ b/src/include/common/int.h @@ -200,8 +200,12 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result) *result = (int64) res; return false; #else + /* + * Note: overflow is also possible when a == 0 and b < 0 (specifically, + * when b == PG_INT64_MIN). + */ if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) || - (a > 0 && b < 0 && a > PG_INT64_MAX + b)) + (a >= 0 && b < 0 && a > PG_INT64_MAX + b)) { *result = 0x5EED; /* to avoid spurious warnings */ return true; diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h index fe769e0..08fac9e 100644 --- a/src/include/jit/llvmjit.h +++ b/src/include/jit/llvmjit.h @@ -42,6 +42,13 @@ typedef struct LLVMJitContext /* number of modules created */ size_t module_generation; + /* + * The LLVM Context used by this JIT context. An LLVM context is reused + * across many compilations, but occasionally reset to prevent it using + * too much memory due to more and more types accumulating. + */ + LLVMContextRef llvm_context; + /* current, "open for write", module */ LLVMModuleRef module; @@ -107,6 +114,7 @@ extern LLVMValueRef llvm_function_reference(LLVMJitContext *context, LLVMModuleRef mod, FunctionCallInfo fcinfo); +extern void llvm_inline_reset_caches(void); extern void llvm_inline(LLVMModuleRef mod); /* diff --git a/src/include/jit/llvmjit_emit.h b/src/include/jit/llvmjit_emit.h index 27a080b..0a0f876 100644 --- a/src/include/jit/llvmjit_emit.h +++ b/src/include/jit/llvmjit_emit.h @@ -45,36 +45,36 @@ l_ptr(LLVMTypeRef t) * Emit constant integer. */ static inline LLVMValueRef -l_int8_const(int8 i) +l_int8_const(LLVMContextRef lc, int8 i) { - return LLVMConstInt(LLVMInt8Type(), i, false); + return LLVMConstInt(LLVMInt8TypeInContext(lc), i, false); } /* * Emit constant integer. */ static inline LLVMValueRef -l_int16_const(int16 i) +l_int16_const(LLVMContextRef lc, int16 i) { - return LLVMConstInt(LLVMInt16Type(), i, false); + return LLVMConstInt(LLVMInt16TypeInContext(lc), i, false); } /* * Emit constant integer. */ static inline LLVMValueRef -l_int32_const(int32 i) +l_int32_const(LLVMContextRef lc, int32 i) { - return LLVMConstInt(LLVMInt32Type(), i, false); + return LLVMConstInt(LLVMInt32TypeInContext(lc), i, false); } /* * Emit constant integer. */ static inline LLVMValueRef -l_int64_const(int64 i) +l_int64_const(LLVMContextRef lc, int64 i) { - return LLVMConstInt(LLVMInt64Type(), i, false); + return LLVMConstInt(LLVMInt64TypeInContext(lc), i, false); } /* @@ -177,12 +177,15 @@ l_bb_before_v(LLVMBasicBlockRef r, const char *fmt,...) { char buf[512]; va_list args; + LLVMContextRef lc; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - return LLVMInsertBasicBlock(r, buf); + lc = LLVMGetTypeContext(LLVMTypeOf(LLVMGetBasicBlockParent(r))); + + return LLVMInsertBasicBlockInContext(lc, r, buf); } /* separate, because pg_attribute_printf(2, 3) can't appear in definition */ @@ -197,12 +200,15 @@ l_bb_append_v(LLVMValueRef f, const char *fmt,...) { char buf[512]; va_list args; + LLVMContextRef lc; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - return LLVMAppendBasicBlock(f, buf); + lc = LLVMGetTypeContext(LLVMTypeOf(f)); + + return LLVMAppendBasicBlockInContext(lc, f, buf); } /* @@ -214,7 +220,7 @@ l_callsite_ro(LLVMValueRef f) const char argname[] = "readonly"; LLVMAttributeRef ref; - ref = LLVMCreateStringAttribute(LLVMGetGlobalContext(), + ref = LLVMCreateStringAttribute(LLVMGetTypeContext(LLVMTypeOf(f)), argname, sizeof(argname) - 1, NULL, 0); @@ -234,7 +240,7 @@ l_callsite_alwaysinline(LLVMValueRef f) id = LLVMGetEnumAttributeKindForName(argname, sizeof(argname) - 1); - attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), id, 0); + attr = LLVMCreateEnumAttribute(LLVMGetTypeContext(LLVMTypeOf(f)), id, 0); LLVMAddCallSiteAttribute(f, LLVMAttributeFunctionIndex, attr); } diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h index 31f5b39..4a0e6bf 100644 --- a/src/include/mb/pg_wchar.h +++ b/src/include/mb/pg_wchar.h @@ -699,57 +699,4 @@ extern int mic2latin_with_table(const unsigned char *mic, unsigned char *p, extern WCHAR *pgwin32_message_to_UTF16(const char *str, int len, int *utf16len); #endif - -/* - * Verify a chunk of bytes for valid ASCII. - * - * Returns false if the input contains any zero bytes or bytes with the - * high-bit set. Input len must be a multiple of 8. - */ -static inline bool -is_valid_ascii(const unsigned char *s, int len) -{ - uint64 chunk, - highbit_cum = UINT64CONST(0), - zero_cum = UINT64CONST(0x8080808080808080); - - Assert(len % sizeof(chunk) == 0); - - while (len > 0) - { - memcpy(&chunk, s, sizeof(chunk)); - - /* - * Capture any zero bytes in this chunk. - * - * First, add 0x7f to each byte. This sets the high bit in each byte, - * unless it was a zero. If any resulting high bits are zero, the - * corresponding high bits in the zero accumulator will be cleared. - * - * If none of the bytes in the chunk had the high bit set, the max - * value each byte can have after the addition is 0x7f + 0x7f = 0xfe, - * and we don't need to worry about carrying over to the next byte. If - * any input bytes did have the high bit set, it doesn't matter - * because we check for those separately. - */ - zero_cum &= (chunk + UINT64CONST(0x7f7f7f7f7f7f7f7f)); - - /* Capture any set bits in this chunk. */ - highbit_cum |= chunk; - - s += sizeof(chunk); - len -= sizeof(chunk); - } - - /* Check if any high bits in the high bit accumulator got set. */ - if (highbit_cum & UINT64CONST(0x8080808080808080)) - return false; - - /* Check if any high bits in the zero accumulator got cleared. */ - if (zero_cum != UINT64CONST(0x8080808080808080)) - return false; - - return true; -} - #endif /* PG_WCHAR_H */ diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h index 409005b..7b2a0e0 100644 --- a/src/include/optimizer/optimizer.h +++ b/src/include/optimizer/optimizer.h @@ -138,7 +138,9 @@ extern Expr *canonicalize_qual(Expr *qual, bool is_check); /* in util/clauses.c: */ extern bool contain_mutable_functions(Node *clause); +extern bool contain_mutable_functions_after_planning(Expr *expr); extern bool contain_volatile_functions(Node *clause); +extern bool contain_volatile_functions_after_planning(Expr *expr); extern bool contain_volatile_functions_not_nextval(Node *clause); extern Node *eval_const_expressions(PlannerInfo *root, Node *node); diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index d09e9f9..768e3d7 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -77,9 +77,6 @@ /* Define to 1 if you have the `backtrace_symbols' function. */ #undef HAVE_BACKTRACE_SYMBOLS -/* Define to 1 if you have the `BIO_get_data' function. */ -#undef HAVE_BIO_GET_DATA - /* Define to 1 if you have the `BIO_meth_new' function. */ #undef HAVE_BIO_METH_NEW diff --git a/src/include/port/atomics/generic.h b/src/include/port/atomics/generic.h index a1f2456..d62428a 100644 --- a/src/include/port/atomics/generic.h +++ b/src/include/port/atomics/generic.h @@ -83,7 +83,7 @@ pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr) static inline bool pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr) { - return pg_atomic_exchange_u32_impl(ptr, &value, 1) == 0; + return pg_atomic_exchange_u32_impl(ptr, 1) == 0; } #define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index a17e7b2..dbb0aef 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -150,7 +150,7 @@ typedef struct buftag * is held. Thus buffer header lock holder can do complex updates of the * state variable in single write, simultaneously with lock release (cleaning * BM_LOCKED flag). On the other hand, updating of state without holding - * buffer header lock is restricted to CAS, which insure that BM_LOCKED flag + * buffer header lock is restricted to CAS, which ensures that BM_LOCKED flag * is not set. Atomic increment/decrement, OR/AND etc. are not allowed. * * An exception is that if we have the buffer pinned, its tag can't change diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index e03d317..d88fa4b 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -23,6 +23,14 @@ struct PGPROC; +/* what state of the wait process is a backend in */ +typedef enum LWLockWaitState +{ + LW_WS_NOT_WAITING, /* not currently waiting / woken up */ + LW_WS_WAITING, /* currently waiting */ + LW_WS_PENDING_WAKEUP /* removed from waitlist, but not yet signalled */ +} LWLockWaitState; + /* * Code outside of lwlock.c should not manipulate the contents of this * structure directly, but we have to declare it here to allow LWLocks to be diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 2579e61..2ea7730 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -211,7 +211,7 @@ struct PGPROC bool recoveryConflictPending; /* Info about LWLock the process is currently waiting for, if any. */ - bool lwWaiting; /* true if waiting for an LW lock */ + uint8 lwWaiting; /* see LWLockWaitState */ uint8 lwWaitMode; /* lwlock mode being waited for */ proclist_node lwWaitLink; /* position in LW lock wait list */ diff --git a/src/include/utils/ascii.h b/src/include/utils/ascii.h index aed8019..4e3a1d4 100644 --- a/src/include/utils/ascii.h +++ b/src/include/utils/ascii.h @@ -13,4 +13,56 @@ extern void ascii_safe_strlcpy(char *dest, const char *src, size_t destsiz); +/* + * Verify a chunk of bytes for valid ASCII. + * + * Returns false if the input contains any zero bytes or bytes with the + * high-bit set. Input len must be a multiple of 8. + */ +static inline bool +is_valid_ascii(const unsigned char *s, int len) +{ + uint64 chunk, + highbit_cum = UINT64CONST(0), + zero_cum = UINT64CONST(0x8080808080808080); + + Assert(len % sizeof(chunk) == 0); + + while (len > 0) + { + memcpy(&chunk, s, sizeof(chunk)); + + /* + * Capture any zero bytes in this chunk. + * + * First, add 0x7f to each byte. This sets the high bit in each byte, + * unless it was a zero. If any resulting high bits are zero, the + * corresponding high bits in the zero accumulator will be cleared. + * + * If none of the bytes in the chunk had the high bit set, the max + * value each byte can have after the addition is 0x7f + 0x7f = 0xfe, + * and we don't need to worry about carrying over to the next byte. If + * any input bytes did have the high bit set, it doesn't matter + * because we check for those separately. + */ + zero_cum &= (chunk + UINT64CONST(0x7f7f7f7f7f7f7f7f)); + + /* Capture any set bits in this chunk. */ + highbit_cum |= chunk; + + s += sizeof(chunk); + len -= sizeof(chunk); + } + + /* Check if any high bits in the high bit accumulator got set. */ + if (highbit_cum & UINT64CONST(0x8080808080808080)) + return false; + + /* Check if any high bits in the zero accumulator got cleared. */ + if (zero_cum != UINT64CONST(0x8080808080808080)) + return false; + + return true; +} + #endif /* _ASCII_H_ */ diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h index b578e2e..c814918 100644 --- a/src/include/utils/wait_event.h +++ b/src/include/utils/wait_event.h @@ -229,7 +229,8 @@ typedef enum WAIT_EVENT_WAL_READ, WAIT_EVENT_WAL_SYNC, WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN, - WAIT_EVENT_WAL_WRITE + WAIT_EVENT_WAL_WRITE, + WAIT_EVENT_VERSION_FILE_SYNC } WaitEventIO; -- cgit v1.2.3