000000000070b520 : /* hash_search_with_hash_value total: 495463 3.6718 */ :hash_search_with_hash_value(HTAB *hashp, : const void *keyPtr, : uint32 hashvalue, : HASHACTION action, : bool *foundPtr) :{ 5023 0.0372 : 70b520: push %r15 5967 0.0442 : 70b522: push %r14 1407 0.0104 : 70b524: mov %rdi,%r14 30 2.2e-04 : 70b527: push %r13 2495 0.0185 : 70b529: push %r12 2631 0.0195 : 70b52b: mov %edx,%r12d 18 1.3e-04 : 70b52e: push %rbp 1277 0.0095 : 70b52f: push %rbx :static inline uint32 :calc_bucket(HASHHDR *hctl, uint32 hash_val) :{ : uint32 bucket; : : bucket = hash_val & hctl->high_mask; 2122 0.0157 : 70b530: mov %edx,%ebx :hash_search_with_hash_value(HTAB *hashp, : const void *keyPtr, : uint32 hashvalue, : HASHACTION action, : bool *foundPtr) :{ 247 0.0018 : 70b532: sub $0x58,%rsp 236 0.0017 : 70b536: mov %rsi,0x10(%rsp) 3851 0.0285 : 70b53b: mov %ecx,0xc(%rsp) 2551 0.0189 : 70b53f: mov %r8,(%rsp) : HASHHDR *hctl = hashp->hctl; 2225 0.0165 : 70b543: mov (%rdi),%r15 :static inline uint32 :calc_bucket(HASHHDR *hctl, uint32 hash_val) :{ : uint32 bucket; : : bucket = hash_val & hctl->high_mask; 4544 0.0337 : 70b546: and 0x2c(%r15),%ebx : if (bucket > hctl->max_bucket) 53409 0.3958 : 70b54a: cmp 0x28(%r15),%ebx : 70b54e: jbe 70b554 : bucket = bucket & hctl->low_mask; 3324 0.0246 : 70b550: and 0x30(%r15),%ebx : bucket = calc_bucket(hctl, hashvalue); : : segment_num = bucket >> hashp->sshift; : segment_ndx = MOD(bucket, hashp->ssize); : : segp = hashp->dir[segment_num]; 9702 0.0719 : 70b554: mov 0x58(%r14),%ecx 2428 0.0180 : 70b558: mov %ebx,%eax 489 0.0036 : 70b55a: mov 0x8(%r14),%rdx : * Do the initial lookup : */ : bucket = calc_bucket(hctl, hashvalue); : : segment_num = bucket >> hashp->sshift; : segment_ndx = MOD(bucket, hashp->ssize); 391 0.0029 : 70b55e: mov 0x50(%r14),%r13 : : segp = hashp->dir[segment_num]; 2062 0.0153 : 70b562: shr %cl,%eax 309 0.0023 : 70b564: mov %eax,%eax 643 0.0048 : 70b566: mov (%rdx,%rax,8),%rbp : : if (segp == NULL) 43329 0.3211 : 70b56a: test %rbp,%rbp 1284 0.0095 : 70b56d: je 70b727 : hash_corrupted(hashp); : : prevBucketPtr = &segp[segment_ndx]; 1878 0.0139 : 70b573: lea -0x1(%r13),%rax : currBucket = *prevBucketPtr; : : /* : * Follow collision chain looking for matching key : */ : match = hashp->match; /* save one fetch in inner loop */ 35 2.6e-04 : 70b577: mov 0x18(%r14),%r13 : segp = hashp->dir[segment_num]; : : if (segp == NULL) : hash_corrupted(hashp); : : prevBucketPtr = &segp[segment_ndx]; 41 3.0e-04 : 70b57b: and %ebx,%eax 434 0.0032 : 70b57d: lea 0x0(%rbp,%rax,8),%rbp : : /* : * Follow collision chain looking for matching key : */ : match = hashp->match; /* save one fetch in inner loop */ : keysize = hashp->keysize; /* ditto */ 2007 0.0149 : 70b582: mov 0x48(%r14),%rax : : if (segp == NULL) : hash_corrupted(hashp); : : prevBucketPtr = &segp[segment_ndx]; : currBucket = *prevBucketPtr; 122 9.0e-04 : 70b586: mov 0x0(%rbp),%rbx : : /* : * Follow collision chain looking for matching key : */ : match = hashp->match; /* save one fetch in inner loop */ : keysize = hashp->keysize; /* ditto */ 99903 0.7404 : 70b58a: mov %rax,0x18(%rsp) : : while (currBucket != NULL) 1066 0.0079 : 70b58f: test %rbx,%rbx : 70b592: jne 70b5ab 2273 0.0168 : 70b594: jmp 70b5d0 : 70b596: nopw %cs:0x0(%rax,%rax,1) : { : if (currBucket->hashvalue == hashvalue && : match(ELEMENTKEY(currBucket), keyPtr, keysize) == 0) : break; : prevBucketPtr = &(currBucket->link); 1362 0.0101 : 70b5a0: mov %rbx,%rbp : currBucket = *prevBucketPtr; 655 0.0049 : 70b5a3: mov (%rbx),%rbx : * Follow collision chain looking for matching key : */ : match = hashp->match; /* save one fetch in inner loop */ : keysize = hashp->keysize; /* ditto */ : : while (currBucket != NULL) 608 0.0045 : 70b5a6: test %rbx,%rbx : 70b5a9: je 70b5d0 : { : if (currBucket->hashvalue == hashvalue && 3504 0.0260 : 70b5ab: cmp %r12d,0x8(%rbx) 98486 0.7299 : 70b5af: nop 1233 0.0091 : 70b5b0: jne 70b5a0 1750 0.0130 : 70b5b2: lea 0x10(%rbx),%rdi 310 0.0023 : 70b5b6: mov 0x18(%rsp),%rdx 871 0.0065 : 70b5bb: mov 0x10(%rsp),%rsi 131 9.7e-04 : 70b5c0: callq *%r13 2031 0.0151 : 70b5c3: test %eax,%eax : 70b5c5: jne 70b5a0 822 0.0061 : 70b5c7: nopw 0x0(%rax,%rax,1) : hash_collisions++; : hctl->collisions++; :#endif : } : : if (foundPtr) 2268 0.0168 : 70b5d0: cmpq $0x0,(%rsp) 3831 0.0284 : 70b5d5: je 70b5e1 : *foundPtr = (bool) (currBucket != NULL); 1411 0.0105 : 70b5d7: mov (%rsp),%rdx 951 0.0070 : 70b5db: test %rbx,%rbx 125 9.3e-04 : 70b5de: setne (%rdx) : : /* : * OK, now what? : */ : switch (action) 4249 0.0315 : 70b5e1: cmpl $0x1,0xc(%rsp) 928 0.0069 : 70b5e6: je 70b650 656 0.0049 : 70b5e8: jae 70b610 : { : case HASH_FIND: : if (currBucket != NULL) 806 0.0060 : 70b5ea: test %rbx,%rbx 216 0.0016 : 70b5ed: je 70b78a : /* FALL THRU */ : : case HASH_ENTER: : /* Return existing element if found, else create one */ : if (currBucket != NULL) : return (void *) ELEMENTKEY(currBucket); 2059 0.0153 : 70b5f3: lea 0x10(%rbx),%r13 : } : : elog(ERROR, "unrecognized hash action code: %d", (int) action); : : return NULL; /* keep compiler quiet */ :} 1418 0.0105 : 70b5f7: add $0x58,%rsp 445 0.0033 : 70b5fb: mov %r13,%rax 516 0.0038 : 70b5fe: pop %rbx 2323 0.0172 : 70b5ff: pop %rbp 1023 0.0076 : 70b600: pop %r12 1208 0.0090 : 70b602: pop %r13 1149 0.0085 : 70b604: pop %r14 1806 0.0134 : 70b606: pop %r15 1349 0.0100 : 70b608: retq : 70b609: nopl 0x0(%rax) : *foundPtr = (bool) (currBucket != NULL); : : /* : * OK, now what? : */ : switch (action) 1687 0.0125 : 70b610: cmpl $0x2,0xc(%rsp) 1815 0.0135 : 70b615: je 70b6d0 38 2.8e-04 : 70b61b: cmpl $0x3,0xc(%rsp) 34 2.5e-04 : 70b620: je 70b650 : } : : return (void *) ELEMENTKEY(currBucket); : } : : elog(ERROR, "unrecognized hash action code: %d", (int) action); : 70b622: mov $0x86b6c0,%edx : 70b627: mov $0x3c5,%esi : 70b62c: mov $0x86b493,%edi : 70b631: callq 7035f0 : 70b636: mov 0xc(%rsp),%edx : 70b63a: mov $0x86b5f0,%esi : 70b63f: mov $0x14,%edi : 70b644: xor %eax,%eax : 70b646: xor %r13d,%r13d : 70b649: callq 7033f0 : 70b64e: jmp 70b5f7 : Assert(hashp->alloc != DynaHashAlloc); : /* FALL THRU */ : : case HASH_ENTER: : /* Return existing element if found, else create one */ : if (currBucket != NULL) 3030 0.0225 : 70b650: test %rbx,%rbx : 70b653: jne 70b5f3 : return (void *) ELEMENTKEY(currBucket); : : /* disallow inserts if frozen */ : if (hashp->frozen) 2150 0.0159 : 70b655: cmpb $0x0,0x42(%r14) 1410 0.0104 : 70b65a: nopw 0x0(%rax,%rax,1) 11 8.2e-05 : 70b660: jne 70b998 : */ :static HASHBUCKET :get_hash_entry(HTAB *hashp) :{ : /* use volatile pointer to prevent code rearrangement */ : volatile HASHHDR *hctlv = hashp->hctl; 405 0.0030 : 70b666: mov (%r14),%rbx 251 0.0019 : 70b669: mov $0x1,%r13d 7 5.2e-05 : 70b66f: nop 2 1.5e-05 : 70b670: jmp 70b6a9 : 70b672: nopw 0x0(%rax,%rax,1) : /* if partitioned, must lock to touch nentries and freeList */ : if (IS_PARTITIONED(hctlv)) : SpinLockAcquire(&hctlv->mutex); : : /* try to get an entry from the freelist */ : newElement = hctlv->freeList; 824 0.0061 : 70b678: mov 0x10(%rbx),%rcx : if (newElement != NULL) 5315 0.0394 : 70b67c: test %rcx,%rcx : /* if partitioned, must lock to touch nentries and freeList */ : if (IS_PARTITIONED(hctlv)) : SpinLockAcquire(&hctlv->mutex); : : /* try to get an entry from the freelist */ : newElement = hctlv->freeList; 242 0.0018 : 70b67f: mov %rcx,0x50(%rsp) : if (newElement != NULL) 559 0.0041 : 70b684: jne 70b9c6 : break; : : /* no free elements. allocate another chunk of buckets */ : if (IS_PARTITIONED(hctlv)) : 70b68a: mov 0x48(%rbx),%rax : 70b68e: test %rax,%rax : 70b691: je 70b696 : SpinLockRelease(&hctlv->mutex); : 70b693: movb $0x0,(%rbx) : : if (!element_alloc(hashp, hctlv->nelem_alloc)) : 70b696: mov 0x6c(%rbx),%esi : 70b699: mov %r14,%rdi : 70b69c: callq 70b370 : 70b6a1: test %al,%al : 70b6a3: je 70b7a9 : HASHBUCKET newElement; : : for (;;) : { : /* if partitioned, must lock to touch nentries and freeList */ : if (IS_PARTITIONED(hctlv)) 875 0.0065 : 70b6a9: mov 0x48(%rbx),%rax 2327 0.0172 : 70b6ad: test %rax,%rax 238 0.0018 : 70b6b0: je 70b678 137 0.0010 : 70b6b2: mov %r13d,%eax 88 6.5e-04 : 70b6b5: lock xchg %al,(%rbx) : SpinLockAcquire(&hctlv->mutex); 6001 0.0445 : 70b6b8: test %al,%al : 70b6ba: je 70b678 6 4.4e-05 : 70b6bc: mov $0x3d8,%edx 3 2.2e-05 : 70b6c1: mov $0x86b493,%esi : 70b6c6: mov %rbx,%rdi 1 7.4e-06 : 70b6c9: callq 6342c0 : 70b6ce: jmp 70b678 : if (currBucket != NULL) : return (void *) ELEMENTKEY(currBucket); : return NULL; : : case HASH_REMOVE: : if (currBucket != NULL) 4191 0.0311 : 70b6d0: test %rbx,%rbx : 70b6d3: je 70b78a : { : /* use volatile pointer to prevent code rearrangement */ : volatile HASHHDR *hctlv = hctl; : : /* if partitioned, must lock to touch nentries and freeList */ : if (IS_PARTITIONED(hctlv)) 1161 0.0086 : 70b6d9: mov 0x48(%r15),%rax 1912 0.0142 : 70b6dd: test %rax,%rax 176 0.0013 : 70b6e0: je 70b6f3 22 1.6e-04 : 70b6e2: mov $0x1,%eax 27 2.0e-04 : 70b6e7: lock xchg %al,(%r15) : SpinLockAcquire(&hctlv->mutex); 6770 0.0502 : 70b6eb: test %al,%al 18 1.3e-04 : 70b6ed: jne 70b792 : : Assert(hctlv->nentries > 0); : hctlv->nentries--; 1385 0.0103 : 70b6f3: mov 0x8(%r15),%rax 5134 0.0380 : 70b6f7: sub $0x1,%rax 220 0.0016 : 70b6fb: mov %rax,0x8(%r15) : : /* remove record from hash bucket's chain. */ : *prevBucketPtr = currBucket->link; 490 0.0036 : 70b6ff: mov (%rbx),%rax 2146 0.0159 : 70b702: mov %rax,0x0(%rbp) : : /* add the record to the freelist for this table. */ : currBucket->link = hctlv->freeList; 749 0.0056 : 70b706: mov 0x10(%r15),%rax 118 8.7e-04 : 70b70a: mov %rax,(%rbx) : hctlv->freeList = currBucket; 169 0.0013 : 70b70d: mov %rbx,0x10(%r15) : : if (IS_PARTITIONED(hctlv)) 244 0.0018 : 70b711: mov 0x48(%r15),%rax 44 3.3e-04 : 70b715: test %rax,%rax : 70b718: je 70b5f3 : SpinLockRelease(&hctlv->mutex); 22 1.6e-04 : 70b71e: movb $0x0,(%r15) 8 5.9e-05 : 70b722: jmpq 70b5f3 :{ : /* : * If the corruption is in a shared hashtable, we'd better force a : * systemwide restart. Otherwise, just shut down this one backend. : */ : if (hashp->isshared) : 70b727: cmpb $0x0,0x40(%r14) : 70b72c: je 70b75c : elog(PANIC, "hash table \"%s\" corrupted", hashp->tabname); : 70b72e: mov $0x86b6dc,%edx : 70b733: mov $0x569,%esi : 70b738: mov $0x86b493,%edi : 70b73d: callq 7035f0 : 70b742: mov 0x38(%r14),%rdx : 70b746: mov $0x86b49e,%esi : 70b74b: mov $0x16,%edi : 70b750: xor %eax,%eax : 70b752: callq 7033f0 : 70b757: jmpq 70b573 : else : elog(FATAL, "hash table \"%s\" corrupted", hashp->tabname); : 70b75c: mov $0x86b6dc,%edx : 70b761: mov $0x56b,%esi : 70b766: mov $0x86b493,%edi : 70b76b: callq 7035f0 : 70b770: mov 0x38(%r14),%rdx : 70b774: mov $0x86b49e,%esi : 70b779: mov $0x15,%edi : 70b77e: xor %eax,%eax : 70b780: callq 7033f0 : 70b785: jmpq 70b573 : return (void *) ELEMENTKEY(currBucket); : } : : elog(ERROR, "unrecognized hash action code: %d", (int) action); : : return NULL; /* keep compiler quiet */ 433 0.0032 : 70b78a: xor %r13d,%r13d 103 7.6e-04 : 70b78d: jmpq 70b5f7 : /* use volatile pointer to prevent code rearrangement */ : volatile HASHHDR *hctlv = hctl; : : /* if partitioned, must lock to touch nentries and freeList */ : if (IS_PARTITIONED(hctlv)) : SpinLockAcquire(&hctlv->mutex); 10 7.4e-05 : 70b792: mov $0x36f,%edx 5 3.7e-05 : 70b797: mov $0x86b493,%esi : 70b79c: mov %r15,%rdi 1 7.4e-06 : 70b79f: callq 6342c0 1 7.4e-06 : 70b7a4: jmpq 70b6f3 : : currBucket = get_hash_entry(hashp); : if (currBucket == NULL) : { : /* out of memory */ : if (action == HASH_ENTER_NULL) : 70b7a9: cmpl $0x3,0xc(%rsp) : 70b7ae: je 70b78a : return NULL; : /* report a generic message */ : if (hashp->isshared) : 70b7b0: cmpb $0x0,0x40(%r14) : 70b7b5: je 70bab1 : ereport(ERROR, : 70b7bb: xor %r8d,%r8d : 70b7be: mov $0x14,%edi : 70b7c3: mov $0x86b6c0,%ecx : 70b7c8: mov $0x3a0,%edx : 70b7cd: mov $0x86b493,%esi : 70b7d2: callq 702d60 : 70b7d7: test %al,%al : 70b7d9: mov $0x848307,%edi : 70b7de: jne 70bada : (errcode(ERRCODE_OUT_OF_MEMORY), : errmsg("out of shared memory"))); : else : ereport(ERROR, : 70b7e4: mov $0x10,%r13d : (errcode(ERRCODE_OUT_OF_MEMORY), : errmsg("out of memory"))); : } : : /* link into hashbucket chain */ : *prevBucketPtr = currBucket; 1997 0.0148 : 70b7ea: mov 0x50(%rsp),%rcx : currBucket->link = NULL; : : /* copy key into record */ : currBucket->hashvalue = hashvalue; : hashp->keycopy(ELEMENTKEY(currBucket), keyPtr, keysize); 1108 0.0082 : 70b7ef: mov %r13,%rdi : (errcode(ERRCODE_OUT_OF_MEMORY), : errmsg("out of memory"))); : } : : /* link into hashbucket chain */ : *prevBucketPtr = currBucket; 11 8.2e-05 : 70b7f2: mov %rcx,0x0(%rbp) : currBucket->link = NULL; 639 0.0047 : 70b7f6: movq $0x0,(%rcx) : : /* copy key into record */ : currBucket->hashvalue = hashvalue; 1539 0.0114 : 70b7fd: mov %r12d,0x8(%rcx) : hashp->keycopy(ELEMENTKEY(currBucket), keyPtr, keysize); 1262 0.0094 : 70b801: mov 0x18(%rsp),%rdx 191 0.0014 : 70b806: mov 0x10(%rsp),%rsi 157 0.0012 : 70b80b: callq *0x20(%r14) : * Check if it is time to split a bucket. Can't split if running : * in partitioned mode, nor if table is the subject of any active : * hash_seq_search scans. Strange order of these tests is to try : * to check cheaper conditions first. : */ : if (!IS_PARTITIONED(hctl) && 483 0.0036 : 70b80f: cmpq $0x0,0x48(%r15) 343 0.0025 : 70b814: jne 70b5f7 234 0.0017 : 70b81a: mov 0x28(%r15),%eax 127 9.4e-04 : 70b81e: mov 0x8(%r15),%rdx 257 0.0019 : 70b822: add $0x1,%eax 15 1.1e-04 : 70b825: mov %rax,%rcx 105 7.8e-04 : 70b828: mov %rdx,%rax 144 0.0011 : 70b82b: sar $0x3f,%rdx 165 0.0012 : 70b82f: idiv %rcx 12710 0.0942 : 70b832: cmp 0x50(%r15),%rax : 70b836: jl 70b5f7