提交 4770dbcd 编写于 作者: O obdev 提交者: wangzelin.wzl

Add defense for builtin_clz/builtin_ctz in case that input is zero

上级 3a6db0a5
......@@ -79,11 +79,13 @@ private:
inline int calc_clz(const uint32_t s)
{
OB_ASSERT(0 != s);
return __builtin_clz(s);
}
inline int calc_clz(const uint64_t s)
{
OB_ASSERT(0ULL != s);
return __builtin_clzl(s);
}
......
......@@ -138,6 +138,7 @@ public:
private:
static uint64_t calc_shift(uint64_t capacity)
{
OB_ASSERT(0ULL != capacity);
return __builtin_clzll(capacity) + 1;
}
HashNode* locate(uint64_t hash)
......
......@@ -163,6 +163,7 @@ public:
private:
static uint64_t calc_n_cond(uint64_t capacity)
{
OB_ASSERT(0ULL != capacity);
return std::min(1024ULL, 1ULL << (63 - __builtin_clzll(capacity)));
}
uint64_t push_bounded(void* p, uint64_t limit)
......
......@@ -71,7 +71,7 @@ int32_t parse_string_to_int_array(const char* line, const char del, int32_t* arr
bool is2n(int64_t input);
constexpr int64_t next_pow2(const int64_t x)
{
return x ? (1ULL << (8 * sizeof(int64_t) - __builtin_clzll(x - 1))) : 1;
return x > 1LL ? (1ULL << (8 * sizeof(int64_t) - __builtin_clzll(x - 1))) : 1LL;
}
bool all_zero(const char* buffer, const int64_t size);
......
......@@ -80,6 +80,7 @@ void ObExprEstimateNdv::llc_estimate_ndv(int64_t& result, const ObString& bitmap
}
uint64_t ObExprEstimateNdv::llc_leading_zeros(uint64_t value, uint64_t bit_width)
{
OB_ASSERT(0ULL != value);
return std::min(bit_width, static_cast<uint64_t>(__builtin_clzll(value)));
}
......
......@@ -126,8 +126,9 @@ public:
typedef bool (*is_type_func)(common::ObObjType type);
static constexpr int flag2bit(uint64_t flag)
static int flag2bit(uint64_t flag)
{
OB_ASSERT(0ULL != flag);
return static_cast<int>(__builtin_ctzll(flag));
}
......
......@@ -1561,12 +1561,14 @@ void ObHashJoinOp::calc_cache_aware_partition_count()
int64_t tmp_partition_cnt_per_level = max_partition_count_per_level_;
if (total_partition_cnt > tmp_partition_cnt_per_level) {
level1_part_count_ = part_count_;
OB_ASSERT(0 != level1_part_count_);
level1_bit_ = __builtin_ctz(level1_part_count_);
level2_part_count_ = total_partition_cnt / level1_part_count_;
level2_part_count_ =
level2_part_count_ > tmp_partition_cnt_per_level ? tmp_partition_cnt_per_level : level2_part_count_;
} else {
level1_part_count_ = total_partition_cnt > part_count_ ? total_partition_cnt : part_count_;
OB_ASSERT(0 != level1_part_count_);
level1_bit_ = __builtin_ctz(level1_part_count_);
}
LOG_TRACE("partition count",
......@@ -2755,6 +2757,7 @@ int ObHashJoinOp::get_next_probe_partition()
}
} else {
// two level
OB_ASSERT(0 != level2_part_count_);
int64_t level1_part_idx = (cur_full_right_partition_ >> (__builtin_ctz(level2_part_count_)));
if (level1_part_idx < dump_part_count) {
cur_left_hist_ = &part_histograms_[cur_full_right_partition_];
......
......@@ -307,6 +307,8 @@ private:
void set_part_count(int64_t part_shift, int64_t level1_part_count, int64_t level2_part_count)
{
OB_ASSERT(0 != level1_part_count);
OB_ASSERT(0 != level2_part_count);
part_shift_ = part_shift;
level_one_part_count_ = level1_part_count;
level_two_part_count_ = level2_part_count;
......
......@@ -19,11 +19,6 @@
namespace oceanbase {
namespace storage {
constexpr int64_t next_pow2(const int64_t x)
{
return x ? (1ULL << (8 * sizeof(int64_t) - __builtin_clzll(x - 1))) : 1;
}
template <typename Key, typename Handle>
class ObHandleCacheNode : public common::ObDLinkBase<ObHandleCacheNode<Key, Handle>> {
public:
......@@ -125,7 +120,7 @@ public:
}
private:
static const uint64_t BUCKET_SIZE = next_pow2(N * 2);
static const uint64_t BUCKET_SIZE = common::next_pow2(N * 2);
static const uint64_t MASK = BUCKET_SIZE - 1;
CacheNode nodes_[N];
int16_t buckets_[BUCKET_SIZE];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册