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 {
}
using VariableModeField = BitField16<VariableMode, 0, 4>;
using VariableKindField =
BitField16<VariableKind, VariableModeField::kNext, 3>;
using LocationField =
BitField16<VariableLocation, VariableKindField::kNext, 3>;
using ForceContextAllocationField = BitField16<bool, LocationField::kNext, 1>;
using IsUsedField = BitField16<bool, ForceContextAllocationField::kNext, 1>;
using InitializationFlagField =
BitField16<InitializationFlag, IsUsedField::kNext, 1>;
using ForceHoleInitializationField =
BitField16<bool, InitializationFlagField::kNext, 1>;
using VariableKindField = VariableModeField::Next<VariableKind, 3>;
using LocationField = VariableKindField::Next<VariableLocation, 3>;
using ForceContextAllocationField = LocationField::Next<bool, 1>;
using IsUsedField = ForceContextAllocationField::Next<bool, 1>;
using InitializationFlagField = IsUsedField::Next<InitializationFlag, 1>;
using ForceHoleInitializationField = InitializationFlagField::Next<bool, 1>;
using MaybeAssignedFlagField =
BitField16<MaybeAssignedFlag, ForceHoleInitializationField::kNext, 1>;
ForceHoleInitializationField::Next<MaybeAssignedFlag, 1>;
Variable** next() { return &next_; }
friend List;
......
......@@ -3909,7 +3909,7 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking(
Comment("Decrease construction counter");
// Slack tracking is only done on initial maps.
CSA_ASSERT(this, IsUndefined(LoadMapBackPointer(map)));
STATIC_ASSERT(Map::ConstructionCounterBits::kNext == 32);
STATIC_ASSERT(Map::ConstructionCounterBits::kLastUsedBit == 31);
Node* new_bit_field3 = Int32Sub(
bit_field3, Int32Constant(1 << Map::ConstructionCounterBits::kShift));
StoreObjectFieldNoWriteBarrier(map, Map::kBitField3Offset, new_bit_field3,
......
......@@ -145,7 +145,7 @@ class LinkageLocation {
enum LocationType { REGISTER, STACK_SLOT };
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 MAX_STACK_SLOT = 32767;
......
......@@ -581,8 +581,8 @@ class GlobalHandles::Node final : public NodeBase<GlobalHandles::Node> {
// This stores three flags (independent, partially_dependent and
// in_young_list) and a State.
using NodeState = BitField8<State, 0, 3>;
using IsInYoungList = BitField8<bool, NodeState::kNext, 1>;
using NodeWeaknessType = BitField8<WeaknessType, IsInYoungList::kNext, 2>;
using IsInYoungList = NodeState::Next<bool, 1>;
using NodeWeaknessType = IsInYoungList::Next<WeaknessType, 2>;
// Handle specific callback - might be a weak reference in disguise.
WeakCallbackInfo<void>::Callback weak_callback_;
......@@ -650,8 +650,8 @@ class GlobalHandles::TracedNode final
protected:
using NodeState = BitField8<State, 0, 2>;
using IsInYoungList = BitField8<bool, NodeState::kNext, 1>;
using IsRoot = BitField8<bool, IsInYoungList::kNext, 1>;
using IsInYoungList = NodeState::Next<bool, 1>;
using IsRoot = IsInYoungList::Next<bool, 1>;
void ClearImplFields() {
set_root(true);
......
......@@ -52,13 +52,12 @@ class LoadHandler final : public DataHandler {
// Defines whether access rights check should be done on receiver object.
// Applicable to named property kinds only when loading value from prototype
// 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
// proceeding to the prototype chain. Applicable to named property kinds only
// when loading value from prototype chain. Ignored when loading from holder.
using LookupOnReceiverBits =
BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1>;
using LookupOnReceiverBits = DoAccessCheckOnReceiverBits::Next<bool, 1>;
//
// Encoding when KindBits contains kForConstants.
......@@ -66,41 +65,40 @@ class LoadHandler final : public DataHandler {
// Index of a value entry in the descriptor array.
using DescriptorBits =
BitField<unsigned, LookupOnReceiverBits::kNext, kDescriptorIndexBitCount>;
LookupOnReceiverBits::Next<unsigned, kDescriptorIndexBitCount>;
// Make sure we don't overflow the smi.
STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize);
STATIC_ASSERT(DescriptorBits::kLastUsedBit < kSmiValueSize);
//
// Encoding when KindBits contains kField.
//
using IsInobjectBits = BitField<bool, LookupOnReceiverBits::kNext, 1>;
using IsDoubleBits = BitField<bool, IsInobjectBits::kNext, 1>;
using IsInobjectBits = LookupOnReceiverBits::Next<bool, 1>;
using IsDoubleBits = IsInobjectBits::Next<bool, 1>;
// +1 here is to cover all possible JSObject header sizes.
using FieldIndexBits =
BitField<unsigned, IsDoubleBits::kNext, kDescriptorIndexBitCount + 1>;
IsDoubleBits::Next<unsigned, kDescriptorIndexBitCount + 1>;
// 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.
//
using AllowOutOfBoundsBits = BitField<bool, LookupOnReceiverBits::kNext, 1>;
using AllowOutOfBoundsBits = LookupOnReceiverBits::Next<bool, 1>;
//
// Encoding when KindBits contains kElement.
//
using IsJsArrayBits = BitField<bool, AllowOutOfBoundsBits::kNext, 1>;
using ConvertHoleBits = BitField<bool, IsJsArrayBits::kNext, 1>;
using ElementsKindBits = BitField<ElementsKind, ConvertHoleBits::kNext, 8>;
using IsJsArrayBits = AllowOutOfBoundsBits::Next<bool, 1>;
using ConvertHoleBits = IsJsArrayBits::Next<bool, 1>;
using ElementsKindBits = ConvertHoleBits::Next<ElementsKind, 8>;
// Make sure we don't overflow the smi.
STATIC_ASSERT(ElementsKindBits::kNext <= kSmiValueSize);
STATIC_ASSERT(ElementsKindBits::kLastUsedBit < kSmiValueSize);
//
// Encoding when KindBits contains kModuleExport.
//
using ExportsIndexBits =
BitField<unsigned, LookupOnReceiverBits::kNext,
kSmiValueSize - LookupOnReceiverBits::kNext>;
using ExportsIndexBits = LookupOnReceiverBits::Next<
unsigned, kSmiValueSize - LookupOnReceiverBits::kLastUsedBit - 1>;
// Decodes kind from Smi-handler.
static inline Kind GetHandlerKind(Smi smi_handler);
......@@ -208,38 +206,36 @@ class StoreHandler final : public DataHandler {
// Applicable to kGlobalProxy, kProxy kinds.
// 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
// proceeding to the prototype chain. Applicable to named property kinds only
// when storing through prototype chain. Ignored when storing to holder.
using LookupOnReceiverBits =
BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1>;
using LookupOnReceiverBits = DoAccessCheckOnReceiverBits::Next<bool, 1>;
// Applicable to kField, kTransitionToField and kTransitionToConstant
// kinds.
// Index of a value entry in the descriptor array.
using DescriptorBits =
BitField<unsigned, LookupOnReceiverBits::kNext, kDescriptorIndexBitCount>;
LookupOnReceiverBits::Next<unsigned, kDescriptorIndexBitCount>;
//
// Encoding when KindBits contains kTransitionToConstant.
//
// 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.
//
using IsInobjectBits = BitField<bool, DescriptorBits::kNext, 1>;
using FieldRepresentationBits =
BitField<FieldRepresentation, IsInobjectBits::kNext, 2>;
using IsInobjectBits = DescriptorBits::Next<bool, 1>;
using FieldRepresentationBits = IsInobjectBits::Next<FieldRepresentation, 2>;
// +1 here is to cover all possible JSObject header sizes.
using FieldIndexBits = BitField<unsigned, FieldRepresentationBits::kNext,
kDescriptorIndexBitCount + 1>;
using FieldIndexBits =
FieldRepresentationBits::Next<unsigned, kDescriptorIndexBitCount + 1>;
// 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.
static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor,
......
......@@ -19,7 +19,7 @@ namespace interpreter {
class CreateArrayLiteralFlags {
public:
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);
......@@ -30,7 +30,7 @@ class CreateArrayLiteralFlags {
class CreateObjectLiteralFlags {
public:
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);
......@@ -41,7 +41,7 @@ class CreateObjectLiteralFlags {
class CreateClosureFlags {
public:
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,
bool might_always_opt);
......@@ -81,7 +81,7 @@ class TestTypeOfFlags {
class StoreLookupSlotFlags {
public:
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 uint8_t Encode(LanguageMode language_mode,
......
......@@ -65,8 +65,8 @@ enum class EscapeKind : uint8_t {
};
using EscapeKindField = BitField8<EscapeKind, 0, 3>;
using MayTerminateStringField = BitField8<bool, EscapeKindField::kNext, 1>;
using NumberPartField = BitField8<bool, MayTerminateStringField::kNext, 1>;
using MayTerminateStringField = EscapeKindField::Next<bool, 1>;
using NumberPartField = MayTerminateStringField::Next<bool, 1>;
constexpr bool MayTerminateJsonString(uint8_t flags) {
return MayTerminateStringField::decode(flags);
......
......@@ -58,8 +58,8 @@ class BigIntBase : public HeapObject {
static const int kLengthFieldBits = 30;
STATIC_ASSERT(kMaxLength <= ((1 << kLengthFieldBits) - 1));
using SignBits = BitField<bool, 0, 1>;
using LengthBits = BitField<int, SignBits::kNext, kLengthFieldBits>;
STATIC_ASSERT(LengthBits::kNext <= 32);
using LengthBits = SignBits::Next<int, kLengthFieldBits>;
STATIC_ASSERT(LengthBits::kLastUsedBit < 32);
// Layout description.
#define BIGINT_FIELDS(V) \
......
......@@ -439,7 +439,7 @@ class Code : public HeapObject {
DEFINE_BIT_FIELDS(CODE_FLAGS_BIT_FIELDS)
#undef CODE_FLAGS_BIT_FIELDS
static_assert(NUMBER_OF_KINDS <= KindField::kMax, "Code::KindField size");
static_assert(IsOffHeapTrampoline::kNext <= 32,
static_assert(IsOffHeapTrampoline::kLastUsedBit < 32,
"Code::flags field exhausted");
// KindSpecificFlags layout (STUB, BUILTIN and OPTIMIZED_FUNCTION)
......@@ -452,7 +452,8 @@ class Code : public HeapObject {
V(IsExceptionCaughtField, bool, 1, _)
DEFINE_BIT_FIELDS(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.
static const int kMarkedForDeoptimizationBit =
......
......@@ -108,16 +108,15 @@ class FieldIndex final {
// Index from beginning of object.
using OffsetBits = BitField64<int, 0, kOffsetBitsSize>;
using IsInObjectBits = BitField64<bool, OffsetBits::kNext, 1>;
using EncodingBits = BitField64<Encoding, IsInObjectBits::kNext, 2>;
using IsInObjectBits = OffsetBits::Next<bool, 1>;
using EncodingBits = IsInObjectBits::Next<Encoding, 2>;
// Number of inobject properties.
using InObjectPropertyBits =
BitField64<int, EncodingBits::kNext, kDescriptorIndexBitCount>;
EncodingBits::Next<int, kDescriptorIndexBitCount>;
// Offset of first inobject property from beginning of object.
using FirstInobjectPropertyOffsetBits =
BitField64<int, InObjectPropertyBits::kNext,
kFirstInobjectPropertyOffsetBitCount>;
STATIC_ASSERT(FirstInobjectPropertyOffsetBits::kNext <= 64);
InObjectPropertyBits::Next<int, kFirstInobjectPropertyOffsetBitCount>;
STATIC_ASSERT(FirstInobjectPropertyOffsetBits::kLastUsedBit < 64);
uint64_t bit_field_;
};
......
......@@ -311,10 +311,9 @@ class PropertyDetails {
// Bit fields in value_ (type, shift, size). Must be public so the
// constants can be embedded in generated code.
using KindField = BitField<PropertyKind, 0, 1>;
using LocationField = BitField<PropertyLocation, KindField::kNext, 1>;
using ConstnessField = BitField<PropertyConstness, LocationField::kNext, 1>;
using AttributesField =
BitField<PropertyAttributes, ConstnessField::kNext, 3>;
using LocationField = KindField::Next<PropertyLocation, 1>;
using ConstnessField = LocationField::Next<PropertyConstness, 1>;
using AttributesField = ConstnessField::Next<PropertyAttributes, 3>;
static const int kAttributesReadOnlyMask =
(READ_ONLY << AttributesField::kShift);
static const int kAttributesDontDeleteMask =
......@@ -323,21 +322,19 @@ class PropertyDetails {
(DONT_ENUM << AttributesField::kShift);
// Bit fields for normalized objects.
using PropertyCellTypeField =
BitField<PropertyCellType, AttributesField::kNext, 2>;
using DictionaryStorageField =
BitField<uint32_t, PropertyCellTypeField::kNext, 23>;
using PropertyCellTypeField = AttributesField::Next<PropertyCellType, 2>;
using DictionaryStorageField = PropertyCellTypeField::Next<uint32_t, 23>;
// Bit fields for fast objects.
using RepresentationField = BitField<uint32_t, AttributesField::kNext, 3>;
using RepresentationField = AttributesField::Next<uint32_t, 3>;
using DescriptorPointer =
BitField<uint32_t, RepresentationField::kNext, kDescriptorIndexBitCount>;
RepresentationField::Next<uint32_t, kDescriptorIndexBitCount>;
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.
STATIC_ASSERT(DictionaryStorageField::kNext <= 31);
STATIC_ASSERT(FieldIndexField::kNext <= 31);
STATIC_ASSERT(DictionaryStorageField::kLastUsedBit < 31);
STATIC_ASSERT(FieldIndexField::kLastUsedBit < 31);
static const int kInitialIndex = 1;
......
......@@ -221,31 +221,25 @@ class ScopeInfo : public FixedArray {
// Properties of scopes.
using ScopeTypeField = BitField<ScopeType, 0, 4>;
using CallsSloppyEvalField = BitField<bool, ScopeTypeField::kNext, 1>;
using CallsSloppyEvalField = ScopeTypeField::Next<bool, 1>;
STATIC_ASSERT(LanguageModeSize == 2);
using LanguageModeField =
BitField<LanguageMode, CallsSloppyEvalField::kNext, 1>;
using DeclarationScopeField = BitField<bool, LanguageModeField::kNext, 1>;
using LanguageModeField = CallsSloppyEvalField::Next<LanguageMode, 1>;
using DeclarationScopeField = LanguageModeField::Next<bool, 1>;
using ReceiverVariableField =
BitField<VariableAllocationInfo, DeclarationScopeField::kNext, 2>;
using HasClassBrandField = BitField<bool, ReceiverVariableField::kNext, 1>;
using HasNewTargetField = BitField<bool, HasClassBrandField::kNext, 1>;
DeclarationScopeField::Next<VariableAllocationInfo, 2>;
using HasClassBrandField = ReceiverVariableField::Next<bool, 1>;
using HasNewTargetField = HasClassBrandField::Next<bool, 1>;
using FunctionVariableField =
BitField<VariableAllocationInfo, HasNewTargetField::kNext, 2>;
HasNewTargetField::Next<VariableAllocationInfo, 2>;
// TODO(cbruni): Combine with function variable field when only storing the
// function name.
using HasInferredFunctionNameField =
BitField<bool, FunctionVariableField::kNext, 1>;
using IsAsmModuleField =
BitField<bool, HasInferredFunctionNameField::kNext, 1>;
using HasSimpleParametersField = BitField<bool, IsAsmModuleField::kNext, 1>;
using FunctionKindField =
BitField<FunctionKind, HasSimpleParametersField::kNext, 5>;
using HasOuterScopeInfoField = BitField<bool, FunctionKindField::kNext, 1>;
using IsDebugEvaluateScopeField =
BitField<bool, HasOuterScopeInfoField::kNext, 1>;
using ForceContextAllocationField =
BitField<bool, IsDebugEvaluateScopeField::kNext, 1>;
using HasInferredFunctionNameField = FunctionVariableField::Next<bool, 1>;
using IsAsmModuleField = HasInferredFunctionNameField::Next<bool, 1>;
using HasSimpleParametersField = IsAsmModuleField::Next<bool, 1>;
using FunctionKindField = HasSimpleParametersField::Next<FunctionKind, 5>;
using HasOuterScopeInfoField = FunctionKindField::Next<bool, 1>;
using IsDebugEvaluateScopeField = HasOuterScopeInfoField::Next<bool, 1>;
using ForceContextAllocationField = IsDebugEvaluateScopeField::Next<bool, 1>;
STATIC_ASSERT(kLastFunctionKind <= FunctionKindField::kMax);
......@@ -313,12 +307,9 @@ class ScopeInfo : public FixedArray {
// Properties of variables.
using VariableModeField = BitField<VariableMode, 0, 4>;
using InitFlagField =
BitField<InitializationFlag, VariableModeField::kNext, 1>;
using MaybeAssignedFlagField =
BitField<MaybeAssignedFlag, InitFlagField::kNext, 1>;
using ParameterNumberField =
BitField<uint32_t, MaybeAssignedFlagField::kNext, 16>;
using InitFlagField = VariableModeField::Next<InitializationFlag, 1>;
using MaybeAssignedFlagField = InitFlagField::Next<MaybeAssignedFlag, 1>;
using ParameterNumberField = MaybeAssignedFlagField::Next<uint32_t, 16>;
friend class ScopeIterator;
friend std::ostream& operator<<(std::ostream& os,
......
......@@ -228,7 +228,7 @@ class ObjectTemplateInfo : public TemplateInfo {
private:
using IsImmutablePrototype = BitField<bool, 0, 1>;
using EmbedderFieldCount = BitField<int, IsImmutablePrototype::kNext, 29>;
using EmbedderFieldCount = IsImmutablePrototype::Next<int, 29>;
OBJECT_CONSTRUCTORS(ObjectTemplateInfo, TemplateInfo);
};
......
......@@ -22,20 +22,17 @@ namespace internal {
namespace {
using ScopeCallsSloppyEvalField = BitField8<bool, 0, 1>;
using InnerScopeCallsEvalField =
BitField8<bool, ScopeCallsSloppyEvalField::kNext, 1>;
using InnerScopeCallsEvalField = ScopeCallsSloppyEvalField::Next<bool, 1>;
using VariableMaybeAssignedField = BitField8<bool, 0, 1>;
using VariableContextAllocatedField =
BitField8<bool, VariableMaybeAssignedField::kNext, 1>;
using VariableContextAllocatedField = VariableMaybeAssignedField::Next<bool, 1>;
using HasDataField = BitField<bool, 0, 1>;
using LengthEqualsParametersField = BitField<bool, HasDataField::kNext, 1>;
using NumberOfParametersField =
BitField<uint16_t, LengthEqualsParametersField::kNext, 16>;
using LengthEqualsParametersField = HasDataField::Next<bool, 1>;
using NumberOfParametersField = LengthEqualsParametersField::Next<uint16_t, 16>;
using LanguageField = BitField8<LanguageMode, 0, 1>;
using UsesSuperField = BitField8<bool, LanguageField::kNext, 1>;
using UsesSuperField = LanguageField::Next<bool, 1>;
STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
} // namespace
......
......@@ -351,16 +351,14 @@ class PreParserExpression {
// Expression nodes may be represented as multiple Types, not exclusively
// through kExpression.
// 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
// of the Type field, so they can share the storage.
using ExpressionTypeField =
BitField<ExpressionType, IsParenthesizedField::kNext, 4>;
using ExpressionTypeField = IsParenthesizedField::Next<ExpressionType, 4>;
using IdentifierTypeField =
BitField<PreParserIdentifier::Type, IsParenthesizedField::kNext, 8>;
using HasCoverInitializedNameField =
BitField<bool, IsParenthesizedField::kNext, 1>;
IsParenthesizedField::Next<PreParserIdentifier::Type, 8>;
using HasCoverInitializedNameField = IsParenthesizedField::Next<bool, 1>;
uint32_t code_;
friend class PreParser;
......
......@@ -216,7 +216,7 @@ class V8_EXPORT_PRIVATE Token {
}
using IsKeywordBits = BitField8<bool, 0, 1>;
using IsPropertyNameBits = BitField8<bool, IsKeywordBits::kNext, 1>;
using IsPropertyNameBits = IsKeywordBits::Next<bool, 1>;
// Predicates
static bool IsKeyword(Value token) {
......
......@@ -155,10 +155,9 @@ class SerializerReference {
private:
using SpaceBits = BitField<SnapshotSpace, 0, kSpaceTagSize>;
using ChunkIndexBits =
BitField<uint32_t, SpaceBits::kNext, 32 - kSpaceTagSize>;
using ChunkIndexBits = SpaceBits::Next<uint32_t, 32 - kSpaceTagSize>;
using SpecialValueTypeBits =
BitField<SpecialValueType, SpaceBits::kNext, 32 - kSpaceTagSize>;
SpaceBits::Next<SpecialValueType, 32 - kSpaceTagSize>;
// We use two fields to store a reference.
// In case of a normal back reference, the bitfield_ stores the space and
......
......@@ -316,21 +316,25 @@ class BitField final {
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(shift + size <= 8 * sizeof(U));
STATIC_ASSERT(size > 0);
using FieldType = T;
// 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
// without using a shift count of x in the computation.
static constexpr U kShift = shift;
static constexpr U kSize = size;
static constexpr int kShift = shift;
static constexpr int kSize = size;
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;
// Value for the field with all bits set.
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.
static constexpr bool is_valid(T value) {
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