Make class BitField able to use 32 bits of a uint32.

Although algorithmically correct, the compiler would not allow to instantiate
a BitField that uses all 32 bits without warnings about a too large shift
count. As a consequence we were limited to 31 bit values when using BitField.

This happened when instantiating a bitfield BitField<T, shift, size> with 
[shift=0, size=32] or [shift=31, size=1] or more general any 
[shift=X, size=32-X]

As side-effect of the new implementation the compiler now warns if we ever
try instantiating a bitfield with size 0.

Review URL: http://codereview.chromium.org/606063

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3910 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
fschneider@chromium.org 2010-02-19 10:02:04 +00:00
parent 62d62cb8e2
commit ec86513519
5 changed files with 10 additions and 8 deletions

View File

@ -518,14 +518,14 @@ class CallFunctionStub: public CodeStub {
} }
#endif #endif
// Minor key encoding in 31 bits AAAAAAAAAAAAAAAAAAAAAFI A(rgs)F(lag)I(nloop). // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
class InLoopBits: public BitField<InLoopFlag, 0, 1> {}; class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
class FlagBits: public BitField<CallFunctionFlags, 1, 1> {}; class FlagBits: public BitField<CallFunctionFlags, 1, 1> {};
class ArgcBits: public BitField<int, 2, 29> {}; class ArgcBits: public BitField<int, 2, 32 - 2> {};
Major MajorKey() { return CallFunction; } Major MajorKey() { return CallFunction; }
int MinorKey() { int MinorKey() {
// Encode the parameters in a unique 31 bit value. // Encode the parameters in a unique 32 bit value.
return InLoopBits::encode(in_loop_) return InLoopBits::encode(in_loop_)
| FlagBits::encode(flags_) | FlagBits::encode(flags_)
| ArgcBits::encode(argc_); | ArgcBits::encode(argc_);

View File

@ -250,7 +250,7 @@ class FrameElement BASE_EMBEDDED {
class CopiedField: public BitField<bool, 3, 1> {}; class CopiedField: public BitField<bool, 3, 1> {};
class SyncedField: public BitField<bool, 4, 1> {}; class SyncedField: public BitField<bool, 4, 1> {};
class NumberInfoField: public BitField<NumberInfo::Type, 5, 3> {}; class NumberInfoField: public BitField<NumberInfo::Type, 5, 3> {};
class DataField: public BitField<uint32_t, 8, 32 - 9> {}; class DataField: public BitField<uint32_t, 8, 32 - 8> {};
friend class VirtualFrame; friend class VirtualFrame;
}; };

View File

@ -179,7 +179,7 @@ class PropertyDetails BASE_EMBEDDED {
class TypeField: public BitField<PropertyType, 0, 3> {}; class TypeField: public BitField<PropertyType, 0, 3> {};
class AttributesField: public BitField<PropertyAttributes, 3, 3> {}; class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
class DeletedField: public BitField<uint32_t, 6, 1> {}; class DeletedField: public BitField<uint32_t, 6, 1> {};
class IndexField: public BitField<uint32_t, 7, 31-7> {}; class IndexField: public BitField<uint32_t, 7, 32-7> {};
static const int kInitialIndex = 1; static const int kInitialIndex = 1;
private: private:

View File

@ -141,7 +141,7 @@ class Result BASE_EMBEDDED {
class TypeField: public BitField<Type, 0, 2> {}; class TypeField: public BitField<Type, 0, 2> {};
class NumberInfoField : public BitField<NumberInfo::Type, 2, 3> {}; class NumberInfoField : public BitField<NumberInfo::Type, 2, 3> {};
class DataField: public BitField<uint32_t, 5, 32 - 6> {}; class DataField: public BitField<uint32_t, 5, 32 - 5> {};
inline void CopyTo(Result* destination) const; inline void CopyTo(Result* destination) const;

View File

@ -157,7 +157,9 @@ class BitField {
// Returns a uint32_t mask of bit field. // Returns a uint32_t mask of bit field.
static uint32_t mask() { static uint32_t mask() {
return (1U << (size + shift)) - (1U << shift); // To use all bits of a uint32 in a bitfield without compiler warnings we
// have to compute 2^32 without using a shift count of 32.
return ((1U << shift) << size) - (1U << shift);
} }
// Returns a uint32_t with the bit field value encoded. // Returns a uint32_t with the bit field value encoded.
@ -168,7 +170,7 @@ class BitField {
// Extracts the bit field from the value. // Extracts the bit field from the value.
static T decode(uint32_t value) { static T decode(uint32_t value) {
return static_cast<T>((value >> shift) & ((1U << (size)) - 1)); return static_cast<T>((value & mask()) >> shift);
} }
}; };