Commit c425a337 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[utils] Simplify chaining of BitFields

Instead of exposing a {kNext} constant to be used to construct the next
bitfield, expose a templatized {Next} type alias. This ensures that the
storage type is the same for all bitfields created this way. It's also
shorter.

Apart from the expected changes in the code base, the AST node classes
are changed to expose a {NextBitField} templated type alias instead of
a {kNextBitFieldIndex} constant. They thus follow the same pattern as
{BitField} itself.

R=jkummerow@chromium.org, mstarzinger@chromium.org, verwaest@chromium.org

Bug: v8:9396
Change-Id: I70a1b0bd71cde694ec53444de0ca55e4cf0a3836
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1728615Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63068}
parent cf81e875
This diff is collapsed.
...@@ -238,18 +238,14 @@ class Variable final : public ZoneObject { ...@@ -238,18 +238,14 @@ class Variable final : public ZoneObject {
} }
using VariableModeField = BitField16<VariableMode, 0, 4>; using VariableModeField = BitField16<VariableMode, 0, 4>;
using VariableKindField = using VariableKindField = VariableModeField::Next<VariableKind, 3>;
BitField16<VariableKind, VariableModeField::kNext, 3>; using LocationField = VariableKindField::Next<VariableLocation, 3>;
using LocationField = using ForceContextAllocationField = LocationField::Next<bool, 1>;
BitField16<VariableLocation, VariableKindField::kNext, 3>; using IsUsedField = ForceContextAllocationField::Next<bool, 1>;
using ForceContextAllocationField = BitField16<bool, LocationField::kNext, 1>; using InitializationFlagField = IsUsedField::Next<InitializationFlag, 1>;
using IsUsedField = BitField16<bool, ForceContextAllocationField::kNext, 1>; using ForceHoleInitializationField = InitializationFlagField::Next<bool, 1>;
using InitializationFlagField =
BitField16<InitializationFlag, IsUsedField::kNext, 1>;
using ForceHoleInitializationField =
BitField16<bool, InitializationFlagField::kNext, 1>;
using MaybeAssignedFlagField = using MaybeAssignedFlagField =
BitField16<MaybeAssignedFlag, ForceHoleInitializationField::kNext, 1>; ForceHoleInitializationField::Next<MaybeAssignedFlag, 1>;
Variable** next() { return &next_; } Variable** next() { return &next_; }
friend List; friend List;
......
...@@ -3909,7 +3909,7 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking( ...@@ -3909,7 +3909,7 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking(
Comment("Decrease construction counter"); Comment("Decrease construction counter");
// Slack tracking is only done on initial maps. // Slack tracking is only done on initial maps.
CSA_ASSERT(this, IsUndefined(LoadMapBackPointer(map))); CSA_ASSERT(this, IsUndefined(LoadMapBackPointer(map)));
STATIC_ASSERT(Map::ConstructionCounterBits::kNext == 32); STATIC_ASSERT(Map::ConstructionCounterBits::kLastUsedBit == 31);
Node* new_bit_field3 = Int32Sub( Node* new_bit_field3 = Int32Sub(
bit_field3, Int32Constant(1 << Map::ConstructionCounterBits::kShift)); bit_field3, Int32Constant(1 << Map::ConstructionCounterBits::kShift));
StoreObjectFieldNoWriteBarrier(map, Map::kBitField3Offset, new_bit_field3, StoreObjectFieldNoWriteBarrier(map, Map::kBitField3Offset, new_bit_field3,
......
...@@ -145,7 +145,7 @@ class LinkageLocation { ...@@ -145,7 +145,7 @@ class LinkageLocation {
enum LocationType { REGISTER, STACK_SLOT }; enum LocationType { REGISTER, STACK_SLOT };
using TypeField = BitField<LocationType, 0, 1>; using TypeField = BitField<LocationType, 0, 1>;
using LocationField = BitField<int32_t, TypeField::kNext, 31>; using LocationField = TypeField::Next<int32_t, 31>;
static constexpr int32_t ANY_REGISTER = -1; static constexpr int32_t ANY_REGISTER = -1;
static constexpr int32_t MAX_STACK_SLOT = 32767; static constexpr int32_t MAX_STACK_SLOT = 32767;
......
...@@ -581,8 +581,8 @@ class GlobalHandles::Node final : public NodeBase<GlobalHandles::Node> { ...@@ -581,8 +581,8 @@ class GlobalHandles::Node final : public NodeBase<GlobalHandles::Node> {
// This stores three flags (independent, partially_dependent and // This stores three flags (independent, partially_dependent and
// in_young_list) and a State. // in_young_list) and a State.
using NodeState = BitField8<State, 0, 3>; using NodeState = BitField8<State, 0, 3>;
using IsInYoungList = BitField8<bool, NodeState::kNext, 1>; using IsInYoungList = NodeState::Next<bool, 1>;
using NodeWeaknessType = BitField8<WeaknessType, IsInYoungList::kNext, 2>; using NodeWeaknessType = IsInYoungList::Next<WeaknessType, 2>;
// Handle specific callback - might be a weak reference in disguise. // Handle specific callback - might be a weak reference in disguise.
WeakCallbackInfo<void>::Callback weak_callback_; WeakCallbackInfo<void>::Callback weak_callback_;
...@@ -650,8 +650,8 @@ class GlobalHandles::TracedNode final ...@@ -650,8 +650,8 @@ class GlobalHandles::TracedNode final
protected: protected:
using NodeState = BitField8<State, 0, 2>; using NodeState = BitField8<State, 0, 2>;
using IsInYoungList = BitField8<bool, NodeState::kNext, 1>; using IsInYoungList = NodeState::Next<bool, 1>;
using IsRoot = BitField8<bool, IsInYoungList::kNext, 1>; using IsRoot = IsInYoungList::Next<bool, 1>;
void ClearImplFields() { void ClearImplFields() {
set_root(true); set_root(true);
......
...@@ -52,13 +52,12 @@ class LoadHandler final : public DataHandler { ...@@ -52,13 +52,12 @@ class LoadHandler final : public DataHandler {
// Defines whether access rights check should be done on receiver object. // Defines whether access rights check should be done on receiver object.
// Applicable to named property kinds only when loading value from prototype // Applicable to named property kinds only when loading value from prototype
// chain. Ignored when loading from holder. // chain. Ignored when loading from holder.
using DoAccessCheckOnReceiverBits = BitField<bool, KindBits::kNext, 1>; using DoAccessCheckOnReceiverBits = KindBits::Next<bool, 1>;
// Defines whether a lookup should be done on receiver object before // Defines whether a lookup should be done on receiver object before
// proceeding to the prototype chain. Applicable to named property kinds only // proceeding to the prototype chain. Applicable to named property kinds only
// when loading value from prototype chain. Ignored when loading from holder. // when loading value from prototype chain. Ignored when loading from holder.
using LookupOnReceiverBits = using LookupOnReceiverBits = DoAccessCheckOnReceiverBits::Next<bool, 1>;
BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1>;
// //
// Encoding when KindBits contains kForConstants. // Encoding when KindBits contains kForConstants.
...@@ -66,41 +65,40 @@ class LoadHandler final : public DataHandler { ...@@ -66,41 +65,40 @@ class LoadHandler final : public DataHandler {
// Index of a value entry in the descriptor array. // Index of a value entry in the descriptor array.
using DescriptorBits = using DescriptorBits =
BitField<unsigned, LookupOnReceiverBits::kNext, kDescriptorIndexBitCount>; LookupOnReceiverBits::Next<unsigned, kDescriptorIndexBitCount>;
// Make sure we don't overflow the smi. // Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize); STATIC_ASSERT(DescriptorBits::kLastUsedBit < kSmiValueSize);
// //
// Encoding when KindBits contains kField. // Encoding when KindBits contains kField.
// //
using IsInobjectBits = BitField<bool, LookupOnReceiverBits::kNext, 1>; using IsInobjectBits = LookupOnReceiverBits::Next<bool, 1>;
using IsDoubleBits = BitField<bool, IsInobjectBits::kNext, 1>; using IsDoubleBits = IsInobjectBits::Next<bool, 1>;
// +1 here is to cover all possible JSObject header sizes. // +1 here is to cover all possible JSObject header sizes.
using FieldIndexBits = using FieldIndexBits =
BitField<unsigned, IsDoubleBits::kNext, kDescriptorIndexBitCount + 1>; IsDoubleBits::Next<unsigned, kDescriptorIndexBitCount + 1>;
// Make sure we don't overflow the smi. // Make sure we don't overflow the smi.
STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize); STATIC_ASSERT(FieldIndexBits::kLastUsedBit < kSmiValueSize);
// //
// Encoding when KindBits contains kElement or kIndexedString. // Encoding when KindBits contains kElement or kIndexedString.
// //
using AllowOutOfBoundsBits = BitField<bool, LookupOnReceiverBits::kNext, 1>; using AllowOutOfBoundsBits = LookupOnReceiverBits::Next<bool, 1>;
// //
// Encoding when KindBits contains kElement. // Encoding when KindBits contains kElement.
// //
using IsJsArrayBits = BitField<bool, AllowOutOfBoundsBits::kNext, 1>; using IsJsArrayBits = AllowOutOfBoundsBits::Next<bool, 1>;
using ConvertHoleBits = BitField<bool, IsJsArrayBits::kNext, 1>; using ConvertHoleBits = IsJsArrayBits::Next<bool, 1>;
using ElementsKindBits = BitField<ElementsKind, ConvertHoleBits::kNext, 8>; using ElementsKindBits = ConvertHoleBits::Next<ElementsKind, 8>;
// Make sure we don't overflow the smi. // Make sure we don't overflow the smi.
STATIC_ASSERT(ElementsKindBits::kNext <= kSmiValueSize); STATIC_ASSERT(ElementsKindBits::kLastUsedBit < kSmiValueSize);
// //
// Encoding when KindBits contains kModuleExport. // Encoding when KindBits contains kModuleExport.
// //
using ExportsIndexBits = using ExportsIndexBits = LookupOnReceiverBits::Next<
BitField<unsigned, LookupOnReceiverBits::kNext, unsigned, kSmiValueSize - LookupOnReceiverBits::kLastUsedBit - 1>;
kSmiValueSize - LookupOnReceiverBits::kNext>;
// Decodes kind from Smi-handler. // Decodes kind from Smi-handler.
static inline Kind GetHandlerKind(Smi smi_handler); static inline Kind GetHandlerKind(Smi smi_handler);
...@@ -208,38 +206,36 @@ class StoreHandler final : public DataHandler { ...@@ -208,38 +206,36 @@ class StoreHandler final : public DataHandler {
// Applicable to kGlobalProxy, kProxy kinds. // Applicable to kGlobalProxy, kProxy kinds.
// Defines whether access rights check should be done on receiver object. // Defines whether access rights check should be done on receiver object.
using DoAccessCheckOnReceiverBits = BitField<bool, KindBits::kNext, 1>; using DoAccessCheckOnReceiverBits = KindBits::Next<bool, 1>;
// Defines whether a lookup should be done on receiver object before // Defines whether a lookup should be done on receiver object before
// proceeding to the prototype chain. Applicable to named property kinds only // proceeding to the prototype chain. Applicable to named property kinds only
// when storing through prototype chain. Ignored when storing to holder. // when storing through prototype chain. Ignored when storing to holder.
using LookupOnReceiverBits = using LookupOnReceiverBits = DoAccessCheckOnReceiverBits::Next<bool, 1>;
BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1>;
// Applicable to kField, kTransitionToField and kTransitionToConstant // Applicable to kField, kTransitionToField and kTransitionToConstant
// kinds. // kinds.
// Index of a value entry in the descriptor array. // Index of a value entry in the descriptor array.
using DescriptorBits = using DescriptorBits =
BitField<unsigned, LookupOnReceiverBits::kNext, kDescriptorIndexBitCount>; LookupOnReceiverBits::Next<unsigned, kDescriptorIndexBitCount>;
// //
// Encoding when KindBits contains kTransitionToConstant. // Encoding when KindBits contains kTransitionToConstant.
// //
// Make sure we don't overflow the smi. // Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize); STATIC_ASSERT(DescriptorBits::kLastUsedBit < kSmiValueSize);
// //
// Encoding when KindBits contains kField or kTransitionToField. // Encoding when KindBits contains kField or kTransitionToField.
// //
using IsInobjectBits = BitField<bool, DescriptorBits::kNext, 1>; using IsInobjectBits = DescriptorBits::Next<bool, 1>;
using FieldRepresentationBits = using FieldRepresentationBits = IsInobjectBits::Next<FieldRepresentation, 2>;
BitField<FieldRepresentation, IsInobjectBits::kNext, 2>;
// +1 here is to cover all possible JSObject header sizes. // +1 here is to cover all possible JSObject header sizes.
using FieldIndexBits = BitField<unsigned, FieldRepresentationBits::kNext, using FieldIndexBits =
kDescriptorIndexBitCount + 1>; FieldRepresentationBits::Next<unsigned, kDescriptorIndexBitCount + 1>;
// Make sure we don't overflow the smi. // Make sure we don't overflow the smi.
STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize); STATIC_ASSERT(FieldIndexBits::kLastUsedBit < kSmiValueSize);
// Creates a Smi-handler for storing a field to fast object. // Creates a Smi-handler for storing a field to fast object.
static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor, static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor,
......
...@@ -19,7 +19,7 @@ namespace interpreter { ...@@ -19,7 +19,7 @@ namespace interpreter {
class CreateArrayLiteralFlags { class CreateArrayLiteralFlags {
public: public:
using FlagsBits = BitField8<int, 0, 5>; using FlagsBits = BitField8<int, 0, 5>;
using FastCloneSupportedBit = BitField8<bool, FlagsBits::kNext, 1>; using FastCloneSupportedBit = FlagsBits::Next<bool, 1>;
static uint8_t Encode(bool use_fast_shallow_clone, int runtime_flags); static uint8_t Encode(bool use_fast_shallow_clone, int runtime_flags);
...@@ -30,7 +30,7 @@ class CreateArrayLiteralFlags { ...@@ -30,7 +30,7 @@ class CreateArrayLiteralFlags {
class CreateObjectLiteralFlags { class CreateObjectLiteralFlags {
public: public:
using FlagsBits = BitField8<int, 0, 5>; using FlagsBits = BitField8<int, 0, 5>;
using FastCloneSupportedBit = BitField8<bool, FlagsBits::kNext, 1>; using FastCloneSupportedBit = FlagsBits::Next<bool, 1>;
static uint8_t Encode(int runtime_flags, bool fast_clone_supported); static uint8_t Encode(int runtime_flags, bool fast_clone_supported);
...@@ -41,7 +41,7 @@ class CreateObjectLiteralFlags { ...@@ -41,7 +41,7 @@ class CreateObjectLiteralFlags {
class CreateClosureFlags { class CreateClosureFlags {
public: public:
using PretenuredBit = BitField8<bool, 0, 1>; using PretenuredBit = BitField8<bool, 0, 1>;
using FastNewClosureBit = BitField8<bool, PretenuredBit::kNext, 1>; using FastNewClosureBit = PretenuredBit::Next<bool, 1>;
static uint8_t Encode(bool pretenure, bool is_function_scope, static uint8_t Encode(bool pretenure, bool is_function_scope,
bool might_always_opt); bool might_always_opt);
...@@ -81,7 +81,7 @@ class TestTypeOfFlags { ...@@ -81,7 +81,7 @@ class TestTypeOfFlags {
class StoreLookupSlotFlags { class StoreLookupSlotFlags {
public: public:
using LanguageModeBit = BitField8<LanguageMode, 0, 1>; using LanguageModeBit = BitField8<LanguageMode, 0, 1>;
using LookupHoistingModeBit = BitField8<bool, LanguageModeBit::kNext, 1>; using LookupHoistingModeBit = LanguageModeBit::Next<bool, 1>;
STATIC_ASSERT(LanguageModeSize <= LanguageModeBit::kNumValues); STATIC_ASSERT(LanguageModeSize <= LanguageModeBit::kNumValues);
static uint8_t Encode(LanguageMode language_mode, static uint8_t Encode(LanguageMode language_mode,
......
...@@ -65,8 +65,8 @@ enum class EscapeKind : uint8_t { ...@@ -65,8 +65,8 @@ enum class EscapeKind : uint8_t {
}; };
using EscapeKindField = BitField8<EscapeKind, 0, 3>; using EscapeKindField = BitField8<EscapeKind, 0, 3>;
using MayTerminateStringField = BitField8<bool, EscapeKindField::kNext, 1>; using MayTerminateStringField = EscapeKindField::Next<bool, 1>;
using NumberPartField = BitField8<bool, MayTerminateStringField::kNext, 1>; using NumberPartField = MayTerminateStringField::Next<bool, 1>;
constexpr bool MayTerminateJsonString(uint8_t flags) { constexpr bool MayTerminateJsonString(uint8_t flags) {
return MayTerminateStringField::decode(flags); return MayTerminateStringField::decode(flags);
......
...@@ -58,8 +58,8 @@ class BigIntBase : public HeapObject { ...@@ -58,8 +58,8 @@ class BigIntBase : public HeapObject {
static const int kLengthFieldBits = 30; static const int kLengthFieldBits = 30;
STATIC_ASSERT(kMaxLength <= ((1 << kLengthFieldBits) - 1)); STATIC_ASSERT(kMaxLength <= ((1 << kLengthFieldBits) - 1));
using SignBits = BitField<bool, 0, 1>; using SignBits = BitField<bool, 0, 1>;
using LengthBits = BitField<int, SignBits::kNext, kLengthFieldBits>; using LengthBits = SignBits::Next<int, kLengthFieldBits>;
STATIC_ASSERT(LengthBits::kNext <= 32); STATIC_ASSERT(LengthBits::kLastUsedBit < 32);
// Layout description. // Layout description.
#define BIGINT_FIELDS(V) \ #define BIGINT_FIELDS(V) \
......
...@@ -439,7 +439,7 @@ class Code : public HeapObject { ...@@ -439,7 +439,7 @@ class Code : public HeapObject {
DEFINE_BIT_FIELDS(CODE_FLAGS_BIT_FIELDS) DEFINE_BIT_FIELDS(CODE_FLAGS_BIT_FIELDS)
#undef CODE_FLAGS_BIT_FIELDS #undef CODE_FLAGS_BIT_FIELDS
static_assert(NUMBER_OF_KINDS <= KindField::kMax, "Code::KindField size"); static_assert(NUMBER_OF_KINDS <= KindField::kMax, "Code::KindField size");
static_assert(IsOffHeapTrampoline::kNext <= 32, static_assert(IsOffHeapTrampoline::kLastUsedBit < 32,
"Code::flags field exhausted"); "Code::flags field exhausted");
// KindSpecificFlags layout (STUB, BUILTIN and OPTIMIZED_FUNCTION) // KindSpecificFlags layout (STUB, BUILTIN and OPTIMIZED_FUNCTION)
...@@ -452,7 +452,8 @@ class Code : public HeapObject { ...@@ -452,7 +452,8 @@ class Code : public HeapObject {
V(IsExceptionCaughtField, bool, 1, _) V(IsExceptionCaughtField, bool, 1, _)
DEFINE_BIT_FIELDS(CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS) DEFINE_BIT_FIELDS(CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS)
#undef CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS #undef CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS
static_assert(IsExceptionCaughtField::kNext <= 32, "KindSpecificFlags full"); static_assert(IsExceptionCaughtField::kLastUsedBit < 32,
"KindSpecificFlags full");
// The {marked_for_deoptimization} field is accessed from generated code. // The {marked_for_deoptimization} field is accessed from generated code.
static const int kMarkedForDeoptimizationBit = static const int kMarkedForDeoptimizationBit =
......
...@@ -108,16 +108,15 @@ class FieldIndex final { ...@@ -108,16 +108,15 @@ class FieldIndex final {
// Index from beginning of object. // Index from beginning of object.
using OffsetBits = BitField64<int, 0, kOffsetBitsSize>; using OffsetBits = BitField64<int, 0, kOffsetBitsSize>;
using IsInObjectBits = BitField64<bool, OffsetBits::kNext, 1>; using IsInObjectBits = OffsetBits::Next<bool, 1>;
using EncodingBits = BitField64<Encoding, IsInObjectBits::kNext, 2>; using EncodingBits = IsInObjectBits::Next<Encoding, 2>;
// Number of inobject properties. // Number of inobject properties.
using InObjectPropertyBits = using InObjectPropertyBits =
BitField64<int, EncodingBits::kNext, kDescriptorIndexBitCount>; EncodingBits::Next<int, kDescriptorIndexBitCount>;
// Offset of first inobject property from beginning of object. // Offset of first inobject property from beginning of object.
using FirstInobjectPropertyOffsetBits = using FirstInobjectPropertyOffsetBits =
BitField64<int, InObjectPropertyBits::kNext, InObjectPropertyBits::Next<int, kFirstInobjectPropertyOffsetBitCount>;
kFirstInobjectPropertyOffsetBitCount>; STATIC_ASSERT(FirstInobjectPropertyOffsetBits::kLastUsedBit < 64);
STATIC_ASSERT(FirstInobjectPropertyOffsetBits::kNext <= 64);
uint64_t bit_field_; uint64_t bit_field_;
}; };
......
...@@ -311,10 +311,9 @@ class PropertyDetails { ...@@ -311,10 +311,9 @@ class PropertyDetails {
// Bit fields in value_ (type, shift, size). Must be public so the // Bit fields in value_ (type, shift, size). Must be public so the
// constants can be embedded in generated code. // constants can be embedded in generated code.
using KindField = BitField<PropertyKind, 0, 1>; using KindField = BitField<PropertyKind, 0, 1>;
using LocationField = BitField<PropertyLocation, KindField::kNext, 1>; using LocationField = KindField::Next<PropertyLocation, 1>;
using ConstnessField = BitField<PropertyConstness, LocationField::kNext, 1>; using ConstnessField = LocationField::Next<PropertyConstness, 1>;
using AttributesField = using AttributesField = ConstnessField::Next<PropertyAttributes, 3>;
BitField<PropertyAttributes, ConstnessField::kNext, 3>;
static const int kAttributesReadOnlyMask = static const int kAttributesReadOnlyMask =
(READ_ONLY << AttributesField::kShift); (READ_ONLY << AttributesField::kShift);
static const int kAttributesDontDeleteMask = static const int kAttributesDontDeleteMask =
...@@ -323,21 +322,19 @@ class PropertyDetails { ...@@ -323,21 +322,19 @@ class PropertyDetails {
(DONT_ENUM << AttributesField::kShift); (DONT_ENUM << AttributesField::kShift);
// Bit fields for normalized objects. // Bit fields for normalized objects.
using PropertyCellTypeField = using PropertyCellTypeField = AttributesField::Next<PropertyCellType, 2>;
BitField<PropertyCellType, AttributesField::kNext, 2>; using DictionaryStorageField = PropertyCellTypeField::Next<uint32_t, 23>;
using DictionaryStorageField =
BitField<uint32_t, PropertyCellTypeField::kNext, 23>;
// Bit fields for fast objects. // Bit fields for fast objects.
using RepresentationField = BitField<uint32_t, AttributesField::kNext, 3>; using RepresentationField = AttributesField::Next<uint32_t, 3>;
using DescriptorPointer = using DescriptorPointer =
BitField<uint32_t, RepresentationField::kNext, kDescriptorIndexBitCount>; RepresentationField::Next<uint32_t, kDescriptorIndexBitCount>;
using FieldIndexField = using FieldIndexField =
BitField<uint32_t, DescriptorPointer::kNext, kDescriptorIndexBitCount>; DescriptorPointer::Next<uint32_t, kDescriptorIndexBitCount>;
// All bits for both fast and slow objects must fit in a smi. // All bits for both fast and slow objects must fit in a smi.
STATIC_ASSERT(DictionaryStorageField::kNext <= 31); STATIC_ASSERT(DictionaryStorageField::kLastUsedBit < 31);
STATIC_ASSERT(FieldIndexField::kNext <= 31); STATIC_ASSERT(FieldIndexField::kLastUsedBit < 31);
static const int kInitialIndex = 1; static const int kInitialIndex = 1;
......
...@@ -221,31 +221,25 @@ class ScopeInfo : public FixedArray { ...@@ -221,31 +221,25 @@ class ScopeInfo : public FixedArray {
// Properties of scopes. // Properties of scopes.
using ScopeTypeField = BitField<ScopeType, 0, 4>; using ScopeTypeField = BitField<ScopeType, 0, 4>;
using CallsSloppyEvalField = BitField<bool, ScopeTypeField::kNext, 1>; using CallsSloppyEvalField = ScopeTypeField::Next<bool, 1>;
STATIC_ASSERT(LanguageModeSize == 2); STATIC_ASSERT(LanguageModeSize == 2);
using LanguageModeField = using LanguageModeField = CallsSloppyEvalField::Next<LanguageMode, 1>;
BitField<LanguageMode, CallsSloppyEvalField::kNext, 1>; using DeclarationScopeField = LanguageModeField::Next<bool, 1>;
using DeclarationScopeField = BitField<bool, LanguageModeField::kNext, 1>;
using ReceiverVariableField = using ReceiverVariableField =
BitField<VariableAllocationInfo, DeclarationScopeField::kNext, 2>; DeclarationScopeField::Next<VariableAllocationInfo, 2>;
using HasClassBrandField = BitField<bool, ReceiverVariableField::kNext, 1>; using HasClassBrandField = ReceiverVariableField::Next<bool, 1>;
using HasNewTargetField = BitField<bool, HasClassBrandField::kNext, 1>; using HasNewTargetField = HasClassBrandField::Next<bool, 1>;
using FunctionVariableField = using FunctionVariableField =
BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2>; HasNewTargetField::Next<VariableAllocationInfo, 2>;
// TODO(cbruni): Combine with function variable field when only storing the // TODO(cbruni): Combine with function variable field when only storing the
// function name. // function name.
using HasInferredFunctionNameField = using HasInferredFunctionNameField = FunctionVariableField::Next<bool, 1>;
BitField<bool, FunctionVariableField::kNext, 1>; using IsAsmModuleField = HasInferredFunctionNameField::Next<bool, 1>;
using IsAsmModuleField = using HasSimpleParametersField = IsAsmModuleField::Next<bool, 1>;
BitField<bool, HasInferredFunctionNameField::kNext, 1>; using FunctionKindField = HasSimpleParametersField::Next<FunctionKind, 5>;
using HasSimpleParametersField = BitField<bool, IsAsmModuleField::kNext, 1>; using HasOuterScopeInfoField = FunctionKindField::Next<bool, 1>;
using FunctionKindField = using IsDebugEvaluateScopeField = HasOuterScopeInfoField::Next<bool, 1>;
BitField<FunctionKind, HasSimpleParametersField::kNext, 5>; using ForceContextAllocationField = IsDebugEvaluateScopeField::Next<bool, 1>;
using HasOuterScopeInfoField = BitField<bool, FunctionKindField::kNext, 1>;
using IsDebugEvaluateScopeField =
BitField<bool, HasOuterScopeInfoField::kNext, 1>;
using ForceContextAllocationField =
BitField<bool, IsDebugEvaluateScopeField::kNext, 1>;
STATIC_ASSERT(kLastFunctionKind <= FunctionKindField::kMax); STATIC_ASSERT(kLastFunctionKind <= FunctionKindField::kMax);
...@@ -313,12 +307,9 @@ class ScopeInfo : public FixedArray { ...@@ -313,12 +307,9 @@ class ScopeInfo : public FixedArray {
// Properties of variables. // Properties of variables.
using VariableModeField = BitField<VariableMode, 0, 4>; using VariableModeField = BitField<VariableMode, 0, 4>;
using InitFlagField = using InitFlagField = VariableModeField::Next<InitializationFlag, 1>;
BitField<InitializationFlag, VariableModeField::kNext, 1>; using MaybeAssignedFlagField = InitFlagField::Next<MaybeAssignedFlag, 1>;
using MaybeAssignedFlagField = using ParameterNumberField = MaybeAssignedFlagField::Next<uint32_t, 16>;
BitField<MaybeAssignedFlag, InitFlagField::kNext, 1>;
using ParameterNumberField =
BitField<uint32_t, MaybeAssignedFlagField::kNext, 16>;
friend class ScopeIterator; friend class ScopeIterator;
friend std::ostream& operator<<(std::ostream& os, friend std::ostream& operator<<(std::ostream& os,
......
...@@ -228,7 +228,7 @@ class ObjectTemplateInfo : public TemplateInfo { ...@@ -228,7 +228,7 @@ class ObjectTemplateInfo : public TemplateInfo {
private: private:
using IsImmutablePrototype = BitField<bool, 0, 1>; using IsImmutablePrototype = BitField<bool, 0, 1>;
using EmbedderFieldCount = BitField<int, IsImmutablePrototype::kNext, 29>; using EmbedderFieldCount = IsImmutablePrototype::Next<int, 29>;
OBJECT_CONSTRUCTORS(ObjectTemplateInfo, TemplateInfo); OBJECT_CONSTRUCTORS(ObjectTemplateInfo, TemplateInfo);
}; };
......
...@@ -22,20 +22,17 @@ namespace internal { ...@@ -22,20 +22,17 @@ namespace internal {
namespace { namespace {
using ScopeCallsSloppyEvalField = BitField8<bool, 0, 1>; using ScopeCallsSloppyEvalField = BitField8<bool, 0, 1>;
using InnerScopeCallsEvalField = using InnerScopeCallsEvalField = ScopeCallsSloppyEvalField::Next<bool, 1>;
BitField8<bool, ScopeCallsSloppyEvalField::kNext, 1>;
using VariableMaybeAssignedField = BitField8<bool, 0, 1>; using VariableMaybeAssignedField = BitField8<bool, 0, 1>;
using VariableContextAllocatedField = using VariableContextAllocatedField = VariableMaybeAssignedField::Next<bool, 1>;
BitField8<bool, VariableMaybeAssignedField::kNext, 1>;
using HasDataField = BitField<bool, 0, 1>; using HasDataField = BitField<bool, 0, 1>;
using LengthEqualsParametersField = BitField<bool, HasDataField::kNext, 1>; using LengthEqualsParametersField = HasDataField::Next<bool, 1>;
using NumberOfParametersField = using NumberOfParametersField = LengthEqualsParametersField::Next<uint16_t, 16>;
BitField<uint16_t, LengthEqualsParametersField::kNext, 16>;
using LanguageField = BitField8<LanguageMode, 0, 1>; using LanguageField = BitField8<LanguageMode, 0, 1>;
using UsesSuperField = BitField8<bool, LanguageField::kNext, 1>; using UsesSuperField = LanguageField::Next<bool, 1>;
STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues); STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
} // namespace } // namespace
......
...@@ -351,16 +351,14 @@ class PreParserExpression { ...@@ -351,16 +351,14 @@ class PreParserExpression {
// Expression nodes may be represented as multiple Types, not exclusively // Expression nodes may be represented as multiple Types, not exclusively
// through kExpression. // through kExpression.
// TODO(caitp, adamk): clean up PreParserExpression bitfields. // TODO(caitp, adamk): clean up PreParserExpression bitfields.
using IsParenthesizedField = BitField<bool, TypeField::kNext, 1>; using IsParenthesizedField = TypeField::Next<bool, 1>;
// The rest of the bits are interpreted depending on the value // The rest of the bits are interpreted depending on the value
// of the Type field, so they can share the storage. // of the Type field, so they can share the storage.
using ExpressionTypeField = using ExpressionTypeField = IsParenthesizedField::Next<ExpressionType, 4>;
BitField<ExpressionType, IsParenthesizedField::kNext, 4>;
using IdentifierTypeField = using IdentifierTypeField =
BitField<PreParserIdentifier::Type, IsParenthesizedField::kNext, 8>; IsParenthesizedField::Next<PreParserIdentifier::Type, 8>;
using HasCoverInitializedNameField = using HasCoverInitializedNameField = IsParenthesizedField::Next<bool, 1>;
BitField<bool, IsParenthesizedField::kNext, 1>;
uint32_t code_; uint32_t code_;
friend class PreParser; friend class PreParser;
......
...@@ -216,7 +216,7 @@ class V8_EXPORT_PRIVATE Token { ...@@ -216,7 +216,7 @@ class V8_EXPORT_PRIVATE Token {
} }
using IsKeywordBits = BitField8<bool, 0, 1>; using IsKeywordBits = BitField8<bool, 0, 1>;
using IsPropertyNameBits = BitField8<bool, IsKeywordBits::kNext, 1>; using IsPropertyNameBits = IsKeywordBits::Next<bool, 1>;
// Predicates // Predicates
static bool IsKeyword(Value token) { static bool IsKeyword(Value token) {
......
...@@ -155,10 +155,9 @@ class SerializerReference { ...@@ -155,10 +155,9 @@ class SerializerReference {
private: private:
using SpaceBits = BitField<SnapshotSpace, 0, kSpaceTagSize>; using SpaceBits = BitField<SnapshotSpace, 0, kSpaceTagSize>;
using ChunkIndexBits = using ChunkIndexBits = SpaceBits::Next<uint32_t, 32 - kSpaceTagSize>;
BitField<uint32_t, SpaceBits::kNext, 32 - kSpaceTagSize>;
using SpecialValueTypeBits = using SpecialValueTypeBits =
BitField<SpecialValueType, SpaceBits::kNext, 32 - kSpaceTagSize>; SpaceBits::Next<SpecialValueType, 32 - kSpaceTagSize>;
// We use two fields to store a reference. // We use two fields to store a reference.
// In case of a normal back reference, the bitfield_ stores the space and // In case of a normal back reference, the bitfield_ stores the space and
......
...@@ -316,21 +316,25 @@ class BitField final { ...@@ -316,21 +316,25 @@ class BitField final {
STATIC_ASSERT(shift < 8 * sizeof(U)); // Otherwise shifts by {shift} are UB. STATIC_ASSERT(shift < 8 * sizeof(U)); // Otherwise shifts by {shift} are UB.
STATIC_ASSERT(size < 8 * sizeof(U)); // Otherwise shifts by {size} are UB. STATIC_ASSERT(size < 8 * sizeof(U)); // Otherwise shifts by {size} are UB.
STATIC_ASSERT(shift + size <= 8 * sizeof(U)); STATIC_ASSERT(shift + size <= 8 * sizeof(U));
STATIC_ASSERT(size > 0);
using FieldType = T; using FieldType = T;
// A type U mask of bit field. To use all bits of a type U of x bits // A type U mask of bit field. To use all bits of a type U of x bits
// in a bitfield without compiler warnings we have to compute 2^x // in a bitfield without compiler warnings we have to compute 2^x
// without using a shift count of x in the computation. // without using a shift count of x in the computation.
static constexpr U kShift = shift; static constexpr int kShift = shift;
static constexpr U kSize = size; static constexpr int kSize = size;
static constexpr U kMask = ((U{1} << kShift) << kSize) - (U{1} << kShift); static constexpr U kMask = ((U{1} << kShift) << kSize) - (U{1} << kShift);
static constexpr U kNext = kShift + kSize; static constexpr int kLastUsedBit = kShift + kSize - 1;
static constexpr U kNumValues = U{1} << kSize; static constexpr U kNumValues = U{1} << kSize;
// Value for the field with all bits set. // Value for the field with all bits set.
static constexpr T kMax = static_cast<T>(kNumValues - 1); static constexpr T kMax = static_cast<T>(kNumValues - 1);
template <class T2, int size2>
using Next = BitField<T2, kShift + kSize, size2, U>;
// Tells whether the provided value fits into the bit field. // Tells whether the provided value fits into the bit field.
static constexpr bool is_valid(T value) { static constexpr bool is_valid(T value) {
return (static_cast<U>(value) & ~static_cast<U>(kMax)) == 0; return (static_cast<U>(value) & ~static_cast<U>(kMax)) == 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment