First step to cleanup the power-of-2 mess.
authorbmeurer@chromium.org <bmeurer@chromium.org>
Tue, 2 Sep 2014 13:36:35 +0000 (13:36 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org>
Tue, 2 Sep 2014 13:36:35 +0000 (13:36 +0000)
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

45 files changed:
BUILD.gn
src/allocation.cc
src/arm/assembler-arm.cc
src/arm/code-stubs-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/arm64/assembler-arm64.cc
src/arm64/assembler-arm64.h
src/arm64/lithium-arm64.cc
src/arm64/lithium-codegen-arm64.cc
src/arm64/macro-assembler-arm64-inl.h
src/arm64/macro-assembler-arm64.cc
src/arm64/macro-assembler-arm64.h
src/base/bits-unittest.cc
src/base/bits.cc [new file with mode: 0644]
src/base/bits.h
src/base/macros.h
src/compiler/arm/instruction-selector-arm.cc
src/compiler/machine-type.h
src/compiler/representation-change.h
src/compiler/simplified-lowering.cc
src/conversions-inl.h
src/factory.cc
src/frames.cc
src/gdb-jit.cc
src/hashmap.h
src/heap/heap.cc
src/heap/mark-compact.h
src/heap/spaces.cc
src/heap/spaces.h
src/hydrogen-instructions.h
src/ia32/assembler-ia32.cc
src/ia32/code-stubs-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/macro-assembler-ia32.cc
src/ic/ic.cc
src/ic/stub-cache.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/utils.h
src/x64/assembler-x64.cc
src/x64/lithium-codegen-x64.cc
src/x64/macro-assembler-x64.cc
tools/gyp/v8.gyp

index 57a2542a36d6cea1e0585cf339a0e8c7a1ef4cbc..f604a3b181dfe3eaf9df9e4030c1782031ce5742 100644 (file)
--- a/BUILD.gn
+++ b/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",
index b5aa98416b6d917eabafe1bf670da1f14bb27d08..cae1c102515c1bdcf9b2ef253907e3000d475680 100644 (file)
@@ -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);
index e7b81cbb171aa5a1d18484e4e45f616aedff99d7..96f28f968391a8021e4e5b2b69a78ba0c9cf50c7 100644 (file)
@@ -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();
   }
index 8cdf6b995beeb0d55d70e113a846e12bccf93dfa..31355b686539571edf40ee478c0413ff93fd6a67 100644 (file)
@@ -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));
   }
 
index 6d920a395da3b1dcc79d1a913f33849ee7226c43..760773247387e0b884b66d20a67e016a06930b4e 100644 (file)
@@ -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 {
index 78324b191003bc5e915aefde34a0f8051cd20166..8d0ee0c7a9135e818a7a04cdb32815e1eca75a02 100644 (file)
@@ -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 {
index 9d804db17b9976e95f2ecbbb63022b0ef5e6a4ee..3aff8ef69170580c2f60505c267a0732c3a1aac6 100644 (file)
@@ -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
index 1bafce845483049704619b88cb43617d1c07a4cd..f01cbaf08946d89a93136971267f0c938add07f9 100644 (file)
@@ -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 ------------------------------------------------------
 
index 92c18a7c5635b4c18fba53c5054431e8b71710bb..28c618b7420bfa674468a4f0beadef8fc5d36e3d 100644 (file)
@@ -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 =
index 5d2014c8185c93ad75f525f790fae48811c2718d..7d4f88dbf32cd45f2ca9392c4ce0fdfe59edb495 100644 (file)
@@ -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);
index f7c724842ac55ffb1584d4770962fd0996306c3e..23767e48b371c78d5cbdd472c8f1cc5cbe5d35ba 100644 (file)
@@ -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),
index 063f53b5f6bf7bf38409ec955a962c6c0c2f5046..6f52cc73b3e8d11902e131451e3fac8f5e3a72a0 100644 (file)
@@ -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.
index aa83c7040fb130f1f5115e7d58fd36f145d010c1..1505800d891db4c901762dbf814e65ac46604fe8 100644 (file)
@@ -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);
   }
index 9113675556c73dba72538539a55012557d03afbc..188d14c533e182632ced2f2466a0e7cb824b6800 100644 (file)
@@ -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));
   }
diff --git a/src/base/bits.cc b/src/base/bits.cc
new file mode 100644 (file)
index 0000000..6daee53
--- /dev/null
@@ -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
index 04a0300a66542785b177cf60884e44ba52914e23..f271df9067d736e8ac512a9d13b15b04840291d3 100644 (file)
@@ -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));
index c313d76fd07f707aa4d5dd1dd8b47ef2f5a39a87..da6e2f6e04f210b2135c0d931be9c8079b408b70 100644 (file)
@@ -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() {
index 73e1aea9445ee89726fce2a821077de68e6915ae..bdfb7838b99244d70a7754dfbeca21ce5cae72f1 100644 (file)
@@ -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()),
index 6e749abb1596a5d067690ed0819292e96dc991e2..22513d984d6d6e00f0be7fa26345493be3af0d9e 100644 (file)
@@ -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);
 }
 
