0000000000001bb0 : { 1bb0: f3 0f 1e fa endbr64 1bb4: 41 57 push r15 1bb6: 49 89 fb mov r11,rdi 1bb9: 41 56 push r14 1bbb: 41 55 push r13 1bbd: 41 54 push r12 1bbf: 4c 63 e6 movsxd r12,esi 1bc2: 55 push rbp 1bc3: 53 push rbx HeapTupleHeader tup = tuple->t_data; 1bc4: 48 8b 47 40 mov rax,QWORD PTR [rdi+0x40] TupleDesc tupleDesc = slot->tts_tupleDescriptor; 1bc8: 48 8b 57 10 mov rdx,QWORD PTR [rdi+0x10] isnull = slot->tts_isnull; 1bcc: 48 8b 4f 20 mov rcx,QWORD PTR [rdi+0x20] HeapTupleHeader tup = tuple->t_data; 1bd0: 48 8b 58 10 mov rbx,QWORD PTR [rax+0x10] if (TTS_OBEYS_NOT_NULL_CONSTRAINTS(slot)) 1bd4: f6 47 04 08 test BYTE PTR [rdi+0x4],0x8 1bd8: 0f 84 02 04 00 00 je 1fe0 firstNonGuaranteedAttr = Min(reqnatts, tupleDesc->firstNonGuaranteedAttr); 1bde: 8b 42 14 mov eax,DWORD PTR [rdx+0x14] 1be1: 41 39 c4 cmp r12d,eax 1be4: 41 0f 4e c4 cmovle eax,r12d if (attnum < firstNonGuaranteedAttr) 1be8: 48 63 e8 movsxd rbp,eax firstNonCacheOffsetAttr = tupleDesc->firstNonCachedOffsetAttr; 1beb: 4c 63 52 10 movsxd r10,DWORD PTR [rdx+0x10] if (HeapTupleHasNulls(tuple)) 1bef: f6 43 14 01 test BYTE PTR [rbx+0x14],0x1 1bf3: 0f 84 b7 03 00 00 je 1fb0 natts = HeapTupleHeaderGetNatts(tup); 1bf9: 44 0f b7 4b 12 movzx r9d,WORD PTR [rbx+0x12] 1bfe: 41 81 e1 ff 07 00 00 and r9d,0x7ff * Computes size of null bitmap given number of data columns. */ static inline int BITMAPLEN(int NATTS) { return (NATTS + 7) / 8; 1c05: 45 8d 41 07 lea r8d,[r9+0x7] 1c09: 41 c1 f8 03 sar r8d,0x3 tp = (char *) tup + MAXALIGN(offsetof(HeapTupleHeaderData, t_bits) + 1c0d: 41 83 c0 1e add r8d,0x1e 1c11: 41 81 e0 f8 03 00 00 and r8d,0x3f8 1c18: 49 01 d8 add r8,rbx natts = Min(natts, reqnatts); 1c1b: 45 39 cc cmp r12d,r9d 1c1e: 4d 0f 4e cc cmovle r9,r12 firstNullAttr = natts; 1c22: 45 89 ce mov r14d,r9d if (natts > firstNonGuaranteedAttr) 1c25: 41 39 c1 cmp r9d,eax 1c28: 0f 8f ea 04 00 00 jg 2118 attnum = slot->tts_nvalid; 1c2e: 49 0f bf 43 06 movsx rax,WORD PTR [r11+0x6] values = slot->tts_values; 1c33: 49 8b 7b 18 mov rdi,QWORD PTR [r11+0x18] slot->tts_nvalid = reqnatts; 1c37: 66 45 89 63 06 mov WORD PTR [r11+0x6],r12w if (attnum < firstNonGuaranteedAttr) 1c3c: 48 39 e8 cmp rax,rbp 1c3f: 73 7f jae 1cc0 1c41: 48 89 54 24 f0 mov QWORD PTR [rsp-0x10],rdx 1c46: 48 8d 74 c2 20 lea rsi,[rdx+rax*8+0x20] 1c4b: eb 22 jmp 1c6f 1c4d: 0f 1f 00 nop DWORD PTR [rax] static inline Datum fetch_att_noerr(const void *T, bool attbyval, int attlen) { if (attbyval) { switch (attlen) 1c50: 66 41 83 ff 01 cmp r15w,0x1 1c55: 74 59 je 1cb0 * Returns datum representation for a 64-bit integer. */ static inline Datum Int64GetDatum(int64 X) { return (Datum) X; 1c57: 48 8b 12 mov rdx,QWORD PTR [rdx] values[attnum] = fetch_att_noerr(tp + off, true, attlen); 1c5a: 48 89 14 c7 mov QWORD PTR [rdi+rax*8],rdx attnum++; 1c5e: 48 83 c0 01 add rax,0x1 } while (attnum < firstNonGuaranteedAttr); 1c62: 48 83 c6 08 add rsi,0x8 1c66: 48 39 e8 cmp rax,rbp 1c69: 0f 83 11 03 00 00 jae 1f80 isnull[attnum] = false; 1c6f: c6 04 01 00 mov BYTE PTR [rcx+rax*1],0x0 off = cattr->attcacheoff; 1c73: 0f bf 16 movsx edx,WORD PTR [rsi] cattr = &cattrs[attnum]; 1c76: 49 89 f5 mov r13,rsi attlen = cattr->attlen; 1c79: 44 0f b7 7e 02 movzx r15d,WORD PTR [rsi+0x2] off = cattr->attcacheoff; 1c7e: 48 89 d3 mov rbx,rdx values[attnum] = fetch_att_noerr(tp + off, true, attlen); 1c81: 4c 01 c2 add rdx,r8 1c84: 66 41 83 ff 02 cmp r15w,0x2 1c89: 74 15 je 1ca0 1c8b: 66 41 83 ff 04 cmp r15w,0x4 1c90: 75 be jne 1c50 return (Datum) X; 1c92: 48 63 12 movsxd rdx,DWORD PTR [rdx] { case sizeof(int32): return Int32GetDatum(*((const int32 *) T)); 1c95: eb c3 jmp 1c5a 1c97: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0] 1c9e: 00 00 return (Datum) X; 1ca0: 48 0f bf 12 movsx rdx,WORD PTR [rdx] case sizeof(int16): return Int16GetDatum(*((const int16 *) T)); 1ca4: eb b4 jmp 1c5a 1ca6: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0] 1cad: 00 00 00 return (Datum) X; 1cb0: 48 0f be 12 movsx rdx,BYTE PTR [rdx] case sizeof(char): return CharGetDatum(*((const char *) T)); 1cb4: eb a4 jmp 1c5a 1cb6: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0] 1cbd: 00 00 00 off = *offp; 1cc0: 41 8b 5b 48 mov ebx,DWORD PTR [r11+0x48] if (unlikely(attnum < reqnatts)) 1cc4: 49 63 ec movsxd rbp,r12d firstNonCacheOffsetAttr = Min(firstNonCacheOffsetAttr, natts); 1cc7: 45 39 ca cmp r10d,r9d 1cca: 4d 0f 4f d1 cmovg r10,r9 if (attnum < firstNonCacheOffsetAttr) 1cce: 4c 39 d0 cmp rax,r10 1cd1: 0f 82 b9 01 00 00 jb 1e90 for (; attnum < firstNullAttr; attnum++) 1cd7: 4d 63 d6 movsxd r10,r14d 1cda: 4c 39 d0 cmp rax,r10 1cdd: 72 5e jb 1d3d 1cdf: e9 24 05 00 00 jmp 2208 1ce4: 0f 1f 40 00 nop DWORD PTR [rax+0x0] if (attlen > 0) { const char *offset_ptr; *off = TYPEALIGN(attalignby, *off); 1ce8: 8d 5c 1e ff lea ebx,[rsi+rbx*1-0x1] 1cec: f7 de neg esi 1cee: 21 de and esi,ebx offset_ptr = tupptr + *off; *off += attlen; 1cf0: 41 0f bf dd movsx ebx,r13w offset_ptr = tupptr + *off; 1cf4: 41 89 f6 mov r14d,esi *off += attlen; 1cf7: 01 f3 add ebx,esi offset_ptr = tupptr + *off; 1cf9: 4d 01 c6 add r14,r8 return (Datum) (uintptr_t) X; 1cfc: 4c 89 f6 mov rsi,r14 if (attbyval) 1cff: 80 7c c2 24 00 cmp BYTE PTR [rdx+rax*8+0x24],0x0 1d04: 74 2a je 1d30 { switch (attlen) 1d06: 66 41 83 fd 02 cmp r13w,0x2 1d0b: 0f 84 ef 01 00 00 je 1f00 1d11: 66 41 83 fd 04 cmp r13w,0x4 1d16: 0f 84 d4 01 00 00 je 1ef0 1d1c: 66 41 83 fd 01 cmp r13w,0x1 1d21: 0f 85 b9 01 00 00 jne 1ee0 return (Datum) X; 1d27: 49 0f be 36 movsx rsi,BYTE PTR [r14] 1d2b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] values[attnum] = align_fetch_then_add(tp, 1d30: 48 89 34 c7 mov QWORD PTR [rdi+rax*8],rsi for (; attnum < firstNullAttr; attnum++) 1d34: 48 83 c0 01 add rax,0x1 1d38: 4c 39 d0 cmp rax,r10 1d3b: 74 73 je 1db0 isnull[attnum] = false; 1d3d: c6 04 01 00 mov BYTE PTR [rcx+rax*1],0x0 attlen = cattr->attlen; 1d41: 44 0f b7 6c c2 22 movzx r13d,WORD PTR [rdx+rax*8+0x22] cattr->attalignby); 1d47: 0f b6 74 c2 25 movzx esi,BYTE PTR [rdx+rax*8+0x25] if (attlen > 0) 1d4c: 66 45 85 ed test r13w,r13w 1d50: 7f 96 jg 1ce8 } return PointerGetDatum(offset_ptr); } else if (attlen == -1) { if (!VARATT_IS_SHORT(tupptr + *off)) 1d52: 41 89 dd mov r13d,ebx 1d55: 4d 01 c5 add r13,r8 1d58: 41 f6 45 00 01 test BYTE PTR [r13+0x0],0x1 1d5d: 75 0e jne 1d6d *off = TYPEALIGN(attalignby, *off); 1d5f: 8d 5c 1e ff lea ebx,[rsi+rbx*1-0x1] 1d63: f7 de neg esi 1d65: 21 f3 and ebx,esi res = PointerGetDatum(tupptr + *off); 1d67: 41 89 dd mov r13d,ebx 1d6a: 4d 01 c5 add r13,r8 if (VARATT_IS_1B_E(PTR)) 1d6d: 45 0f b6 75 00 movzx r14d,BYTE PTR [r13+0x0] return (Datum) (uintptr_t) X; 1d72: 4c 89 ee mov rsi,r13 1d75: 41 80 fe 01 cmp r14b,0x1 1d79: 0f 84 59 03 00 00 je 20d8 else if (VARATT_IS_1B(PTR)) 1d7f: 41 f6 c6 01 test r14b,0x1 1d83: 0f 85 87 02 00 00 jne 2010 return VARSIZE_4B(PTR); 1d89: 45 8b 75 00 mov r14d,DWORD PTR [r13+0x0] 1d8d: 41 c1 ee 02 shr r14d,0x2 values[attnum] = align_fetch_then_add(tp, 1d91: 48 89 34 c7 mov QWORD PTR [rdi+rax*8],rsi for (; attnum < firstNullAttr; attnum++) 1d95: 48 83 c0 01 add rax,0x1 *off += VARSIZE_ANY(DatumGetPointer(res)); 1d99: 44 01 f3 add ebx,r14d 1d9c: 4c 39 d0 cmp rax,r10 1d9f: 75 9c jne 1d3d 1da1: 0f 1f 40 00 nop DWORD PTR [rax+0x0] 1da5: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 1dac: 00 00 00 00 for (; attnum < natts; attnum++) 1db0: 4d 39 ca cmp r10,r9 1db3: 0f 83 57 04 00 00 jae 2210 1db9: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] if (isnull[attnum]) 1dc0: 31 c0 xor eax,eax 1dc2: 42 80 3c 11 00 cmp BYTE PTR [rcx+r10*1],0x0 1dc7: 75 57 jne 1e20 attlen = cattr->attlen; 1dc9: 42 0f b7 74 d2 22 movzx esi,WORD PTR [rdx+r10*8+0x22] cattr->attalignby); 1dcf: 42 0f b6 44 d2 25 movzx eax,BYTE PTR [rdx+r10*8+0x25] if (attlen > 0) 1dd5: 66 85 f6 test si,si 1dd8: 0f 8e 32 01 00 00 jle 1f10 *off = TYPEALIGN(attalignby, *off); 1dde: 8d 5c 18 ff lea ebx,[rax+rbx*1-0x1] 1de2: f7 d8 neg eax 1de4: 21 d8 and eax,ebx *off += attlen; 1de6: 0f bf de movsx ebx,si offset_ptr = tupptr + *off; 1de9: 41 89 c5 mov r13d,eax *off += attlen; 1dec: 01 c3 add ebx,eax offset_ptr = tupptr + *off; 1dee: 4d 01 c5 add r13,r8 1df1: 4c 89 e8 mov rax,r13 if (attbyval) 1df4: 42 80 7c d2 24 00 cmp BYTE PTR [rdx+r10*8+0x24],0x0 1dfa: 74 24 je 1e20 switch (attlen) 1dfc: 66 83 fe 02 cmp si,0x2 1e00: 0f 84 b2 02 00 00 je 20b8 1e06: 66 83 fe 04 cmp si,0x4 1e0a: 0f 84 88 02 00 00 je 2098 1e10: 66 83 fe 01 cmp si,0x1 1e14: 0f 84 d6 01 00 00 je 1ff0 return (Datum) X; 1e1a: 49 8b 45 00 mov rax,QWORD PTR [r13+0x0] 1e1e: 66 90 xchg ax,ax values[attnum] = (Datum) 0; 1e20: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 1e24: 49 83 c2 01 add r10,0x1 1e28: 4d 39 ca cmp r10,r9 1e2b: 75 93 jne 1dc0 if (unlikely(attnum < reqnatts)) 1e2d: 49 39 e9 cmp r9,rbp 1e30: 0f 82 ea 03 00 00 jb 2220 *offp = off; 1e36: 41 89 5b 48 mov DWORD PTR [r11+0x48],ebx } 1e3a: 5b pop rbx 1e3b: 5d pop rbp 1e3c: 41 5c pop r12 1e3e: 41 5d pop r13 1e40: 41 5e pop r14 1e42: 41 5f pop r15 1e44: c3 ret 1e45: 0f 1f 00 nop DWORD PTR [rax] switch (attlen) 1e48: 66 83 fb 01 cmp bx,0x1 1e4c: 0f 84 0e 01 00 00 je 1f60 1e52: 48 8b 1e mov rbx,QWORD PTR [rsi] 1e55: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0] 1e5c: 00 00 00 1e5f: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 1e66: 00 00 00 00 1e6a: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 1e71: 00 00 00 00 1e75: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 1e7c: 00 00 00 00 } while (++attnum < firstNonCacheOffsetAttr); 1e80: 48 8d 70 01 lea rsi,[rax+0x1] values[attnum] = fetch_att_noerr(tp + off, 1e84: 48 89 1c c7 mov QWORD PTR [rdi+rax*8],rbx } while (++attnum < firstNonCacheOffsetAttr); 1e88: 49 39 f2 cmp r10,rsi 1e8b: 74 43 je 1ed0 1e8d: 48 89 f0 mov rax,rsi isnull[attnum] = false; 1e90: c6 04 01 00 mov BYTE PTR [rcx+rax*1],0x0 off = cattr->attcacheoff; 1e94: 0f bf 74 c2 20 movsx esi,WORD PTR [rdx+rax*8+0x20] 1e99: 49 89 f5 mov r13,rsi values[attnum] = fetch_att_noerr(tp + off, 1e9c: 4c 01 c6 add rsi,r8 return (Datum) (uintptr_t) X; 1e9f: 48 89 f3 mov rbx,rsi if (attbyval) 1ea2: 80 7c c2 24 00 cmp BYTE PTR [rdx+rax*8+0x24],0x0 1ea7: 74 d7 je 1e80 cattr->attlen); 1ea9: 0f b7 5c c2 22 movzx ebx,WORD PTR [rdx+rax*8+0x22] switch (attlen) 1eae: 66 83 fb 02 cmp bx,0x2 1eb2: 0f 84 b8 00 00 00 je 1f70 1eb8: 66 83 fb 04 cmp bx,0x4 1ebc: 75 8a jne 1e48 return (Datum) X; 1ebe: 48 63 1e movsxd rbx,DWORD PTR [rsi] } while (++attnum < firstNonCacheOffsetAttr); 1ec1: 48 8d 70 01 lea rsi,[rax+0x1] values[attnum] = fetch_att_noerr(tp + off, 1ec5: 48 89 1c c7 mov QWORD PTR [rdi+rax*8],rbx } while (++attnum < firstNonCacheOffsetAttr); 1ec9: 49 39 f2 cmp r10,rsi 1ecc: 75 bf jne 1e8d 1ece: 66 90 xchg ax,ax off += cattr->attlen; 1ed0: 0f bf 5c c2 22 movsx ebx,WORD PTR [rdx+rax*8+0x22] } while (++attnum < firstNonCacheOffsetAttr); 1ed5: 4c 89 d0 mov rax,r10 off += cattr->attlen; 1ed8: 44 01 eb add ebx,r13d 1edb: e9 f7 fd ff ff jmp 1cd7 return (Datum) X; 1ee0: 49 8b 36 mov rsi,QWORD PTR [r14] return Int64GetDatum(*((const int64 *) offset_ptr)); 1ee3: e9 48 fe ff ff jmp 1d30 1ee8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 1eef: 00 return (Datum) X; 1ef0: 49 63 36 movsxd rsi,DWORD PTR [r14] return Int32GetDatum(*((const int32 *) offset_ptr)); 1ef3: e9 38 fe ff ff jmp 1d30 1ef8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 1eff: 00 return (Datum) X; 1f00: 49 0f bf 36 movsx rsi,WORD PTR [r14] return Int16GetDatum(*((const int16 *) offset_ptr)); 1f04: e9 27 fe ff ff jmp 1d30 1f09: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] if (!VARATT_IS_SHORT(tupptr + *off)) 1f10: 89 de mov esi,ebx 1f12: 4c 01 c6 add rsi,r8 1f15: f6 06 01 test BYTE PTR [rsi],0x1 1f18: 0f 84 02 01 00 00 je 2020 if (VARATT_IS_1B_E(PTR)) 1f1e: 44 0f b6 2e movzx r13d,BYTE PTR [rsi] return (Datum) (uintptr_t) X; 1f22: 48 89 f0 mov rax,rsi 1f25: 41 80 fd 01 cmp r13b,0x1 1f29: 0f 84 0f 01 00 00 je 203e else if (VARATT_IS_1B(PTR)) 1f2f: 41 f6 c5 01 test r13b,0x1 1f33: 0f 84 3f 01 00 00 je 2078 return VARSIZE_1B(PTR); 1f39: 41 d0 ed shr r13b,1 *off += VARSIZE_ANY(DatumGetPointer(res)); 1f3c: 45 0f b6 ed movzx r13d,r13b values[attnum] = (Datum) 0; 1f40: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 1f44: 49 83 c2 01 add r10,0x1 1f48: 44 01 eb add ebx,r13d 1f4b: 4d 39 ca cmp r10,r9 1f4e: 0f 85 6c fe ff ff jne 1dc0 1f54: e9 d4 fe ff ff jmp 1e2d 1f59: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] return (Datum) X; 1f60: 48 0f be 1e movsx rbx,BYTE PTR [rsi] return CharGetDatum(*((const char *) T)); 1f64: e9 17 ff ff ff jmp 1e80 1f69: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] return (Datum) X; 1f70: 48 0f bf 1e movsx rbx,WORD PTR [rsi] return Int16GetDatum(*((const int16 *) T)); 1f74: e9 07 ff ff ff jmp 1e80 1f79: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] off += cattr->attlen; 1f80: 41 0f bf 75 02 movsx esi,WORD PTR [r13+0x2] if (attnum == reqnatts) 1f85: 49 63 ec movsxd rbp,r12d off += cattr->attlen; 1f88: 48 8b 54 24 f0 mov rdx,QWORD PTR [rsp-0x10] 1f8d: 01 f3 add ebx,esi if (attnum == reqnatts) 1f8f: 48 39 e8 cmp rax,rbp 1f92: 0f 85 2f fd ff ff jne 1cc7 *offp = off; 1f98: 41 89 5b 48 mov DWORD PTR [r11+0x48],ebx } 1f9c: 5b pop rbx 1f9d: 5d pop rbp 1f9e: 41 5c pop r12 1fa0: 41 5d pop r13 1fa2: 41 5e pop r14 1fa4: 41 5f pop r15 1fa6: c3 ret 1fa7: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0] 1fae: 00 00 tp = (char *) tup + MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)); 1fb0: 4c 8d 43 18 lea r8,[rbx+0x18] if (reqnatts > firstNonGuaranteedAttr) 1fb4: 41 39 c4 cmp r12d,eax 1fb7: 0f 8e cb 00 00 00 jle 2088 natts = Min(HeapTupleHeaderGetNatts(tup), reqnatts); 1fbd: 0f b7 43 12 movzx eax,WORD PTR [rbx+0x12] 1fc1: 25 ff 07 00 00 and eax,0x7ff 1fc6: 44 39 e0 cmp eax,r12d 1fc9: 41 0f 4f c4 cmovg eax,r12d 1fcd: 41 89 c6 mov r14d,eax 1fd0: 4c 63 c8 movsxd r9,eax 1fd3: e9 56 fc ff ff jmp 1c2e 1fd8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 1fdf: 00 1fe0: 31 ed xor ebp,ebp firstNonGuaranteedAttr = 0; 1fe2: 31 c0 xor eax,eax 1fe4: e9 02 fc ff ff jmp 1beb 1fe9: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] return (Datum) X; 1ff0: 49 0f be 45 00 movsx rax,BYTE PTR [r13+0x0] values[attnum] = (Datum) 0; 1ff5: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 1ff9: 49 83 c2 01 add r10,0x1 1ffd: 4d 39 ca cmp r10,r9 2000: 0f 85 ba fd ff ff jne 1dc0 2006: e9 22 fe ff ff jmp 1e2d 200b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] 2010: 41 d0 ee shr r14b,1 *off += VARSIZE_ANY(DatumGetPointer(res)); 2013: 45 0f b6 f6 movzx r14d,r14b 2017: e9 75 fd ff ff jmp 1d91 201c: 0f 1f 40 00 nop DWORD PTR [rax+0x0] *off = TYPEALIGN(attalignby, *off); 2020: 8d 5c 18 ff lea ebx,[rax+rbx*1-0x1] 2024: f7 d8 neg eax 2026: 21 c3 and ebx,eax res = PointerGetDatum(tupptr + *off); 2028: 89 de mov esi,ebx 202a: 4c 01 c6 add rsi,r8 if (VARATT_IS_1B_E(PTR)) 202d: 44 0f b6 2e movzx r13d,BYTE PTR [rsi] return (Datum) (uintptr_t) X; 2031: 48 89 f0 mov rax,rsi 2034: 41 80 fd 01 cmp r13b,0x1 2038: 0f 85 f1 fe ff ff jne 1f2f return VARTAG_1B_E(PTR); 203e: 0f b6 76 01 movzx esi,BYTE PTR [rsi+0x1] if (tag == VARTAG_INDIRECT) 2042: 83 fe 01 cmp esi,0x1 2045: 0f 84 12 02 00 00 je 225d return ((tag & ~1) == VARTAG_EXPANDED_RO); 204b: 41 89 f5 mov r13d,esi 204e: 41 83 e5 fe and r13d,0xfffffffe else if (VARTAG_IS_EXPANDED(tag)) 2052: 41 83 fd 02 cmp r13d,0x2 2056: 0f 84 01 02 00 00 je 225d else if (tag == VARTAG_ONDISK) 205c: 83 fe 12 cmp esi,0x12 205f: 40 0f 94 c6 sete sil 2063: 40 0f b6 f6 movzx esi,sil 2067: 48 c1 e6 04 shl rsi,0x4 *off += VARSIZE_ANY(DatumGetPointer(res)); 206b: 44 8d 6e 02 lea r13d,[rsi+0x2] 206f: e9 cc fe ff ff jmp 1f40 2074: 0f 1f 40 00 nop DWORD PTR [rax+0x0] return VARSIZE_4B(PTR); 2078: 44 8b 2e mov r13d,DWORD PTR [rsi] 207b: 41 c1 ed 02 shr r13d,0x2 207f: e9 bc fe ff ff jmp 1f40 2084: 0f 1f 40 00 nop DWORD PTR [rax+0x0] natts = reqnatts; 2088: 4d 63 cc movsxd r9,r12d 208b: 45 89 e6 mov r14d,r12d 208e: e9 9b fb ff ff jmp 1c2e 2093: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] return (Datum) X; 2098: 49 63 45 00 movsxd rax,DWORD PTR [r13+0x0] values[attnum] = (Datum) 0; 209c: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 20a0: 49 83 c2 01 add r10,0x1 20a4: 4d 39 ca cmp r10,r9 20a7: 0f 85 13 fd ff ff jne 1dc0 20ad: e9 7b fd ff ff jmp 1e2d 20b2: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0] return (Datum) X; 20b8: 49 0f bf 45 00 movsx rax,WORD PTR [r13+0x0] values[attnum] = (Datum) 0; 20bd: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 20c1: 49 83 c2 01 add r10,0x1 20c5: 4d 39 ca cmp r10,r9 20c8: 0f 85 f2 fc ff ff jne 1dc0 20ce: e9 5a fd ff ff jmp 1e2d 20d3: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] return VARTAG_1B_E(PTR); 20d8: 45 0f b6 6d 01 movzx r13d,BYTE PTR [r13+0x1] if (tag == VARTAG_INDIRECT) 20dd: 41 83 fd 01 cmp r13d,0x1 20e1: 0f 84 6b 01 00 00 je 2252 return ((tag & ~1) == VARTAG_EXPANDED_RO); 20e7: 45 89 ee mov r14d,r13d 20ea: 41 83 e6 fe and r14d,0xfffffffe else if (VARTAG_IS_EXPANDED(tag)) 20ee: 41 83 fe 02 cmp r14d,0x2 20f2: 0f 84 5a 01 00 00 je 2252 else if (tag == VARTAG_ONDISK) 20f8: 41 83 fd 12 cmp r13d,0x12 20fc: 41 0f 94 c5 sete r13b 2100: 45 0f b6 ed movzx r13d,r13b 2104: 49 c1 e5 04 shl r13,0x4 2108: 45 8d 75 02 lea r14d,[r13+0x2] 210c: e9 80 fc ff ff jmp 1d91 2111: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] * case. */ static inline int first_null_attr(const bits8 *bits, int natts) { int nattByte = natts >> 3; 2118: 45 89 cd mov r13d,r9d 211b: 41 c1 fd 03 sar r13d,0x3 } } #endif /* Process all bytes up to just before the byte for the natts attribute */ for (bytenum = 0; bytenum < nattByte; bytenum++) 211f: 45 85 ed test r13d,r13d 2122: 0f 8e 40 01 00 00 jle 2268 2128: 48 8d 73 17 lea rsi,[rbx+0x17] 212c: 31 ff xor edi,edi 212e: eb 20 jmp 2150 2130: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] 2135: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 213c: 00 00 00 00 2140: 83 c7 01 add edi,0x1 2143: 48 83 c6 01 add rsi,0x1 2147: 41 39 fd cmp r13d,edi 214a: 0f 84 ec 00 00 00 je 223c { /* break if there's any NULL attrs (a 0 bit) */ if (bits[bytenum] != 0xFF) 2150: 0f b6 06 movzx eax,BYTE PTR [rsi] 2153: 3c ff cmp al,0xff 2155: 74 e9 je 2140 * looking for the first 1-bit. This works even when the byte is 0xFF, as * the bitwise NOT of 0xFF in 32 bits is 0xFFFFFF00, in which case * pg_rightmost_one_pos32() will return 8. We may end up with a value * higher than natts here, but we'll fix that with the Min() below. */ res = bytenum << 3; 2157: c1 e7 03 shl edi,0x3 res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 215a: f7 d0 not eax int nbytes = (natts + 7) >> 3; 215c: 45 8d 69 07 lea r13d,[r9+0x7] pg_rightmost_one_pos32(uint32 word) { #ifdef HAVE__BUILTIN_CTZ Assert(word != 0); return __builtin_ctz(word); 2160: f3 0f bc c0 tzcnt eax,eax res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 2164: 01 f8 add eax,edi /* * Since we did no masking to mask out bits beyond the natt'th bit, we may * have found a bit higher than natts, so we must cap res to natts */ res = Min(res, natts); 2166: 41 39 c1 cmp r9d,eax 2169: 41 0f 4e c1 cmovle eax,r9d int nbytes = (natts + 7) >> 3; 216d: 41 c1 fd 03 sar r13d,0x3 res = Min(res, natts); 2171: 4c 63 f0 movsxd r14,eax isnull_8 &= UINT64CONST(0x0101010101010101); 2174: 49 bf 01 01 01 01 01 movabs r15,0x101010101010101 217b: 01 01 01 217e: 4d 63 ed movsxd r13,r13d for (bytenum = 0; bytenum < nattByte; bytenum++) 2181: 31 ff xor edi,edi 2183: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0] 2189: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 2190: 00 00 00 00 2194: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 219b: 00 00 00 00 219f: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 21a6: 00 00 00 00 21aa: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 21b1: 00 00 00 00 21b5: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 21bc: 00 00 00 00 bits8 nullbyte = ~bits[i]; 21c0: 0f b6 74 3b 17 movzx esi,BYTE PTR [rbx+rdi*1+0x17] 21c5: f7 d6 not esi isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32; 21c7: 89 f0 mov eax,esi isnull_8 = (nullbyte & 0xf) * SPREAD_BITS_MULTIPLIER_32; 21c9: 83 e6 0f and esi,0xf isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32; 21cc: c0 e8 04 shr al,0x4 isnull_8 = (nullbyte & 0xf) * SPREAD_BITS_MULTIPLIER_32; 21cf: 48 69 f6 81 40 20 00 imul rsi,rsi,0x204081 isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32; 21d6: 83 e0 0f and eax,0xf 21d9: 48 69 c0 81 40 20 00 imul rax,rax,0x204081 21e0: 48 c1 e0 20 shl rax,0x20 21e4: 48 09 f0 or rax,rsi isnull_8 &= UINT64CONST(0x0101010101010101); 21e7: 4c 21 f8 and rax,r15 21ea: 48 89 04 f9 mov QWORD PTR [rcx+rdi*8],rax for (int i = 0; i < nbytes; i++, isnull += 8) 21ee: 48 83 c7 01 add rdi,0x1 21f2: 4c 39 ef cmp rdi,r13 21f5: 75 c9 jne 21c0 firstNonCacheOffsetAttr = Min(firstNonCacheOffsetAttr, firstNullAttr); 21f7: 45 39 f2 cmp r10d,r14d 21fa: 4d 0f 4f d6 cmovg r10,r14 21fe: e9 2b fa ff ff jmp 1c2e 2203: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] for (; attnum < firstNullAttr; attnum++) 2208: 49 89 c2 mov r10,rax 220b: e9 a0 fb ff ff jmp 1db0 for (; attnum < natts; attnum++) 2210: 4d 89 d1 mov r9,r10 2213: e9 15 fc ff ff jmp 1e2d 2218: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 221f: 00 *offp = off; 2220: 41 89 5b 48 mov DWORD PTR [r11+0x48],ebx slot_getmissingattrs(slot, attnum, reqnatts); 2224: 44 89 e2 mov edx,r12d } 2227: 5b pop rbx slot_getmissingattrs(slot, attnum, reqnatts); 2228: 44 89 ce mov esi,r9d } 222b: 5d pop rbp slot_getmissingattrs(slot, attnum, reqnatts); 222c: 4c 89 df mov rdi,r11 } 222f: 41 5c pop r12 2231: 41 5d pop r13 2233: 41 5e pop r14 2235: 41 5f pop r15 slot_getmissingattrs(slot, attnum, reqnatts); 2237: e9 b4 f8 ff ff jmp 1af0 res = bytenum << 3; 223c: 42 8d 3c ed 00 00 00 lea edi,[r13*8+0x0] 2243: 00 res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 2244: 4d 63 ed movsxd r13,r13d 2247: 42 0f b6 44 2b 17 movzx eax,BYTE PTR [rbx+r13*1+0x17] 224d: e9 08 ff ff ff jmp 215a 2252: 41 be 0a 00 00 00 mov r14d,0xa 2258: e9 34 fb ff ff jmp 1d91 225d: 41 bd 0a 00 00 00 mov r13d,0xa 2263: e9 d8 fc ff ff jmp 1f40 2268: 0f b6 43 17 movzx eax,BYTE PTR [rbx+0x17] int nbytes = (natts + 7) >> 3; 226c: 45 8d 69 07 lea r13d,[r9+0x7] res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 2270: f7 d0 not eax 2272: f3 0f bc c0 tzcnt eax,eax res = Min(res, natts); 2276: 41 39 c1 cmp r9d,eax 2279: 41 0f 4e c1 cmovle eax,r9d int nbytes = (natts + 7) >> 3; 227d: 41 c1 fd 03 sar r13d,0x3 res = Min(res, natts); 2281: 4c 63 f0 movsxd r14,eax for (int i = 0; i < nbytes; i++, isnull += 8) 2284: 41 83 fd 01 cmp r13d,0x1 2288: 0f 85 69 ff ff ff jne 21f7 228e: e9 e1 fe ff ff jmp 2174 2293: 66 90 xchg ax,ax 2295: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 229c: 00 00 00 00 00000000000022a0 : { 22a0: f3 0f 1e fa endbr64 22a4: 41 57 push r15 22a6: 49 89 fb mov r11,rdi 22a9: 41 56 push r14 22ab: 41 55 push r13 22ad: 41 54 push r12 22af: 4c 63 e6 movsxd r12,esi 22b2: 55 push rbp 22b3: 53 push rbx HeapTupleHeader tup = tuple->t_data; 22b4: 48 8b 47 40 mov rax,QWORD PTR [rdi+0x40] TupleDesc tupleDesc = slot->tts_tupleDescriptor; 22b8: 48 8b 57 10 mov rdx,QWORD PTR [rdi+0x10] isnull = slot->tts_isnull; 22bc: 48 8b 4f 20 mov rcx,QWORD PTR [rdi+0x20] HeapTupleHeader tup = tuple->t_data; 22c0: 48 8b 58 10 mov rbx,QWORD PTR [rax+0x10] if (TTS_OBEYS_NOT_NULL_CONSTRAINTS(slot)) 22c4: f6 47 04 08 test BYTE PTR [rdi+0x4],0x8 22c8: 0f 84 22 04 00 00 je 26f0 firstNonGuaranteedAttr = Min(reqnatts, tupleDesc->firstNonGuaranteedAttr); 22ce: 8b 42 14 mov eax,DWORD PTR [rdx+0x14] 22d1: 41 39 c4 cmp r12d,eax 22d4: 41 0f 4e c4 cmovle eax,r12d if (attnum < firstNonGuaranteedAttr) 22d8: 48 63 e8 movsxd rbp,eax firstNonCacheOffsetAttr = tupleDesc->firstNonCachedOffsetAttr; 22db: 4c 63 52 10 movsxd r10,DWORD PTR [rdx+0x10] if (HeapTupleHasNulls(tuple)) 22df: f6 43 14 01 test BYTE PTR [rbx+0x14],0x1 22e3: 0f 84 d7 03 00 00 je 26c0 natts = HeapTupleHeaderGetNatts(tup); 22e9: 44 0f b7 4b 12 movzx r9d,WORD PTR [rbx+0x12] 22ee: 41 81 e1 ff 07 00 00 and r9d,0x7ff 22f5: 45 8d 41 07 lea r8d,[r9+0x7] 22f9: 41 c1 f8 03 sar r8d,0x3 tp = (char *) tup + MAXALIGN(offsetof(HeapTupleHeaderData, t_bits) + 22fd: 41 83 c0 1e add r8d,0x1e 2301: 41 81 e0 f8 03 00 00 and r8d,0x3f8 2308: 49 01 d8 add r8,rbx natts = Min(natts, reqnatts); 230b: 45 39 cc cmp r12d,r9d 230e: 4d 0f 4e cc cmovle r9,r12 firstNullAttr = natts; 2312: 45 89 ce mov r14d,r9d if (natts > firstNonGuaranteedAttr) 2315: 41 39 c1 cmp r9d,eax 2318: 0f 8f 0a 05 00 00 jg 2828 attnum = slot->tts_nvalid; 231e: 49 0f bf 43 06 movsx rax,WORD PTR [r11+0x6] values = slot->tts_values; 2323: 49 8b 7b 18 mov rdi,QWORD PTR [r11+0x18] slot->tts_nvalid = reqnatts; 2327: 66 45 89 63 06 mov WORD PTR [r11+0x6],r12w if (attnum < firstNonGuaranteedAttr) 232c: 48 39 e8 cmp rax,rbp 232f: 73 7f jae 23b0 2331: 48 89 54 24 f0 mov QWORD PTR [rsp-0x10],rdx 2336: 48 8d 74 c2 20 lea rsi,[rdx+rax*8+0x20] 233b: eb 22 jmp 235f 233d: 0f 1f 00 nop DWORD PTR [rax] switch (attlen) 2340: 66 41 83 ff 01 cmp r15w,0x1 2345: 74 59 je 23a0 return (Datum) X; 2347: 48 8b 12 mov rdx,QWORD PTR [rdx] values[attnum] = fetch_att_noerr(tp + off, true, attlen); 234a: 48 89 14 c7 mov QWORD PTR [rdi+rax*8],rdx attnum++; 234e: 48 83 c0 01 add rax,0x1 } while (attnum < firstNonGuaranteedAttr); 2352: 48 83 c6 08 add rsi,0x8 2356: 48 39 e8 cmp rax,rbp 2359: 0f 83 31 03 00 00 jae 2690 isnull[attnum] = false; 235f: c6 04 01 00 mov BYTE PTR [rcx+rax*1],0x0 off = cattr->attcacheoff; 2363: 0f bf 16 movsx edx,WORD PTR [rsi] cattr = &cattrs[attnum]; 2366: 49 89 f5 mov r13,rsi attlen = cattr->attlen; 2369: 44 0f b7 7e 02 movzx r15d,WORD PTR [rsi+0x2] off = cattr->attcacheoff; 236e: 48 89 d3 mov rbx,rdx values[attnum] = fetch_att_noerr(tp + off, true, attlen); 2371: 4c 01 c2 add rdx,r8 2374: 66 41 83 ff 02 cmp r15w,0x2 2379: 74 15 je 2390 237b: 66 41 83 ff 04 cmp r15w,0x4 2380: 75 be jne 2340 return (Datum) X; 2382: 48 63 12 movsxd rdx,DWORD PTR [rdx] return Int32GetDatum(*((const int32 *) T)); 2385: eb c3 jmp 234a 2387: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0] 238e: 00 00 return (Datum) X; 2390: 48 0f bf 12 movsx rdx,WORD PTR [rdx] return Int16GetDatum(*((const int16 *) T)); 2394: eb b4 jmp 234a 2396: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0] 239d: 00 00 00 return (Datum) X; 23a0: 48 0f be 12 movsx rdx,BYTE PTR [rdx] return CharGetDatum(*((const char *) T)); 23a4: eb a4 jmp 234a 23a6: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0] 23ad: 00 00 00 off = *offp; 23b0: 41 8b 5b 68 mov ebx,DWORD PTR [r11+0x68] if (unlikely(attnum < reqnatts)) 23b4: 49 63 ec movsxd rbp,r12d firstNonCacheOffsetAttr = Min(firstNonCacheOffsetAttr, natts); 23b7: 45 39 ca cmp r10d,r9d 23ba: 4d 0f 4f d1 cmovg r10,r9 if (attnum < firstNonCacheOffsetAttr) 23be: 4c 39 d0 cmp rax,r10 23c1: 0f 82 c9 01 00 00 jb 2590 for (; attnum < firstNullAttr; attnum++) 23c7: 4d 63 d6 movsxd r10,r14d 23ca: 4c 39 d0 cmp rax,r10 23cd: 72 5e jb 242d 23cf: e9 34 05 00 00 jmp 2908 23d4: 0f 1f 40 00 nop DWORD PTR [rax+0x0] *off = TYPEALIGN(attalignby, *off); 23d8: 8d 5c 1e ff lea ebx,[rsi+rbx*1-0x1] 23dc: f7 de neg esi 23de: 21 de and esi,ebx *off += attlen; 23e0: 41 0f bf dd movsx ebx,r13w offset_ptr = tupptr + *off; 23e4: 41 89 f6 mov r14d,esi *off += attlen; 23e7: 01 f3 add ebx,esi offset_ptr = tupptr + *off; 23e9: 4d 01 c6 add r14,r8 return (Datum) (uintptr_t) X; 23ec: 4c 89 f6 mov rsi,r14 if (attbyval) 23ef: 80 7c c2 24 00 cmp BYTE PTR [rdx+rax*8+0x24],0x0 23f4: 74 2a je 2420 switch (attlen) 23f6: 66 41 83 fd 02 cmp r13w,0x2 23fb: 0f 84 0f 02 00 00 je 2610 2401: 66 41 83 fd 04 cmp r13w,0x4 2406: 0f 84 f4 01 00 00 je 2600 240c: 66 41 83 fd 01 cmp r13w,0x1 2411: 0f 85 d9 01 00 00 jne 25f0 return (Datum) X; 2417: 49 0f be 36 movsx rsi,BYTE PTR [r14] 241b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] values[attnum] = align_fetch_then_add(tp, 2420: 48 89 34 c7 mov QWORD PTR [rdi+rax*8],rsi for (; attnum < firstNullAttr; attnum++) 2424: 48 83 c0 01 add rax,0x1 2428: 4c 39 d0 cmp rax,r10 242b: 74 73 je 24a0 isnull[attnum] = false; 242d: c6 04 01 00 mov BYTE PTR [rcx+rax*1],0x0 attlen = cattr->attlen; 2431: 44 0f b7 6c c2 22 movzx r13d,WORD PTR [rdx+rax*8+0x22] cattr->attalignby); 2437: 0f b6 74 c2 25 movzx esi,BYTE PTR [rdx+rax*8+0x25] if (attlen > 0) 243c: 66 45 85 ed test r13w,r13w 2440: 7f 96 jg 23d8 if (!VARATT_IS_SHORT(tupptr + *off)) 2442: 41 89 dd mov r13d,ebx 2445: 4d 01 c5 add r13,r8 2448: 41 f6 45 00 01 test BYTE PTR [r13+0x0],0x1 244d: 75 0e jne 245d *off = TYPEALIGN(attalignby, *off); 244f: 8d 5c 1e ff lea ebx,[rsi+rbx*1-0x1] 2453: f7 de neg esi 2455: 21 f3 and ebx,esi res = PointerGetDatum(tupptr + *off); 2457: 41 89 dd mov r13d,ebx 245a: 4d 01 c5 add r13,r8 if (VARATT_IS_1B_E(PTR)) 245d: 45 0f b6 75 00 movzx r14d,BYTE PTR [r13+0x0] return (Datum) (uintptr_t) X; 2462: 4c 89 ee mov rsi,r13 2465: 41 80 fe 01 cmp r14b,0x1 2469: 0f 84 79 03 00 00 je 27e8 else if (VARATT_IS_1B(PTR)) 246f: 41 f6 c6 01 test r14b,0x1 2473: 0f 85 a7 02 00 00 jne 2720 return VARSIZE_4B(PTR); 2479: 45 8b 75 00 mov r14d,DWORD PTR [r13+0x0] 247d: 41 c1 ee 02 shr r14d,0x2 values[attnum] = align_fetch_then_add(tp, 2481: 48 89 34 c7 mov QWORD PTR [rdi+rax*8],rsi for (; attnum < firstNullAttr; attnum++) 2485: 48 83 c0 01 add rax,0x1 *off += VARSIZE_ANY(DatumGetPointer(res)); 2489: 44 01 f3 add ebx,r14d 248c: 4c 39 d0 cmp rax,r10 248f: 75 9c jne 242d 2491: 0f 1f 40 00 nop DWORD PTR [rax+0x0] 2495: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 249c: 00 00 00 00 for (; attnum < natts; attnum++) 24a0: 4d 39 ca cmp r10,r9 24a3: 0f 83 67 04 00 00 jae 2910 24a9: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] if (isnull[attnum]) 24b0: 31 c0 xor eax,eax 24b2: 42 80 3c 11 00 cmp BYTE PTR [rcx+r10*1],0x0 24b7: 75 57 jne 2510 attlen = cattr->attlen; 24b9: 42 0f b7 74 d2 22 movzx esi,WORD PTR [rdx+r10*8+0x22] cattr->attalignby); 24bf: 42 0f b6 44 d2 25 movzx eax,BYTE PTR [rdx+r10*8+0x25] if (attlen > 0) 24c5: 66 85 f6 test si,si 24c8: 0f 8e 52 01 00 00 jle 2620 *off = TYPEALIGN(attalignby, *off); 24ce: 8d 5c 18 ff lea ebx,[rax+rbx*1-0x1] 24d2: f7 d8 neg eax 24d4: 21 d8 and eax,ebx *off += attlen; 24d6: 0f bf de movsx ebx,si offset_ptr = tupptr + *off; 24d9: 41 89 c5 mov r13d,eax *off += attlen; 24dc: 01 c3 add ebx,eax offset_ptr = tupptr + *off; 24de: 4d 01 c5 add r13,r8 24e1: 4c 89 e8 mov rax,r13 if (attbyval) 24e4: 42 80 7c d2 24 00 cmp BYTE PTR [rdx+r10*8+0x24],0x0 24ea: 74 24 je 2510 switch (attlen) 24ec: 66 83 fe 02 cmp si,0x2 24f0: 0f 84 d2 02 00 00 je 27c8 24f6: 66 83 fe 04 cmp si,0x4 24fa: 0f 84 a8 02 00 00 je 27a8 2500: 66 83 fe 01 cmp si,0x1 2504: 0f 84 f6 01 00 00 je 2700 return (Datum) X; 250a: 49 8b 45 00 mov rax,QWORD PTR [r13+0x0] 250e: 66 90 xchg ax,ax values[attnum] = (Datum) 0; 2510: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 2514: 49 83 c2 01 add r10,0x1 2518: 4d 39 ca cmp r10,r9 251b: 75 93 jne 24b0 if (unlikely(attnum < reqnatts)) 251d: 49 39 e9 cmp r9,rbp 2520: 0f 82 fa 03 00 00 jb 2920 *offp = off; 2526: 41 89 5b 68 mov DWORD PTR [r11+0x68],ebx } 252a: 5b pop rbx 252b: 5d pop rbp 252c: 41 5c pop r12 252e: 41 5d pop r13 2530: 41 5e pop r14 2532: 41 5f pop r15 2534: c3 ret 2535: 0f 1f 00 nop DWORD PTR [rax] switch (attlen) 2538: 66 83 fb 01 cmp bx,0x1 253c: 0f 84 2e 01 00 00 je 2670 2542: 48 8b 1e mov rbx,QWORD PTR [rsi] 2545: 0f 1f 40 00 nop DWORD PTR [rax+0x0] 2549: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 2550: 00 00 00 00 2554: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 255b: 00 00 00 00 255f: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 2566: 00 00 00 00 256a: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 2571: 00 00 00 00 2575: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 257c: 00 00 00 00 } while (++attnum < firstNonCacheOffsetAttr); 2580: 48 8d 70 01 lea rsi,[rax+0x1] values[attnum] = fetch_att_noerr(tp + off, 2584: 48 89 1c c7 mov QWORD PTR [rdi+rax*8],rbx } while (++attnum < firstNonCacheOffsetAttr); 2588: 49 39 f2 cmp r10,rsi 258b: 74 53 je 25e0 258d: 48 89 f0 mov rax,rsi isnull[attnum] = false; 2590: c6 04 01 00 mov BYTE PTR [rcx+rax*1],0x0 off = cattr->attcacheoff; 2594: 0f bf 74 c2 20 movsx esi,WORD PTR [rdx+rax*8+0x20] 2599: 49 89 f5 mov r13,rsi values[attnum] = fetch_att_noerr(tp + off, 259c: 4c 01 c6 add rsi,r8 return (Datum) (uintptr_t) X; 259f: 48 89 f3 mov rbx,rsi if (attbyval) 25a2: 80 7c c2 24 00 cmp BYTE PTR [rdx+rax*8+0x24],0x0 25a7: 74 d7 je 2580 cattr->attlen); 25a9: 0f b7 5c c2 22 movzx ebx,WORD PTR [rdx+rax*8+0x22] switch (attlen) 25ae: 66 83 fb 02 cmp bx,0x2 25b2: 0f 84 c8 00 00 00 je 2680 25b8: 66 83 fb 04 cmp bx,0x4 25bc: 0f 85 76 ff ff ff jne 2538 return (Datum) X; 25c2: 48 63 1e movsxd rbx,DWORD PTR [rsi] } while (++attnum < firstNonCacheOffsetAttr); 25c5: 48 8d 70 01 lea rsi,[rax+0x1] values[attnum] = fetch_att_noerr(tp + off, 25c9: 48 89 1c c7 mov QWORD PTR [rdi+rax*8],rbx } while (++attnum < firstNonCacheOffsetAttr); 25cd: 49 39 f2 cmp r10,rsi 25d0: 75 bb jne 258d 25d2: 0f 1f 00 nop DWORD PTR [rax] 25d5: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 25dc: 00 00 00 00 off += cattr->attlen; 25e0: 0f bf 5c c2 22 movsx ebx,WORD PTR [rdx+rax*8+0x22] } while (++attnum < firstNonCacheOffsetAttr); 25e5: 4c 89 d0 mov rax,r10 off += cattr->attlen; 25e8: 44 01 eb add ebx,r13d 25eb: e9 d7 fd ff ff jmp 23c7 return (Datum) X; 25f0: 49 8b 36 mov rsi,QWORD PTR [r14] return Int64GetDatum(*((const int64 *) offset_ptr)); 25f3: e9 28 fe ff ff jmp 2420 25f8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 25ff: 00 return (Datum) X; 2600: 49 63 36 movsxd rsi,DWORD PTR [r14] return Int32GetDatum(*((const int32 *) offset_ptr)); 2603: e9 18 fe ff ff jmp 2420 2608: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 260f: 00 return (Datum) X; 2610: 49 0f bf 36 movsx rsi,WORD PTR [r14] return Int16GetDatum(*((const int16 *) offset_ptr)); 2614: e9 07 fe ff ff jmp 2420 2619: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] if (!VARATT_IS_SHORT(tupptr + *off)) 2620: 89 de mov esi,ebx 2622: 4c 01 c6 add rsi,r8 2625: f6 06 01 test BYTE PTR [rsi],0x1 2628: 0f 84 02 01 00 00 je 2730 if (VARATT_IS_1B_E(PTR)) 262e: 44 0f b6 2e movzx r13d,BYTE PTR [rsi] return (Datum) (uintptr_t) X; 2632: 48 89 f0 mov rax,rsi 2635: 41 80 fd 01 cmp r13b,0x1 2639: 0f 84 0f 01 00 00 je 274e else if (VARATT_IS_1B(PTR)) 263f: 41 f6 c5 01 test r13b,0x1 2643: 0f 84 3f 01 00 00 je 2788 return VARSIZE_1B(PTR); 2649: 41 d0 ed shr r13b,1 *off += VARSIZE_ANY(DatumGetPointer(res)); 264c: 45 0f b6 ed movzx r13d,r13b values[attnum] = (Datum) 0; 2650: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 2654: 49 83 c2 01 add r10,0x1 2658: 44 01 eb add ebx,r13d 265b: 4d 39 ca cmp r10,r9 265e: 0f 85 4c fe ff ff jne 24b0 2664: e9 b4 fe ff ff jmp 251d 2669: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] return (Datum) X; 2670: 48 0f be 1e movsx rbx,BYTE PTR [rsi] return CharGetDatum(*((const char *) T)); 2674: e9 07 ff ff ff jmp 2580 2679: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] return (Datum) X; 2680: 48 0f bf 1e movsx rbx,WORD PTR [rsi] return Int16GetDatum(*((const int16 *) T)); 2684: e9 f7 fe ff ff jmp 2580 2689: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] off += cattr->attlen; 2690: 41 0f bf 75 02 movsx esi,WORD PTR [r13+0x2] if (attnum == reqnatts) 2695: 49 63 ec movsxd rbp,r12d off += cattr->attlen; 2698: 48 8b 54 24 f0 mov rdx,QWORD PTR [rsp-0x10] 269d: 01 f3 add ebx,esi if (attnum == reqnatts) 269f: 48 39 e8 cmp rax,rbp 26a2: 0f 85 0f fd ff ff jne 23b7 *offp = off; 26a8: 41 89 5b 68 mov DWORD PTR [r11+0x68],ebx } 26ac: 5b pop rbx 26ad: 5d pop rbp 26ae: 41 5c pop r12 26b0: 41 5d pop r13 26b2: 41 5e pop r14 26b4: 41 5f pop r15 26b6: c3 ret 26b7: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0] 26be: 00 00 tp = (char *) tup + MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)); 26c0: 4c 8d 43 18 lea r8,[rbx+0x18] if (reqnatts > firstNonGuaranteedAttr) 26c4: 41 39 c4 cmp r12d,eax 26c7: 0f 8e cb 00 00 00 jle 2798 natts = Min(HeapTupleHeaderGetNatts(tup), reqnatts); 26cd: 0f b7 43 12 movzx eax,WORD PTR [rbx+0x12] 26d1: 25 ff 07 00 00 and eax,0x7ff 26d6: 44 39 e0 cmp eax,r12d 26d9: 41 0f 4f c4 cmovg eax,r12d 26dd: 41 89 c6 mov r14d,eax 26e0: 4c 63 c8 movsxd r9,eax 26e3: e9 36 fc ff ff jmp 231e 26e8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 26ef: 00 26f0: 31 ed xor ebp,ebp firstNonGuaranteedAttr = 0; 26f2: 31 c0 xor eax,eax 26f4: e9 e2 fb ff ff jmp 22db 26f9: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] return (Datum) X; 2700: 49 0f be 45 00 movsx rax,BYTE PTR [r13+0x0] values[attnum] = (Datum) 0; 2705: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 2709: 49 83 c2 01 add r10,0x1 270d: 4d 39 ca cmp r10,r9 2710: 0f 85 9a fd ff ff jne 24b0 2716: e9 02 fe ff ff jmp 251d 271b: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] 2720: 41 d0 ee shr r14b,1 *off += VARSIZE_ANY(DatumGetPointer(res)); 2723: 45 0f b6 f6 movzx r14d,r14b 2727: e9 55 fd ff ff jmp 2481 272c: 0f 1f 40 00 nop DWORD PTR [rax+0x0] *off = TYPEALIGN(attalignby, *off); 2730: 8d 5c 18 ff lea ebx,[rax+rbx*1-0x1] 2734: f7 d8 neg eax 2736: 21 c3 and ebx,eax res = PointerGetDatum(tupptr + *off); 2738: 89 de mov esi,ebx 273a: 4c 01 c6 add rsi,r8 if (VARATT_IS_1B_E(PTR)) 273d: 44 0f b6 2e movzx r13d,BYTE PTR [rsi] return (Datum) (uintptr_t) X; 2741: 48 89 f0 mov rax,rsi 2744: 41 80 fd 01 cmp r13b,0x1 2748: 0f 85 f1 fe ff ff jne 263f return VARTAG_1B_E(PTR); 274e: 0f b6 76 01 movzx esi,BYTE PTR [rsi+0x1] if (tag == VARTAG_INDIRECT) 2752: 83 fe 01 cmp esi,0x1 2755: 0f 84 02 02 00 00 je 295d return ((tag & ~1) == VARTAG_EXPANDED_RO); 275b: 41 89 f5 mov r13d,esi 275e: 41 83 e5 fe and r13d,0xfffffffe else if (VARTAG_IS_EXPANDED(tag)) 2762: 41 83 fd 02 cmp r13d,0x2 2766: 0f 84 f1 01 00 00 je 295d else if (tag == VARTAG_ONDISK) 276c: 83 fe 12 cmp esi,0x12 276f: 40 0f 94 c6 sete sil 2773: 40 0f b6 f6 movzx esi,sil 2777: 48 c1 e6 04 shl rsi,0x4 *off += VARSIZE_ANY(DatumGetPointer(res)); 277b: 44 8d 6e 02 lea r13d,[rsi+0x2] 277f: e9 cc fe ff ff jmp 2650 2784: 0f 1f 40 00 nop DWORD PTR [rax+0x0] return VARSIZE_4B(PTR); 2788: 44 8b 2e mov r13d,DWORD PTR [rsi] 278b: 41 c1 ed 02 shr r13d,0x2 278f: e9 bc fe ff ff jmp 2650 2794: 0f 1f 40 00 nop DWORD PTR [rax+0x0] natts = reqnatts; 2798: 4d 63 cc movsxd r9,r12d 279b: 45 89 e6 mov r14d,r12d 279e: e9 7b fb ff ff jmp 231e 27a3: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] return (Datum) X; 27a8: 49 63 45 00 movsxd rax,DWORD PTR [r13+0x0] values[attnum] = (Datum) 0; 27ac: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 27b0: 49 83 c2 01 add r10,0x1 27b4: 4d 39 ca cmp r10,r9 27b7: 0f 85 f3 fc ff ff jne 24b0 27bd: e9 5b fd ff ff jmp 251d 27c2: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0] return (Datum) X; 27c8: 49 0f bf 45 00 movsx rax,WORD PTR [r13+0x0] values[attnum] = (Datum) 0; 27cd: 4a 89 04 d7 mov QWORD PTR [rdi+r10*8],rax for (; attnum < natts; attnum++) 27d1: 49 83 c2 01 add r10,0x1 27d5: 4d 39 ca cmp r10,r9 27d8: 0f 85 d2 fc ff ff jne 24b0 27de: e9 3a fd ff ff jmp 251d 27e3: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] return VARTAG_1B_E(PTR); 27e8: 45 0f b6 6d 01 movzx r13d,BYTE PTR [r13+0x1] if (tag == VARTAG_INDIRECT) 27ed: 41 83 fd 01 cmp r13d,0x1 27f1: 0f 84 5b 01 00 00 je 2952 return ((tag & ~1) == VARTAG_EXPANDED_RO); 27f7: 45 89 ee mov r14d,r13d 27fa: 41 83 e6 fe and r14d,0xfffffffe else if (VARTAG_IS_EXPANDED(tag)) 27fe: 41 83 fe 02 cmp r14d,0x2 2802: 0f 84 4a 01 00 00 je 2952 else if (tag == VARTAG_ONDISK) 2808: 41 83 fd 12 cmp r13d,0x12 280c: 41 0f 94 c5 sete r13b 2810: 45 0f b6 ed movzx r13d,r13b 2814: 49 c1 e5 04 shl r13,0x4 2818: 45 8d 75 02 lea r14d,[r13+0x2] 281c: e9 60 fc ff ff jmp 2481 2821: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] int nattByte = natts >> 3; 2828: 45 89 cd mov r13d,r9d 282b: 41 c1 fd 03 sar r13d,0x3 for (bytenum = 0; bytenum < nattByte; bytenum++) 282f: 45 85 ed test r13d,r13d 2832: 0f 8e 30 01 00 00 jle 2968 2838: 48 8d 73 17 lea rsi,[rbx+0x17] 283c: 31 ff xor edi,edi 283e: eb 10 jmp 2850 2840: 83 c7 01 add edi,0x1 2843: 48 83 c6 01 add rsi,0x1 2847: 41 39 fd cmp r13d,edi 284a: 0f 84 ec 00 00 00 je 293c if (bits[bytenum] != 0xFF) 2850: 0f b6 06 movzx eax,BYTE PTR [rsi] 2853: 3c ff cmp al,0xff 2855: 74 e9 je 2840 res = bytenum << 3; 2857: c1 e7 03 shl edi,0x3 res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 285a: f7 d0 not eax int nbytes = (natts + 7) >> 3; 285c: 45 8d 69 07 lea r13d,[r9+0x7] 2860: f3 0f bc c0 tzcnt eax,eax res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 2864: 01 f8 add eax,edi res = Min(res, natts); 2866: 41 39 c1 cmp r9d,eax 2869: 41 0f 4e c1 cmovle eax,r9d int nbytes = (natts + 7) >> 3; 286d: 41 c1 fd 03 sar r13d,0x3 res = Min(res, natts); 2871: 4c 63 f0 movsxd r14,eax isnull_8 &= UINT64CONST(0x0101010101010101); 2874: 49 bf 01 01 01 01 01 movabs r15,0x101010101010101 287b: 01 01 01 287e: 4d 63 ed movsxd r13,r13d for (bytenum = 0; bytenum < nattByte; bytenum++) 2881: 31 ff xor edi,edi 2883: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0] 2889: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 2890: 00 00 00 00 2894: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 289b: 00 00 00 00 289f: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 28a6: 00 00 00 00 28aa: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 28b1: 00 00 00 00 28b5: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 28bc: 00 00 00 00 bits8 nullbyte = ~bits[i]; 28c0: 0f b6 74 3b 17 movzx esi,BYTE PTR [rbx+rdi*1+0x17] 28c5: f7 d6 not esi isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32; 28c7: 89 f0 mov eax,esi isnull_8 = (nullbyte & 0xf) * SPREAD_BITS_MULTIPLIER_32; 28c9: 83 e6 0f and esi,0xf isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32; 28cc: c0 e8 04 shr al,0x4 isnull_8 = (nullbyte & 0xf) * SPREAD_BITS_MULTIPLIER_32; 28cf: 48 69 f6 81 40 20 00 imul rsi,rsi,0x204081 isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32; 28d6: 83 e0 0f and eax,0xf 28d9: 48 69 c0 81 40 20 00 imul rax,rax,0x204081 28e0: 48 c1 e0 20 shl rax,0x20 28e4: 48 09 f0 or rax,rsi isnull_8 &= UINT64CONST(0x0101010101010101); 28e7: 4c 21 f8 and rax,r15 28ea: 48 89 04 f9 mov QWORD PTR [rcx+rdi*8],rax for (int i = 0; i < nbytes; i++, isnull += 8) 28ee: 48 83 c7 01 add rdi,0x1 28f2: 4c 39 ef cmp rdi,r13 28f5: 75 c9 jne 28c0 firstNonCacheOffsetAttr = Min(firstNonCacheOffsetAttr, firstNullAttr); 28f7: 45 39 f2 cmp r10d,r14d 28fa: 4d 0f 4f d6 cmovg r10,r14 28fe: e9 1b fa ff ff jmp 231e 2903: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] for (; attnum < firstNullAttr; attnum++) 2908: 49 89 c2 mov r10,rax 290b: e9 90 fb ff ff jmp 24a0 for (; attnum < natts; attnum++) 2910: 4d 89 d1 mov r9,r10 2913: e9 05 fc ff ff jmp 251d 2918: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 291f: 00 *offp = off; 2920: 41 89 5b 68 mov DWORD PTR [r11+0x68],ebx slot_getmissingattrs(slot, attnum, reqnatts); 2924: 44 89 e2 mov edx,r12d } 2927: 5b pop rbx slot_getmissingattrs(slot, attnum, reqnatts); 2928: 44 89 ce mov esi,r9d } 292b: 5d pop rbp slot_getmissingattrs(slot, attnum, reqnatts); 292c: 4c 89 df mov rdi,r11 } 292f: 41 5c pop r12 2931: 41 5d pop r13 2933: 41 5e pop r14 2935: 41 5f pop r15 slot_getmissingattrs(slot, attnum, reqnatts); 2937: e9 b4 f1 ff ff jmp 1af0 res = bytenum << 3; 293c: 42 8d 3c ed 00 00 00 lea edi,[r13*8+0x0] 2943: 00 res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 2944: 4d 63 ed movsxd r13,r13d 2947: 42 0f b6 44 2b 17 movzx eax,BYTE PTR [rbx+r13*1+0x17] 294d: e9 08 ff ff ff jmp 285a 2952: 41 be 0a 00 00 00 mov r14d,0xa 2958: e9 24 fb ff ff jmp 2481 295d: 41 bd 0a 00 00 00 mov r13d,0xa 2963: e9 e8 fc ff ff jmp 2650 2968: 0f b6 43 17 movzx eax,BYTE PTR [rbx+0x17] int nbytes = (natts + 7) >> 3; 296c: 45 8d 69 07 lea r13d,[r9+0x7] res += pg_rightmost_one_pos32(~((uint32) bits[bytenum])); 2970: f7 d0 not eax 2972: f3 0f bc c0 tzcnt eax,eax res = Min(res, natts); 2976: 41 39 c1 cmp r9d,eax 2979: 41 0f 4e c1 cmovle eax,r9d int nbytes = (natts + 7) >> 3; 297d: 41 c1 fd 03 sar r13d,0x3 res = Min(res, natts); 2981: 4c 63 f0 movsxd r14,eax for (int i = 0; i < nbytes; i++, isnull += 8) 2984: 41 83 fd 01 cmp r13d,0x1 2988: 0f 85 69 ff ff ff jne 28f7 298e: e9 e1 fe ff ff jmp 2874 2993: 66 90 xchg ax,ax 2995: 66 66 2e 0f 1f 84 00 data16 cs nop WORD PTR [rax+rax*1+0x0] 299c: 00 00 00 00