First step to cleanup the power-of-2 mess.
TEST=base-unittests,cctest,mjsunit R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/528993002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23617 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
baf818b152
commit
7d0d01005c
1
BUILD.gn
1
BUILD.gn
@ -1175,6 +1175,7 @@ source_set("v8_libbase") {
|
||||
"src/base/atomicops_internals_x86_gcc.cc",
|
||||
"src/base/atomicops_internals_x86_gcc.h",
|
||||
"src/base/atomicops_internals_x86_msvc.h",
|
||||
"src/base/bits.cc",
|
||||
"src/base/bits.h",
|
||||
"src/base/build_config.h",
|
||||
"src/base/cpu.cc",
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/allocation.h"
|
||||
|
||||
#include <stdlib.h> // For free, malloc.
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/logging.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "src/utils.h"
|
||||
@ -83,7 +84,8 @@ char* StrNDup(const char* str, int n) {
|
||||
|
||||
|
||||
void* AlignedAlloc(size_t size, size_t alignment) {
|
||||
DCHECK(IsPowerOf2(alignment) && alignment >= V8_ALIGNOF(void*)); // NOLINT
|
||||
DCHECK_LE(V8_ALIGNOF(void*), alignment);
|
||||
DCHECK(base::bits::IsPowerOfTwo32(alignment));
|
||||
void* ptr;
|
||||
#if V8_OS_WIN
|
||||
ptr = _aligned_malloc(size, alignment);
|
||||
|
@ -39,6 +39,7 @@
|
||||
#if V8_TARGET_ARCH_ARM
|
||||
|
||||
#include "src/arm/assembler-arm-inl.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/cpu.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/serialize.h"
|
||||
@ -498,7 +499,7 @@ void Assembler::GetCode(CodeDesc* desc) {
|
||||
|
||||
|
||||
void Assembler::Align(int m) {
|
||||
DCHECK(m >= 4 && IsPowerOf2(m));
|
||||
DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
|
||||
while ((pc_offset() & (m - 1)) != 0) {
|
||||
nop();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_ARM
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/codegen.h"
|
||||
@ -2953,7 +2954,7 @@ void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
|
||||
// Fast case of Heap::LookupSingleCharacterStringFromCode.
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
STATIC_ASSERT(kSmiShiftSize == 0);
|
||||
DCHECK(IsPowerOf2(String::kMaxOneByteCharCode + 1));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1));
|
||||
__ tst(code_,
|
||||
Operand(kSmiTagMask |
|
||||
((~String::kMaxOneByteCharCode) << kSmiTagSize)));
|
||||
@ -4393,7 +4394,7 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
|
||||
int frame_alignment = masm->ActivationFrameAlignment();
|
||||
if (frame_alignment > kPointerSize) {
|
||||
__ mov(r5, sp);
|
||||
DCHECK(IsPowerOf2(frame_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
|
||||
__ and_(sp, sp, Operand(-frame_alignment));
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/arm/lithium-codegen-arm.h"
|
||||
#include "src/arm/lithium-gap-resolver-arm.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/hydrogen-osr.h"
|
||||
|
||||
@ -1309,7 +1310,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
|
||||
Register dividend = ToRegister(instr->dividend());
|
||||
int32_t divisor = instr->divisor();
|
||||
Register result = ToRegister(instr->result());
|
||||
DCHECK(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
|
||||
DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
|
||||
DCHECK(!result.is(dividend));
|
||||
|
||||
// Check for (0 / -x) that will produce negative zero.
|
||||
@ -1666,17 +1667,17 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
||||
int32_t mask = constant >> 31;
|
||||
uint32_t constant_abs = (constant + mask) ^ mask;
|
||||
|
||||
if (IsPowerOf2(constant_abs)) {
|
||||
if (base::bits::IsPowerOfTwo32(constant_abs)) {
|
||||
int32_t shift = WhichPowerOf2(constant_abs);
|
||||
__ mov(result, Operand(left, LSL, shift));
|
||||
// Correct the sign of the result is the constant is negative.
|
||||
if (constant < 0) __ rsb(result, result, Operand::Zero());
|
||||
} else if (IsPowerOf2(constant_abs - 1)) {
|
||||
} else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) {
|
||||
int32_t shift = WhichPowerOf2(constant_abs - 1);
|
||||
__ add(result, left, Operand(left, LSL, shift));
|
||||
// Correct the sign of the result is the constant is negative.
|
||||
if (constant < 0) __ rsb(result, result, Operand::Zero());
|
||||
} else if (IsPowerOf2(constant_abs + 1)) {
|
||||
} else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) {
|
||||
int32_t shift = WhichPowerOf2(constant_abs + 1);
|
||||
__ rsb(result, left, Operand(left, LSL, shift));
|
||||
// Correct the sign of the result is the constant is negative.
|
||||
@ -5119,8 +5120,8 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
|
||||
uint8_t tag;
|
||||
instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
|
||||
|
||||
if (IsPowerOf2(mask)) {
|
||||
DCHECK(tag == 0 || IsPowerOf2(tag));
|
||||
if (base::bits::IsPowerOfTwo32(mask)) {
|
||||
DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
|
||||
__ tst(scratch, Operand(mask));
|
||||
DeoptimizeIf(tag == 0 ? ne : eq, instr->environment());
|
||||
} else {
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_ARM
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/cpu-profiler.h"
|
||||
@ -270,7 +271,7 @@ void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
|
||||
} else if (!(src2.instructions_required(this) == 1) &&
|
||||
!src2.must_output_reloc_info(this) &&
|
||||
CpuFeatures::IsSupported(ARMv7) &&
|
||||
IsPowerOf2(src2.immediate() + 1)) {
|
||||
base::bits::IsPowerOfTwo32(src2.immediate() + 1)) {
|
||||
ubfx(dst, src1, 0,
|
||||
WhichPowerOf2(static_cast<uint32_t>(src2.immediate()) + 1), cond);
|
||||
} else {
|
||||
@ -1074,7 +1075,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
|
||||
const int frame_alignment = MacroAssembler::ActivationFrameAlignment();
|
||||
sub(sp, sp, Operand((stack_space + 1) * kPointerSize));
|
||||
if (frame_alignment > 0) {
|
||||
DCHECK(IsPowerOf2(frame_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
|
||||
and_(sp, sp, Operand(-frame_alignment));
|
||||
}
|
||||
|
||||
@ -3488,7 +3489,7 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
|
||||
// and the original value of sp.
|
||||
mov(scratch, sp);
|
||||
sub(sp, sp, Operand((stack_passed_arguments + 1) * kPointerSize));
|
||||
DCHECK(IsPowerOf2(frame_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
|
||||
and_(sp, sp, Operand(-frame_alignment));
|
||||
str(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
|
||||
} else {
|
||||
|
@ -33,6 +33,7 @@
|
||||
#define ARM64_DEFINE_REG_STATICS
|
||||
|
||||
#include "src/arm64/assembler-arm64-inl.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/cpu.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -601,7 +602,7 @@ void Assembler::GetCode(CodeDesc* desc) {
|
||||
|
||||
|
||||
void Assembler::Align(int m) {
|
||||
DCHECK(m >= 4 && IsPowerOf2(m));
|
||||
DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
|
||||
while ((pc_offset() & (m - 1)) != 0) {
|
||||
nop();
|
||||
}
|
||||
@ -2208,6 +2209,17 @@ void Assembler::brk(int code) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::EmitStringData(const char* string) {
|
||||
size_t len = strlen(string) + 1;
|
||||
DCHECK(RoundUp(len, kInstructionSize) <= static_cast<size_t>(kGap));
|
||||
EmitData(string, len);
|
||||
// Pad with NULL characters until pc_ is aligned.
|
||||
const char pad[] = {'\0', '\0', '\0', '\0'};
|
||||
STATIC_ASSERT(sizeof(pad) == kInstructionSize);
|
||||
EmitData(pad, RoundUp(pc_offset(), kInstructionSize) - pc_offset());
|
||||
}
|
||||
|
||||
|
||||
void Assembler::debug(const char* message, uint32_t code, Instr params) {
|
||||
#ifdef USE_SIMULATOR
|
||||
// Don't generate simulator specific code if we are building a snapshot, which
|
||||
|
@ -1733,16 +1733,7 @@ class Assembler : public AssemblerBase {
|
||||
// Copy a string into the instruction stream, including the terminating NULL
|
||||
// character. The instruction pointer (pc_) is then aligned correctly for
|
||||
// subsequent instructions.
|
||||
void EmitStringData(const char * string) {
|
||||
size_t len = strlen(string) + 1;
|
||||
DCHECK(RoundUp(len, kInstructionSize) <= static_cast<size_t>(kGap));
|
||||
EmitData(string, len);
|
||||
// Pad with NULL characters until pc_ is aligned.
|
||||
const char pad[] = {'\0', '\0', '\0', '\0'};
|
||||
STATIC_ASSERT(sizeof(pad) == kInstructionSize);
|
||||
byte* next_pc = AlignUp(pc_, kInstructionSize);
|
||||
EmitData(&pad, next_pc - pc_);
|
||||
}
|
||||
void EmitStringData(const char* string);
|
||||
|
||||
// Pseudo-instructions ------------------------------------------------------
|
||||
|
||||
|
@ -1937,12 +1937,12 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
||||
int32_t constant_abs = Abs(constant);
|
||||
|
||||
if (!end_range_constant &&
|
||||
(small_constant ||
|
||||
(IsPowerOf2(constant_abs)) ||
|
||||
(!can_overflow && (IsPowerOf2(constant_abs + 1) ||
|
||||
IsPowerOf2(constant_abs - 1))))) {
|
||||
(small_constant || (base::bits::IsPowerOfTwo32(constant_abs)) ||
|
||||
(!can_overflow && (base::bits::IsPowerOfTwo32(constant_abs + 1) ||
|
||||
base::bits::IsPowerOfTwo32(constant_abs - 1))))) {
|
||||
LConstantOperand* right = UseConstant(most_const);
|
||||
bool need_register = IsPowerOf2(constant_abs) && !small_constant;
|
||||
bool need_register =
|
||||
base::bits::IsPowerOfTwo32(constant_abs) && !small_constant;
|
||||
LOperand* left = need_register ? UseRegister(least_const)
|
||||
: UseRegisterAtStart(least_const);
|
||||
LInstruction* result =
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/arm64/lithium-codegen-arm64.h"
|
||||
#include "src/arm64/lithium-gap-resolver-arm64.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/hydrogen-osr.h"
|
||||
|
||||
@ -2236,7 +2237,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
|
||||
uint8_t tag;
|
||||
instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
|
||||
|
||||
if (IsPowerOf2(mask)) {
|
||||
if (base::bits::IsPowerOfTwo32(mask)) {
|
||||
DCHECK((tag == 0) || (tag == mask));
|
||||
if (tag == 0) {
|
||||
DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr->environment());
|
||||
@ -2669,7 +2670,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
|
||||
Register dividend = ToRegister32(instr->dividend());
|
||||
int32_t divisor = instr->divisor();
|
||||
Register result = ToRegister32(instr->result());
|
||||
DCHECK(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
|
||||
DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
|
||||
DCHECK(!result.is(dividend));
|
||||
|
||||
// Check for (0 / -x) that will produce negative zero.
|
||||
@ -4360,7 +4361,7 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) {
|
||||
// can be done efficiently with shifted operands.
|
||||
int32_t right_abs = Abs(right);
|
||||
|
||||
if (IsPowerOf2(right_abs)) {
|
||||
if (base::bits::IsPowerOfTwo32(right_abs)) {
|
||||
int right_log2 = WhichPowerOf2(right_abs);
|
||||
|
||||
if (can_overflow) {
|
||||
@ -4393,10 +4394,10 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) {
|
||||
DCHECK(!can_overflow);
|
||||
|
||||
if (right >= 0) {
|
||||
if (IsPowerOf2(right - 1)) {
|
||||
if (base::bits::IsPowerOfTwo32(right - 1)) {
|
||||
// result = left + left << log2(right - 1)
|
||||
__ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1)));
|
||||
} else if (IsPowerOf2(right + 1)) {
|
||||
} else if (base::bits::IsPowerOfTwo32(right + 1)) {
|
||||
// result = -left + left << log2(right + 1)
|
||||
__ Sub(result, left, Operand(left, LSL, WhichPowerOf2(right + 1)));
|
||||
__ Neg(result, result);
|
||||
@ -4404,10 +4405,10 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
if (IsPowerOf2(-right + 1)) {
|
||||
if (base::bits::IsPowerOfTwo32(-right + 1)) {
|
||||
// result = left - left << log2(-right + 1)
|
||||
__ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1)));
|
||||
} else if (IsPowerOf2(-right - 1)) {
|
||||
} else if (base::bits::IsPowerOfTwo32(-right - 1)) {
|
||||
// result = -left - left << log2(-right - 1)
|
||||
__ Add(result, left, Operand(left, LSL, WhichPowerOf2(-right - 1)));
|
||||
__ Neg(result, result);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/arm64/assembler-arm64.h"
|
||||
#include "src/arm64/instrument-arm64.h"
|
||||
#include "src/arm64/macro-assembler-arm64.h"
|
||||
#include "src/base/bits.h"
|
||||
|
||||
|
||||
namespace v8 {
|
||||
@ -1520,7 +1521,7 @@ void MacroAssembler::Claim(uint64_t count, uint64_t unit_size) {
|
||||
|
||||
void MacroAssembler::Claim(const Register& count, uint64_t unit_size) {
|
||||
if (unit_size == 0) return;
|
||||
DCHECK(IsPowerOf2(unit_size));
|
||||
DCHECK(base::bits::IsPowerOfTwo64(unit_size));
|
||||
|
||||
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
|
||||
const Operand size(count, LSL, shift);
|
||||
@ -1538,7 +1539,7 @@ void MacroAssembler::Claim(const Register& count, uint64_t unit_size) {
|
||||
|
||||
|
||||
void MacroAssembler::ClaimBySMI(const Register& count_smi, uint64_t unit_size) {
|
||||
DCHECK(unit_size == 0 || IsPowerOf2(unit_size));
|
||||
DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo64(unit_size));
|
||||
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
|
||||
const Operand size(count_smi,
|
||||
(shift >= 0) ? (LSL) : (LSR),
|
||||
@ -1578,7 +1579,7 @@ void MacroAssembler::Drop(uint64_t count, uint64_t unit_size) {
|
||||
|
||||
void MacroAssembler::Drop(const Register& count, uint64_t unit_size) {
|
||||
if (unit_size == 0) return;
|
||||
DCHECK(IsPowerOf2(unit_size));
|
||||
DCHECK(base::bits::IsPowerOfTwo64(unit_size));
|
||||
|
||||
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits);
|
||||
const Operand size(count, LSL, shift);
|
||||
@ -1599,7 +1600,7 @@ void MacroAssembler::Drop(const Register& count, uint64_t unit_size) {
|
||||
|
||||
|
||||
void MacroAssembler::DropBySMI(const Register& count_smi, uint64_t unit_size) {
|
||||
DCHECK(unit_size == 0 || IsPowerOf2(unit_size));
|
||||
DCHECK(unit_size == 0 || base::bits::IsPowerOfTwo64(unit_size));
|
||||
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits) - kSmiShift;
|
||||
const Operand size(count_smi,
|
||||
(shift >= 0) ? (LSL) : (LSR),
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_ARM64
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/cpu-profiler.h"
|
||||
@ -2059,7 +2060,7 @@ void MacroAssembler::CallCFunction(Register function,
|
||||
int sp_alignment = ActivationFrameAlignment();
|
||||
// The ABI mandates at least 16-byte alignment.
|
||||
DCHECK(sp_alignment >= 16);
|
||||
DCHECK(IsPowerOf2(sp_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(sp_alignment));
|
||||
|
||||
// The current stack pointer is a callee saved register, and is preserved
|
||||
// across the call.
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/globals.h"
|
||||
|
||||
#include "src/arm64/assembler-arm64-inl.h"
|
||||
#include "src/base/bits.h"
|
||||
|
||||
// Simulator specific helpers.
|
||||
#if USE_SIMULATOR
|
||||
@ -808,7 +809,7 @@ class MacroAssembler : public Assembler {
|
||||
int sp_alignment = ActivationFrameAlignment();
|
||||
// AAPCS64 mandates at least 16-byte alignment.
|
||||
DCHECK(sp_alignment >= 16);
|
||||
DCHECK(IsPowerOf2(sp_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(sp_alignment));
|
||||
Bic(csp, StackPointer(), sp_alignment - 1);
|
||||
SetStackPointer(csp);
|
||||
}
|
||||
|
@ -6,11 +6,17 @@
|
||||
#include "src/base/macros.h"
|
||||
#include "testing/gtest-support.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DISABLE_IN_RELEASE(Name) Name
|
||||
#else
|
||||
#define DISABLE_IN_RELEASE(Name) DISABLED_##Name
|
||||
#endif
|
||||
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
namespace bits {
|
||||
|
||||
TEST(BitsTest, CountPopulation32) {
|
||||
TEST(Bits, CountPopulation32) {
|
||||
EXPECT_EQ(0u, CountPopulation32(0));
|
||||
EXPECT_EQ(1u, CountPopulation32(1));
|
||||
EXPECT_EQ(8u, CountPopulation32(0x11111111));
|
||||
@ -20,7 +26,7 @@ TEST(BitsTest, CountPopulation32) {
|
||||
}
|
||||
|
||||
|
||||
TEST(BitsTest, CountLeadingZeros32) {
|
||||
TEST(Bits, CountLeadingZeros32) {
|
||||
EXPECT_EQ(32u, CountLeadingZeros32(0));
|
||||
EXPECT_EQ(31u, CountLeadingZeros32(1));
|
||||
TRACED_FORRANGE(uint32_t, shift, 0, 31) {
|
||||
@ -30,7 +36,7 @@ TEST(BitsTest, CountLeadingZeros32) {
|
||||
}
|
||||
|
||||
|
||||
TEST(BitsTest, CountTrailingZeros32) {
|
||||
TEST(Bits, CountTrailingZeros32) {
|
||||
EXPECT_EQ(32u, CountTrailingZeros32(0));
|
||||
EXPECT_EQ(31u, CountTrailingZeros32(0x80000000));
|
||||
TRACED_FORRANGE(uint32_t, shift, 0, 31) {
|
||||
@ -40,7 +46,60 @@ TEST(BitsTest, CountTrailingZeros32) {
|
||||
}
|
||||
|
||||
|
||||
TEST(BitsTest, RotateRight32) {
|
||||
TEST(Bits, IsPowerOfTwo32) {
|
||||
EXPECT_FALSE(IsPowerOfTwo32(0U));
|
||||
TRACED_FORRANGE(uint32_t, shift, 0, 31) {
|
||||
EXPECT_TRUE(IsPowerOfTwo32(1U << shift));
|
||||
EXPECT_FALSE(IsPowerOfTwo32((1U << shift) + 5U));
|
||||
EXPECT_FALSE(IsPowerOfTwo32(~(1U << shift)));
|
||||
}
|
||||
TRACED_FORRANGE(uint32_t, shift, 2, 31) {
|
||||
EXPECT_FALSE(IsPowerOfTwo32((1U << shift) - 1U));
|
||||
}
|
||||
EXPECT_FALSE(IsPowerOfTwo32(0xffffffff));
|
||||
}
|
||||
|
||||
|
||||
TEST(Bits, IsPowerOfTwo64) {
|
||||
EXPECT_FALSE(IsPowerOfTwo64(0U));
|
||||
TRACED_FORRANGE(uint32_t, shift, 0, 63) {
|
||||
EXPECT_TRUE(IsPowerOfTwo64(V8_UINT64_C(1) << shift));
|
||||
EXPECT_FALSE(IsPowerOfTwo64((V8_UINT64_C(1) << shift) + 5U));
|
||||
EXPECT_FALSE(IsPowerOfTwo64(~(V8_UINT64_C(1) << shift)));
|
||||
}
|
||||
TRACED_FORRANGE(uint32_t, shift, 2, 63) {
|
||||
EXPECT_FALSE(IsPowerOfTwo64((V8_UINT64_C(1) << shift) - 1U));
|
||||
}
|
||||
EXPECT_FALSE(IsPowerOfTwo64(V8_UINT64_C(0xffffffffffffffff)));
|
||||
}
|
||||
|
||||
|
||||
TEST(Bits, RoundUpToPowerOfTwo32) {
|
||||
TRACED_FORRANGE(uint32_t, shift, 0, 31) {
|
||||
EXPECT_EQ(1u << shift, RoundUpToPowerOfTwo32(1u << shift));
|
||||
}
|
||||
EXPECT_EQ(0u, RoundUpToPowerOfTwo32(0));
|
||||
EXPECT_EQ(4u, RoundUpToPowerOfTwo32(3));
|
||||
EXPECT_EQ(0x80000000u, RoundUpToPowerOfTwo32(0x7fffffffu));
|
||||
}
|
||||
|
||||
|
||||
TEST(BitsDeathTest, DISABLE_IN_RELEASE(RoundUpToPowerOfTwo32)) {
|
||||
ASSERT_DEATH({ RoundUpToPowerOfTwo32(0x80000001u); }, "0x80000000");
|
||||
}
|
||||
|
||||
|
||||
TEST(Bits, RoundDownToPowerOfTwo32) {
|
||||
TRACED_FORRANGE(uint32_t, shift, 0, 31) {
|
||||
EXPECT_EQ(1u << shift, RoundDownToPowerOfTwo32(1u << shift));
|
||||
}
|
||||
EXPECT_EQ(0u, RoundDownToPowerOfTwo32(0));
|
||||
EXPECT_EQ(4u, RoundDownToPowerOfTwo32(5));
|
||||
EXPECT_EQ(0x80000000u, RoundDownToPowerOfTwo32(0x80000001u));
|
||||
}
|
||||
|
||||
|
||||
TEST(Bits, RotateRight32) {
|
||||
TRACED_FORRANGE(uint32_t, shift, 0, 31) {
|
||||
EXPECT_EQ(0u, RotateRight32(0u, shift));
|
||||
}
|
||||
@ -50,7 +109,7 @@ TEST(BitsTest, RotateRight32) {
|
||||
}
|
||||
|
||||
|
||||
TEST(BitsTest, RotateRight64) {
|
||||
TEST(Bits, RotateRight64) {
|
||||
TRACED_FORRANGE(uint64_t, shift, 0, 63) {
|
||||
EXPECT_EQ(0u, RotateRight64(0u, shift));
|
||||
}
|
||||
|
25
src/base/bits.cc
Normal file
25
src/base/bits.cc
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/logging.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
namespace bits {
|
||||
|
||||
uint32_t RoundUpToPowerOfTwo32(uint32_t value) {
|
||||
DCHECK_LE(value, 0x80000000u);
|
||||
value = value - 1;
|
||||
value = value | (value >> 1);
|
||||
value = value | (value >> 2);
|
||||
value = value | (value >> 4);
|
||||
value = value | (value >> 8);
|
||||
value = value | (value >> 16);
|
||||
return value + 1;
|
||||
}
|
||||
|
||||
} // namespace bits
|
||||
} // namespace base
|
||||
} // namespace v8
|
@ -72,6 +72,37 @@ inline uint32_t CountTrailingZeros32(uint32_t value) {
|
||||
}
|
||||
|
||||
|
||||
// Returns true iff |value| is a power of 2.
|
||||
inline bool IsPowerOfTwo32(uint32_t value) {
|
||||
return value && !(value & (value - 1));
|
||||
}
|
||||
|
||||
|
||||
// Returns true iff |value| is a power of 2.
|
||||
inline bool IsPowerOfTwo64(uint64_t value) {
|
||||
return value && !(value & (value - 1));
|
||||
}
|
||||
|
||||
|
||||
// RoundUpToPowerOfTwo32(value) returns the smallest power of two which is
|
||||
// greater than or equal to |value|. If you pass in a |value| that is already a
|
||||
// power of two, it is returned as is. |value| must be less than or equal to
|
||||
// 0x80000000u. Implementation is from "Hacker's Delight" by Henry S. Warren,
|
||||
// Jr., figure 3-3, page 48, where the function is called clp2.
|
||||
uint32_t RoundUpToPowerOfTwo32(uint32_t value);
|
||||
|
||||
|
||||
// RoundDownToPowerOfTwo32(value) returns the greatest power of two which is
|
||||
// less than or equal to |value|. If you pass in a |value| that is already a
|
||||
// power of two, it is returned as is.
|
||||
inline uint32_t RoundDownToPowerOfTwo32(uint32_t value) {
|
||||
if (value > 0x80000000u) return 0x80000000u;
|
||||
uint32_t result = RoundUpToPowerOfTwo32(value);
|
||||
if (result > value) result >>= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
inline uint32_t RotateRight32(uint32_t value, uint32_t shift) {
|
||||
if (shift == 0) return value;
|
||||
return (value >> shift) | (value << (32 - shift));
|
||||
|
@ -188,14 +188,6 @@ inline void USE(T) { }
|
||||
#define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
|
||||
|
||||
|
||||
// Returns true iff x is a power of 2. Cannot be used with the maximally
|
||||
// negative value of the type T (the -1 overflows).
|
||||
template <typename T>
|
||||
inline bool IsPowerOf2(T x) {
|
||||
return IS_POWER_OF_TWO(x);
|
||||
}
|
||||
|
||||
|
||||
// Define our own macros for writing 64-bit constants. This is less fragile
|
||||
// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
|
||||
// works on compilers that don't have it (like MSVC).
|
||||
@ -268,7 +260,7 @@ inline T AddressFrom(intptr_t x) {
|
||||
// Return the largest multiple of m which is <= x.
|
||||
template <typename T>
|
||||
inline T RoundDown(T x, intptr_t m) {
|
||||
DCHECK(IsPowerOf2(m));
|
||||
DCHECK(IS_POWER_OF_TWO(m));
|
||||
return AddressFrom<T>(OffsetFrom(x) & -m);
|
||||
}
|
||||
|
||||
@ -280,46 +272,12 @@ inline T RoundUp(T x, intptr_t m) {
|
||||
}
|
||||
|
||||
|
||||
// Increment a pointer until it has the specified alignment.
|
||||
// This works like RoundUp, but it works correctly on pointer types where
|
||||
// sizeof(*pointer) might not be 1.
|
||||
template<class T>
|
||||
T AlignUp(T pointer, size_t alignment) {
|
||||
DCHECK(sizeof(pointer) == sizeof(uintptr_t));
|
||||
uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
|
||||
return reinterpret_cast<T>(RoundUp(pointer_raw, alignment));
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool IsAligned(T value, U alignment) {
|
||||
return (value & (alignment - 1)) == 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns the smallest power of two which is >= x. If you pass in a
|
||||
// number that is already a power of two, it is returned as is.
|
||||
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
|
||||
// figure 3-3, page 48, where the function is called clp2.
|
||||
inline uint32_t RoundUpToPowerOf2(uint32_t x) {
|
||||
DCHECK(x <= 0x80000000u);
|
||||
x = x - 1;
|
||||
x = x | (x >> 1);
|
||||
x = x | (x >> 2);
|
||||
x = x | (x >> 4);
|
||||
x = x | (x >> 8);
|
||||
x = x | (x >> 16);
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
|
||||
inline uint32_t RoundDownToPowerOf2(uint32_t x) {
|
||||
uint32_t rounded_up = RoundUpToPowerOf2(x);
|
||||
if (rounded_up > x) return rounded_up >> 1;
|
||||
return rounded_up;
|
||||
}
|
||||
|
||||
|
||||
// Returns current value of top of the stack. Works correctly with ASAN.
|
||||
DISABLE_ASAN
|
||||
inline uintptr_t GetCurrentStackPosition() {
|
||||
|
@ -596,14 +596,14 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
|
||||
Int32BinopMatcher m(node);
|
||||
if (m.right().HasValue() && m.right().Value() > 0) {
|
||||
int32_t value = m.right().Value();
|
||||
if (IsPowerOf2(value - 1)) {
|
||||
if (base::bits::IsPowerOfTwo32(value - 1)) {
|
||||
Emit(kArmAdd | AddressingModeField::encode(kMode_Operand2_R_LSL_I),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseRegister(m.left().node()),
|
||||
g.TempImmediate(WhichPowerOf2(value - 1)));
|
||||
return;
|
||||
}
|
||||
if (value < kMaxInt && IsPowerOf2(value + 1)) {
|
||||
if (value < kMaxInt && base::bits::IsPowerOfTwo32(value + 1)) {
|
||||
Emit(kArmRsb | AddressingModeField::encode(kMode_Operand2_R_LSL_I),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.UseRegister(m.left().node()),
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef V8_COMPILER_MACHINE_TYPE_H_
|
||||
#define V8_COMPILER_MACHINE_TYPE_H_
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/globals.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -82,7 +83,7 @@ inline MachineType TypeOf(MachineType machine_type) {
|
||||
// Gets only the representation of the given type.
|
||||
inline MachineType RepresentationOf(MachineType machine_type) {
|
||||
int result = machine_type & kRepMask;
|
||||
CHECK(IsPowerOf2(result));
|
||||
CHECK(base::bits::IsPowerOfTwo32(result));
|
||||
return static_cast<MachineType>(result);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_
|
||||
#define V8_COMPILER_REPRESENTATION_CHANGE_H_
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/compiler/js-graph.h"
|
||||
#include "src/compiler/machine-operator.h"
|
||||
#include "src/compiler/node-properties-inl.h"
|
||||
@ -34,7 +35,7 @@ class RepresentationChanger {
|
||||
|
||||
Node* GetRepresentationFor(Node* node, MachineTypeUnion output_type,
|
||||
MachineTypeUnion use_type) {
|
||||
if (!IsPowerOf2(output_type & kRepMask)) {
|
||||
if (!base::bits::IsPowerOfTwo32(output_type & kRepMask)) {
|
||||
// There should be only one output representation.
|
||||
return TypeError(node, output_type, use_type);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "src/compiler/simplified-lowering.h"
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/compiler/common-operator.h"
|
||||
#include "src/compiler/graph-inl.h"
|
||||
#include "src/compiler/node-properties-inl.h"
|
||||
@ -151,7 +152,8 @@ class RepresentationSelector {
|
||||
// Every node should have at most one output representation. Note that
|
||||
// phis can have 0, if they have not been used in a representation-inducing
|
||||
// instruction.
|
||||
DCHECK((output & kRepMask) == 0 || IsPowerOf2(output & kRepMask));
|
||||
DCHECK((output & kRepMask) == 0 ||
|
||||
base::bits::IsPowerOfTwo32(output & kRepMask));
|
||||
GetInfo(node)->output = output;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// Extra POSIX/ANSI functions for Win32/MSVC.
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "src/conversions.h"
|
||||
#include "src/double.h"
|
||||
@ -288,7 +289,7 @@ double InternalStringToInt(UnicodeCache* unicode_cache,
|
||||
return JunkStringValue();
|
||||
}
|
||||
|
||||
if (IsPowerOf2(radix)) {
|
||||
if (base::bits::IsPowerOfTwo32(radix)) {
|
||||
switch (radix) {
|
||||
case 2:
|
||||
return InternalStringToIntDouble<1>(
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/factory.h"
|
||||
|
||||
#include "src/allocation-site-scopes.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/conversions.h"
|
||||
#include "src/isolate-inl.h"
|
||||
#include "src/macro-assembler.h"
|
||||
@ -435,7 +436,8 @@ static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
|
||||
// when building the new string.
|
||||
if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
|
||||
// We can do this.
|
||||
DCHECK(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this.
|
||||
DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCodeU +
|
||||
1)); // because of this.
|
||||
Handle<SeqOneByteString> str =
|
||||
isolate->factory()->NewRawOneByteString(2).ToHandleChecked();
|
||||
uint8_t* dest = str->GetChars();
|
||||
|
@ -1501,7 +1501,7 @@ Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
|
||||
InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
|
||||
InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
|
||||
isolate_->counters()->pc_to_code()->Increment();
|
||||
DCHECK(IsPowerOf2(kInnerPointerToCodeCacheSize));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(kInnerPointerToCodeCacheSize));
|
||||
uint32_t hash = ComputeIntegerHash(
|
||||
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)),
|
||||
v8::internal::kZeroHashSeed);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifdef ENABLE_GDB_JIT_INTERFACE
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/compiler.h"
|
||||
@ -222,16 +223,11 @@ class MachOSection : public DebugSectionBase<MachOSectionHeader> {
|
||||
S_ATTR_PURE_INSTRUCTIONS = 0x80000000u
|
||||
};
|
||||
|
||||
MachOSection(const char* name,
|
||||
const char* segment,
|
||||
uintptr_t align,
|
||||
MachOSection(const char* name, const char* segment, uint32_t align,
|
||||
uint32_t flags)
|
||||
: name_(name),
|
||||
segment_(segment),
|
||||
align_(align),
|
||||
flags_(flags) {
|
||||
: name_(name), segment_(segment), align_(align), flags_(flags) {
|
||||
if (align_ != 0) {
|
||||
DCHECK(IsPowerOf2(align));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(align));
|
||||
align_ = WhichPowerOf2(align_);
|
||||
}
|
||||
}
|
||||
@ -259,7 +255,7 @@ class MachOSection : public DebugSectionBase<MachOSectionHeader> {
|
||||
private:
|
||||
const char* name_;
|
||||
const char* segment_;
|
||||
uintptr_t align_;
|
||||
uint32_t align_;
|
||||
uint32_t flags_;
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define V8_HASHMAP_H_
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/logging.h"
|
||||
#include "src/utils.h"
|
||||
|
||||
@ -239,7 +240,7 @@ typename TemplateHashMapImpl<AllocationPolicy>::Entry*
|
||||
TemplateHashMapImpl<AllocationPolicy>::Probe(void* key, uint32_t hash) {
|
||||
DCHECK(key != NULL);
|
||||
|
||||
DCHECK(IsPowerOf2(capacity_));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(capacity_));
|
||||
Entry* p = map_ + (hash & (capacity_ - 1));
|
||||
const Entry* end = map_end();
|
||||
DCHECK(map_ <= p && p < end);
|
||||
@ -259,7 +260,7 @@ typename TemplateHashMapImpl<AllocationPolicy>::Entry*
|
||||
template<class AllocationPolicy>
|
||||
void TemplateHashMapImpl<AllocationPolicy>::Initialize(
|
||||
uint32_t capacity, AllocationPolicy allocator) {
|
||||
DCHECK(IsPowerOf2(capacity));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(capacity));
|
||||
map_ = reinterpret_cast<Entry*>(allocator.New(capacity * sizeof(Entry)));
|
||||
if (map_ == NULL) {
|
||||
v8::internal::FatalProcessOutOfMemory("HashMap::Initialize");
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/accessors.h"
|
||||
#include "src/api.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/once.h"
|
||||
#include "src/base/utils/random-number-generator.h"
|
||||
#include "src/bootstrapper.h"
|
||||
@ -4854,8 +4855,10 @@ bool Heap::ConfigureHeap(int max_semi_space_size, int max_old_space_size,
|
||||
|
||||
// The new space size must be a power of two to support single-bit testing
|
||||
// for containment.
|
||||
max_semi_space_size_ = RoundUpToPowerOf2(max_semi_space_size_);
|
||||
reserved_semispace_size_ = RoundUpToPowerOf2(reserved_semispace_size_);
|
||||
max_semi_space_size_ =
|
||||
base::bits::RoundUpToPowerOfTwo32(max_semi_space_size_);
|
||||
reserved_semispace_size_ =
|
||||
base::bits::RoundUpToPowerOfTwo32(reserved_semispace_size_);
|
||||
|
||||
if (FLAG_min_semi_space_size > 0) {
|
||||
int initial_semispace_size = FLAG_min_semi_space_size * MB;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef V8_HEAP_MARK_COMPACT_H_
|
||||
#define V8_HEAP_MARK_COMPACT_H_
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/heap/spaces.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -145,7 +146,9 @@ class MarkingDeque {
|
||||
HeapObject** obj_low = reinterpret_cast<HeapObject**>(low);
|
||||
HeapObject** obj_high = reinterpret_cast<HeapObject**>(high);
|
||||
array_ = obj_low;
|
||||
mask_ = RoundDownToPowerOf2(static_cast<int>(obj_high - obj_low)) - 1;
|
||||
mask_ = base::bits::RoundDownToPowerOfTwo32(
|
||||
static_cast<uint32_t>(obj_high - obj_low)) -
|
||||
1;
|
||||
top_ = bottom_ = 0;
|
||||
overflowed_ = false;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "src/full-codegen.h"
|
||||
#include "src/heap/mark-compact.h"
|
||||
@ -1190,7 +1191,7 @@ bool NewSpace::SetUp(int reserved_semispace_capacity,
|
||||
LOG(heap()->isolate(), NewEvent("InitialChunk", chunk_base_, chunk_size_));
|
||||
|
||||
DCHECK(initial_semispace_capacity <= maximum_semispace_capacity);
|
||||
DCHECK(IsPowerOf2(maximum_semispace_capacity));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(maximum_semispace_capacity));
|
||||
|
||||
// Allocate and set up the histogram arrays if necessary.
|
||||
allocated_histogram_ = NewArray<HistogramInfo>(LAST_TYPE + 1);
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/base/atomicops.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/platform/mutex.h"
|
||||
#include "src/hashmap.h"
|
||||
#include "src/list.h"
|
||||
@ -2620,7 +2621,7 @@ class MapSpace : public PagedSpace {
|
||||
static const int kMaxMapPageIndex = 1 << 16;
|
||||
|
||||
virtual int RoundSizeDownToObjectAlignment(int size) {
|
||||
if (IsPowerOf2(Map::kSize)) {
|
||||
if (base::bits::IsPowerOfTwo32(Map::kSize)) {
|
||||
return RoundDown(size, Map::kSize);
|
||||
} else {
|
||||
return (size / Map::kSize) * Map::kSize;
|
||||
@ -2655,7 +2656,7 @@ class CellSpace : public PagedSpace {
|
||||
: PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {}
|
||||
|
||||
virtual int RoundSizeDownToObjectAlignment(int size) {
|
||||
if (IsPowerOf2(Cell::kSize)) {
|
||||
if (base::bits::IsPowerOfTwo32(Cell::kSize)) {
|
||||
return RoundDown(size, Cell::kSize);
|
||||
} else {
|
||||
return (size / Cell::kSize) * Cell::kSize;
|
||||
@ -2680,7 +2681,7 @@ class PropertyCellSpace : public PagedSpace {
|
||||
: PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) {}
|
||||
|
||||
virtual int RoundSizeDownToObjectAlignment(int size) {
|
||||
if (IsPowerOf2(PropertyCell::kSize)) {
|
||||
if (base::bits::IsPowerOfTwo32(PropertyCell::kSize)) {
|
||||
return RoundDown(size, PropertyCell::kSize);
|
||||
} else {
|
||||
return (size / PropertyCell::kSize) * PropertyCell::kSize;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/conversions.h"
|
||||
#include "src/data-flow.h"
|
||||
@ -3845,7 +3846,10 @@ class HBinaryOperation : public HTemplateInstruction<3> {
|
||||
bool RightIsPowerOf2() {
|
||||
if (!right()->IsInteger32Constant()) return false;
|
||||
int32_t value = right()->GetInteger32Constant();
|
||||
return IsPowerOf2(value) || IsPowerOf2(-value);
|
||||
if (value < 0) {
|
||||
return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(-value));
|
||||
}
|
||||
return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value));
|
||||
}
|
||||
|
||||
DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/cpu.h"
|
||||
#include "src/disassembler.h"
|
||||
#include "src/macro-assembler.h"
|
||||
@ -271,7 +272,7 @@ void Assembler::GetCode(CodeDesc* desc) {
|
||||
|
||||
|
||||
void Assembler::Align(int m) {
|
||||
DCHECK(IsPowerOf2(m));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(m));
|
||||
int mask = m - 1;
|
||||
int addr = pc_offset();
|
||||
Nop((m - (addr & mask)) & mask);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/codegen.h"
|
||||
@ -2833,7 +2834,7 @@ void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
|
||||
// Fast case of Heap::LookupSingleCharacterStringFromCode.
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
STATIC_ASSERT(kSmiShiftSize == 0);
|
||||
DCHECK(IsPowerOf2(String::kMaxOneByteCharCode + 1));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1));
|
||||
__ test(code_,
|
||||
Immediate(kSmiTagMask |
|
||||
((~String::kMaxOneByteCharCode) << kSmiTagSize)));
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/deoptimizer.h"
|
||||
@ -1218,7 +1219,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
|
||||
Register dividend = ToRegister(instr->dividend());
|
||||
int32_t divisor = instr->divisor();
|
||||
Register result = ToRegister(instr->result());
|
||||
DCHECK(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
|
||||
DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
|
||||
DCHECK(!result.is(dividend));
|
||||
|
||||
// Check for (0 / -x) that will produce negative zero.
|
||||
@ -4903,8 +4904,8 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
|
||||
uint8_t tag;
|
||||
instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
|
||||
|
||||
if (IsPowerOf2(mask)) {
|
||||
DCHECK(tag == 0 || IsPowerOf2(tag));
|
||||
if (base::bits::IsPowerOfTwo32(mask)) {
|
||||
DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
|
||||
__ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask);
|
||||
DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
|
||||
} else {
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/cpu-profiler.h"
|
||||
@ -993,7 +994,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) {
|
||||
// Get the required frame alignment for the OS.
|
||||
const int kFrameAlignment = base::OS::ActivationFrameAlignment();
|
||||
if (kFrameAlignment > 0) {
|
||||
DCHECK(IsPowerOf2(kFrameAlignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment));
|
||||
and_(esp, -kFrameAlignment);
|
||||
}
|
||||
|
||||
@ -1934,7 +1935,7 @@ void MacroAssembler::BooleanBitTest(Register object,
|
||||
int field_offset,
|
||||
int bit_index) {
|
||||
bit_index += kSmiTagSize + kSmiShiftSize;
|
||||
DCHECK(IsPowerOf2(kBitsPerByte));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(kBitsPerByte));
|
||||
int byte_index = bit_index / kBitsPerByte;
|
||||
int byte_bit_index = bit_index & (kBitsPerByte - 1);
|
||||
test_b(FieldOperand(object, field_offset + byte_index),
|
||||
@ -2771,7 +2772,7 @@ void MacroAssembler::CheckStackAlignment() {
|
||||
int frame_alignment = base::OS::ActivationFrameAlignment();
|
||||
int frame_alignment_mask = frame_alignment - 1;
|
||||
if (frame_alignment > kPointerSize) {
|
||||
DCHECK(IsPowerOf2(frame_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
|
||||
Label alignment_as_expected;
|
||||
test(esp, Immediate(frame_alignment_mask));
|
||||
j(zero, &alignment_as_expected);
|
||||
@ -3011,7 +3012,7 @@ void MacroAssembler::PrepareCallCFunction(int num_arguments, Register scratch) {
|
||||
// and the original value of esp.
|
||||
mov(scratch, esp);
|
||||
sub(esp, Immediate((num_arguments + 1) * kPointerSize));
|
||||
DCHECK(IsPowerOf2(frame_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
|
||||
and_(esp, -frame_alignment);
|
||||
mov(Operand(esp, num_arguments * kPointerSize), scratch);
|
||||
} else {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/accessors.h"
|
||||
#include "src/api.h"
|
||||
#include "src/arguments.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/conversions.h"
|
||||
#include "src/execution.h"
|
||||
@ -2456,7 +2457,8 @@ void BinaryOpIC::State::Update(Handle<Object> left, Handle<Object> right,
|
||||
int32_t fixed_right_arg_value = 0;
|
||||
bool has_fixed_right_arg =
|
||||
op_ == Token::MOD && right->ToInt32(&fixed_right_arg_value) &&
|
||||
fixed_right_arg_value > 0 && IsPowerOf2(fixed_right_arg_value) &&
|
||||
fixed_right_arg_value > 0 &&
|
||||
base::bits::IsPowerOfTwo32(fixed_right_arg_value) &&
|
||||
FixedRightArgValueField::is_valid(WhichPowerOf2(fixed_right_arg_value)) &&
|
||||
(left_kind_ == SMI || left_kind_ == INT32) &&
|
||||
(result_kind_ == NONE || !fixed_right_arg_.has_value);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/ic/stub-cache.h"
|
||||
#include "src/type-info.h"
|
||||
|
||||
@ -15,8 +16,8 @@ StubCache::StubCache(Isolate* isolate) : isolate_(isolate) {}
|
||||
|
||||
|
||||
void StubCache::Initialize() {
|
||||
DCHECK(IsPowerOf2(kPrimaryTableSize));
|
||||
DCHECK(IsPowerOf2(kSecondaryTableSize));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(kPrimaryTableSize));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(kSecondaryTableSize));
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define V8_OBJECTS_INL_H_
|
||||
|
||||
#include "src/base/atomicops.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/contexts.h"
|
||||
#include "src/conversions-inl.h"
|
||||
#include "src/elements.h"
|
||||
@ -3095,7 +3096,7 @@ DescriptorArray::WhitenessWitness::~WhitenessWitness() {
|
||||
template<typename Derived, typename Shape, typename Key>
|
||||
int HashTable<Derived, Shape, Key>::ComputeCapacity(int at_least_space_for) {
|
||||
const int kMinCapacity = 32;
|
||||
int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
|
||||
int capacity = base::bits::RoundUpToPowerOfTwo32(at_least_space_for * 2);
|
||||
if (capacity < kMinCapacity) {
|
||||
capacity = kMinCapacity; // Guarantee min capacity.
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/allocation-site-scopes.h"
|
||||
#include "src/api.h"
|
||||
#include "src/arguments.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/codegen.h"
|
||||
@ -13784,7 +13785,7 @@ Handle<Derived> HashTable<Derived, Shape, Key>::New(
|
||||
MinimumCapacity capacity_option,
|
||||
PretenureFlag pretenure) {
|
||||
DCHECK(0 <= at_least_space_for);
|
||||
DCHECK(!capacity_option || IsPowerOf2(at_least_space_for));
|
||||
DCHECK(!capacity_option || base::bits::IsPowerOfTwo32(at_least_space_for));
|
||||
int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY)
|
||||
? at_least_space_for
|
||||
: ComputeCapacity(at_least_space_for);
|
||||
@ -15441,7 +15442,7 @@ Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
|
||||
// from number of buckets. If we decide to change kLoadFactor
|
||||
// to something other than 2, capacity should be stored as another
|
||||
// field of this object.
|
||||
capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity));
|
||||
capacity = base::bits::RoundUpToPowerOfTwo32(Max(kMinCapacity, capacity));
|
||||
if (capacity > kMaxCapacity) {
|
||||
v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/assert-scope.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/builtins.h"
|
||||
#include "src/checks.h"
|
||||
#include "src/elements-kind.h"
|
||||
@ -3694,7 +3695,7 @@ class HashTable: public FixedArray {
|
||||
|
||||
// Returns probe entry.
|
||||
static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) {
|
||||
DCHECK(IsPowerOf2(size));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(size));
|
||||
return (hash + GetProbeOffset(number)) & (size - 1);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "include/v8.h"
|
||||
#include "src/allocation.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/base/logging.h"
|
||||
#include "src/base/macros.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
@ -27,7 +28,7 @@ namespace internal {
|
||||
|
||||
// X must be a power of 2. Returns the number of trailing zeros.
|
||||
inline int WhichPowerOf2(uint32_t x) {
|
||||
DCHECK(IsPowerOf2(x));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(x));
|
||||
int bits = 0;
|
||||
#ifdef DEBUG
|
||||
int original_x = x;
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_X64
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/macro-assembler.h"
|
||||
#include "src/serialize.h"
|
||||
|
||||
@ -265,7 +266,7 @@ void Assembler::GetCode(CodeDesc* desc) {
|
||||
|
||||
|
||||
void Assembler::Align(int m) {
|
||||
DCHECK(IsPowerOf2(m));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(m));
|
||||
int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
|
||||
Nop(delta);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_X64
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/code-stubs.h"
|
||||
#include "src/hydrogen-osr.h"
|
||||
#include "src/x64/lithium-codegen-x64.h"
|
||||
@ -1273,7 +1274,7 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
|
||||
Register dividend = ToRegister(instr->dividend());
|
||||
int32_t divisor = instr->divisor();
|
||||
Register result = ToRegister(instr->result());
|
||||
DCHECK(divisor == kMinInt || IsPowerOf2(Abs(divisor)));
|
||||
DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
|
||||
DCHECK(!result.is(dividend));
|
||||
|
||||
// Check for (0 / -x) that will produce negative zero.
|
||||
@ -5095,8 +5096,8 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
|
||||
uint8_t tag;
|
||||
instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
|
||||
|
||||
if (IsPowerOf2(mask)) {
|
||||
DCHECK(tag == 0 || IsPowerOf2(tag));
|
||||
if (base::bits::IsPowerOfTwo32(mask)) {
|
||||
DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
|
||||
__ testb(FieldOperand(kScratchRegister, Map::kInstanceTypeOffset),
|
||||
Immediate(mask));
|
||||
DeoptimizeIf(tag == 0 ? not_zero : zero, instr->environment());
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#if V8_TARGET_ARCH_X64
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/cpu-profiler.h"
|
||||
@ -544,7 +545,7 @@ void MacroAssembler::CheckStackAlignment() {
|
||||
int frame_alignment = base::OS::ActivationFrameAlignment();
|
||||
int frame_alignment_mask = frame_alignment - 1;
|
||||
if (frame_alignment > kPointerSize) {
|
||||
DCHECK(IsPowerOf2(frame_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
|
||||
Label alignment_as_expected;
|
||||
testp(rsp, Immediate(frame_alignment_mask));
|
||||
j(zero, &alignment_as_expected, Label::kNear);
|
||||
@ -4101,7 +4102,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
|
||||
// Get the required frame alignment for the OS.
|
||||
const int kFrameAlignment = base::OS::ActivationFrameAlignment();
|
||||
if (kFrameAlignment > 0) {
|
||||
DCHECK(IsPowerOf2(kFrameAlignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment));
|
||||
DCHECK(is_int8(kFrameAlignment));
|
||||
andp(rsp, Immediate(-kFrameAlignment));
|
||||
}
|
||||
@ -4990,7 +4991,7 @@ void MacroAssembler::PrepareCallCFunction(int num_arguments) {
|
||||
|
||||
// Make stack end at alignment and allocate space for arguments and old rsp.
|
||||
movp(kScratchRegister, rsp);
|
||||
DCHECK(IsPowerOf2(frame_alignment));
|
||||
DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
|
||||
int argument_slots_on_stack =
|
||||
ArgumentStackSlotsForCFunctionCall(num_arguments);
|
||||
subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize));
|
||||
|
@ -1171,6 +1171,7 @@
|
||||
'../../src/base/atomicops_internals_x86_gcc.cc',
|
||||
'../../src/base/atomicops_internals_x86_gcc.h',
|
||||
'../../src/base/atomicops_internals_x86_msvc.h',
|
||||
'../../src/base/bits.cc',
|
||||
'../../src/base/bits.h',
|
||||
'../../src/base/build_config.h',
|
||||
'../../src/base/compiler-specific.h',
|
||||
|
Loading…
Reference in New Issue
Block a user