index 8adab1ae461a8fb7270557adbb3d78ea1a8e9728..8194fcceea2c60a110955612b1e81bc8fefe35e3 100644 (file)
@@ -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);
     }
index b8e7d8d4b6b9428780fc73c2f77029e4a653725c..06df207149cccaf3d71405360b3695cf8fd093d0 100644 (file)
@@ -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;
   }
 
index ce3054ba3126e19c6ce3e676285b14289bd58463..c0c788334f6556f0f8f4dc1dd89bb58f03293a23 100644 (file)
@@ -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>(
index 13cba9d6bb4e564428ac488a2c60ee39edd2c6c8..85713ee23f26a8239be20f344d515c8965fe7b04 100644 (file)
@@ -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();
index a4e77ff5561aeed691c5a7d055770cb91fb01d0b..01c0a4960ec66036abdc6754ce4cbbeeec80eba8 100644 (file)
@@ -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);
index c9a57b5fa0f8ade67968f3c46b10c550b4822505..776c662b01ce4e65b02be91fb3d28f19bb9ad420 100644 (file)
@@ -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_;
 };
 
index 26dbd584736e5afb8bb52a4fb025f551bf328444..33eb115258b4eaa6f0079fb0ceaec0b2cc4bce3c 100644 (file)
@@ -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");
index 6781711defa7fdb90813f2109a3ac25a11cc67a8..65ad7bc98a719347b981a8f7bd72131069b4f210 100644 (file)
@@ -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;
index f7075d6e69afbab8bca89cfa607490283a9012ee..c5087b4ea6a0fd1ebb93f13e48d0df7632d798dd 100644 (file)
@@ -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;
   }
index f91181e03661a927c53b0e7f9cf99f431fa9461b..ca0907359fece6101d110f3fd1dd5ed861b4c424 100644 (file)
@@ -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);
index 16261b3670d40311cd8feae8b75f0e7d3a7b7c40..cc7e63001b7abf620adcf4828499030e1ed636c1 100644 (file)
@@ -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;
index 5ddf6c584b507cdb19fa52b47f6c0f1e1f48eaf0..d866630b19ad944c9deb4201bdc52eda49d310ee 100644 (file)
@@ -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)
index d8cd59cf50433b59fc97a43eef6d26b823ff8c79..5dc733ad9b90f20df178217c5d8e6812a9b507d3 100644 (file)
@@ -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);
index 18dc9e1dddb7815cf0ca12a87453ff7ae4fb48de..16169b435ef14d82603d05a4c0f6930a519277eb 100644 (file)
@@ -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)));
index 1f40bf7a083ba0f35e5cd09274cca8293de69986..7556e6cf9ac6cddb2489d9dd42348837ae7886c4 100644 (file)
@@ -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 {
index 918775dcdb87045bcbafd33e5d39abd993603990..16bc4d27a453ac0cee60345c00814c720a2337cd 100644 (file)
@@ -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 {
index 5b7382f79a57ca6579332567a7a643161efe9c63..a7a04518f64ee794205b2b1d59d49da5b8dead07 100644 (file)
@@ -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);
index e63fbfe9e50c1991056e3e69ce70dcc01742b7a2..35a4acf8cc3a73bf50e1f665cba9a8baa230b15b 100644 (file)
@@ -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();
 }
 
index 53820e0f4f7ea4a862284b32a847f89eea90f886..c49bfc8b9e74a11346820590dc2a4fa0ecfa7384 100644 (file)
@@ -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.
   }
index beeb7d33f80aca3f822a55239249fd311efc447f..d2943f9f6dfed04b0b1b5e6ca86bdd56d4273f5a 100644 (file)
@@ -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);
   }
index 730e56d5f01b258a2706ea29fbdc97b3281fbda4..7a4ff33050e8845c2bb633d3083f587ed1453d8b 100644 (file)
@@ -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);
   }
 
index c5012bbc25516652d802ba05f4f3ce390ac5506b..ebc33ba2651f425caa9e96b0c030f478660bee6b 100644 (file)
@@ -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;
index d13c21f4b7c17a2c044d7eee052df85c95797a4a..4325c60ea0caae36e6f67e91c5752b4135aeef69 100644 (file)
@@ -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);
 }
index 74bb1327483111248f7381b6a1c35894ee6fd412..479c10127b67fd5876e4ec3dc3f2ff69025f293c 100644 (file)
@@ -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());
index a6d5113492c80cd11d9f60c6bab9c87dd85a816c..aee3e9efe5bce58957fa347b0947f25452edbaab 100644 (file)
@@ -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));
index f38a67d8b4769019a53149165f91110a6e333ed3..6c6ad6894de495b3a64b42ad0889a9f438ff7721 100644 (file)
         '../../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',