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
......@@ -172,7 +172,9 @@ class AstNode: public ZoneObject {
protected:
uint32_t bit_field_;
static const uint8_t kNextBitFieldIndex = NodeTypeField::kNext;
template <class T, int size>
using NextBitField = NodeTypeField::Next<T, size>;
AstNode(int position, NodeType type)
: position_(position), bit_field_(NodeTypeField::encode(type)) {}
......@@ -182,8 +184,6 @@ class AstNode: public ZoneObject {
class Statement : public AstNode {
protected:
Statement(int position, NodeType type) : AstNode(position, type) {}
static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex;
};
......@@ -265,14 +265,15 @@ class Expression : public AstNode {
}
private:
using IsParenthesizedField = BitField<bool, AstNode::kNextBitFieldIndex, 1>;
using IsParenthesizedField = AstNode::NextBitField<bool, 1>;
protected:
Expression(int pos, NodeType type) : AstNode(pos, type) {
DCHECK(!is_parenthesized());
}
static const uint8_t kNextBitFieldIndex = IsParenthesizedField::kNext;
template <class T, int size>
using NextBitField = IsParenthesizedField::Next<T, size>;
};
class FailureExpression : public Expression {
......@@ -320,8 +321,7 @@ class BreakableStatement : public Statement {
}
private:
using BreakableTypeField =
BitField<BreakableType, Statement::kNextBitFieldIndex, 1>;
using BreakableTypeField = Statement::NextBitField<BreakableType, 1>;
protected:
BreakableStatement(BreakableType breakable_type, int position, NodeType type)
......@@ -329,7 +329,8 @@ class BreakableStatement : public Statement {
bit_field_ |= BreakableTypeField::encode(breakable_type);
}
static const uint8_t kNextBitFieldIndex = BreakableTypeField::kNext;
template <class T, int size>
using NextBitField = BreakableTypeField::Next<T, size>;
};
class Block : public BreakableStatement {
......@@ -356,9 +357,8 @@ class Block : public BreakableStatement {
ZonePtrList<Statement> statements_;
Scope* scope_;
using IgnoreCompletionField =
BitField<bool, BreakableStatement::kNextBitFieldIndex, 1>;
using IsLabeledField = BitField<bool, IgnoreCompletionField::kNext, 1>;
using IgnoreCompletionField = BreakableStatement::NextBitField<bool, 1>;
using IsLabeledField = IgnoreCompletionField::Next<bool, 1>;
protected:
Block(Zone* zone, ZonePtrList<const AstRawString>* labels, int capacity,
......@@ -446,7 +446,7 @@ class VariableDeclaration : public Declaration {
private:
friend class AstNodeFactory;
using IsNestedField = BitField<bool, Declaration::kNextBitFieldIndex, 1>;
using IsNestedField = Declaration::NextBitField<bool, 1>;
protected:
explicit VariableDeclaration(int pos, bool is_nested = false)
......@@ -454,7 +454,8 @@ class VariableDeclaration : public Declaration {
bit_field_ = IsNestedField::update(bit_field_, is_nested);
}
static const uint8_t kNextBitFieldIndex = IsNestedField::kNext;
template <class T, int size>
using NextBitField = IsNestedField::Next<T, size>;
};
// For var declarations that appear in a block scope.
......@@ -521,9 +522,6 @@ class IterationStatement : public BreakableStatement {
body_(nullptr) {}
void Initialize(Statement* body) { body_ = body; }
static const uint8_t kNextBitFieldIndex =
BreakableStatement::kNextBitFieldIndex;
private:
ZonePtrList<const AstRawString>* labels_;
ZonePtrList<const AstRawString>* own_labels_;
......@@ -737,7 +735,7 @@ class ReturnStatement final : public JumpStatement {
Expression* expression_;
int end_position_;
using TypeField = BitField<Type, JumpStatement::kNextBitFieldIndex, 1>;
using TypeField = JumpStatement::NextBitField<Type, 1>;
};
......@@ -973,7 +971,7 @@ class SloppyBlockFunctionStatement final : public Statement {
private:
friend class AstNodeFactory;
using TokenField = BitField<Token::Value, Statement::kNextBitFieldIndex, 8>;
using TokenField = Statement::NextBitField<Token::Value, 8>;
SloppyBlockFunctionStatement(int pos, Variable* var, Token::Value init,
Statement* statement)
......@@ -1074,7 +1072,7 @@ class Literal final : public Expression {
private:
friend class AstNodeFactory;
using TypeField = BitField<Type, Expression::kNextBitFieldIndex, 4>;
using TypeField = Expression::NextBitField<Type, 4>;
Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) {
bit_field_ = TypeField::update(bit_field_, kSmi);
......@@ -1206,9 +1204,8 @@ class AggregateLiteral : public MaterializedLiteral {
private:
int depth_ : 31;
using NeedsInitialAllocationSiteField =
BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1>;
using IsSimpleField =
BitField<bool, NeedsInitialAllocationSiteField::kNext, 1>;
MaterializedLiteral::NextBitField<bool, 1>;
using IsSimpleField = NeedsInitialAllocationSiteField::Next<bool, 1>;
protected:
friend class AstNodeFactory;
......@@ -1231,7 +1228,8 @@ class AggregateLiteral : public MaterializedLiteral {
bit_field_ = NeedsInitialAllocationSiteField::update(bit_field_, required);
}
static const uint8_t kNextBitFieldIndex = IsSimpleField::kNext;
template <class T, int size>
using NextBitField = IsSimpleField::Next<T, size>;
};
// Common supertype for ObjectLiteralProperty and ClassLiteralProperty
......@@ -1408,11 +1406,10 @@ class ObjectLiteral final : public AggregateLiteral {
Handle<ObjectBoilerplateDescription> boilerplate_description_;
ZoneList<Property*> properties_;
using HasElementsField =
BitField<bool, AggregateLiteral::kNextBitFieldIndex, 1>;
using HasRestPropertyField = BitField<bool, HasElementsField::kNext, 1>;
using FastElementsField = BitField<bool, HasRestPropertyField::kNext, 1>;
using HasNullPrototypeField = BitField<bool, FastElementsField::kNext, 1>;
using HasElementsField = AggregateLiteral::NextBitField<bool, 1>;
using HasRestPropertyField = HasElementsField::Next<bool, 1>;
using FastElementsField = HasRestPropertyField::Next<bool, 1>;
using HasNullPrototypeField = FastElementsField::Next<bool, 1>;
};
// An array literal has a literals object that is used
......@@ -1581,14 +1578,11 @@ class VariableProxy final : public Expression {
explicit VariableProxy(const VariableProxy* copy_from);
using IsAssignedField = BitField<bool, Expression::kNextBitFieldIndex, 1>;
using IsResolvedField = BitField<bool, IsAssignedField::kNext, 1>;
using IsRemovedFromUnresolvedField =
BitField<bool, IsResolvedField::kNext, 1>;
using IsNewTargetField =
BitField<bool, IsRemovedFromUnresolvedField::kNext, 1>;
using HoleCheckModeField =
BitField<HoleCheckMode, IsNewTargetField::kNext, 1>;
using IsAssignedField = Expression::NextBitField<bool, 1>;
using IsResolvedField = IsAssignedField::Next<bool, 1>;
using IsRemovedFromUnresolvedField = IsResolvedField::Next<bool, 1>;
using IsNewTargetField = IsRemovedFromUnresolvedField::Next<bool, 1>;
using HoleCheckModeField = IsNewTargetField::Next<HoleCheckMode, 1>;
union {
const AstRawString* raw_name_; // if !is_resolved_
......@@ -1753,8 +1747,8 @@ class Call final : public Expression {
arguments.CopyTo(&arguments_, zone);
}
using IsPossiblyEvalField = BitField<bool, Expression::kNextBitFieldIndex, 1>;
using IsTaggedTemplateField = BitField<bool, IsPossiblyEvalField::kNext, 1>;
using IsPossiblyEvalField = Expression::NextBitField<bool, 1>;
using IsTaggedTemplateField = IsPossiblyEvalField::Next<bool, 1>;
Expression* expression_;
ZonePtrList<Expression> arguments_;
......@@ -1846,8 +1840,7 @@ class UnaryOperation final : public Expression {
Expression* expression_;
using OperatorField =
BitField<Token::Value, Expression::kNextBitFieldIndex, 7>;
using OperatorField = Expression::NextBitField<Token::Value, 7>;
};
......@@ -1873,8 +1866,7 @@ class BinaryOperation final : public Expression {
Expression* left_;
Expression* right_;
using OperatorField =
BitField<Token::Value, Expression::kNextBitFieldIndex, 7>;
using OperatorField = Expression::NextBitField<Token::Value, 7>;
};
class NaryOperation final : public Expression {
......@@ -1933,8 +1925,7 @@ class NaryOperation final : public Expression {
};
ZoneVector<NaryOperationEntry> subsequent_;
using OperatorField =
BitField<Token::Value, Expression::kNextBitFieldIndex, 7>;
using OperatorField = Expression::NextBitField<Token::Value, 7>;
};
class CountOperation final : public Expression {
......@@ -1954,8 +1945,8 @@ class CountOperation final : public Expression {
bit_field_ |= IsPrefixField::encode(is_prefix) | TokenField::encode(op);
}
using IsPrefixField = BitField<bool, Expression::kNextBitFieldIndex, 1>;
using TokenField = BitField<Token::Value, IsPrefixField::kNext, 7>;
using IsPrefixField = Expression::NextBitField<bool, 1>;
using TokenField = IsPrefixField::Next<Token::Value, 7>;
Expression* expression_;
};
......@@ -1985,8 +1976,7 @@ class CompareOperation final : public Expression {
Expression* left_;
Expression* right_;
using OperatorField =
BitField<Token::Value, Expression::kNextBitFieldIndex, 7>;
using OperatorField = Expression::NextBitField<Token::Value, 7>;
};
......@@ -2078,8 +2068,8 @@ class Assignment : public Expression {
private:
friend class AstNodeFactory;
using TokenField = BitField<Token::Value, Expression::kNextBitFieldIndex, 7>;
using LookupHoistingModeField = BitField<bool, TokenField::kNext, 1>;
using TokenField = Expression::NextBitField<Token::Value, 7>;
using LookupHoistingModeField = TokenField::Next<bool, 1>;
Expression* target_;
Expression* value_;
......@@ -2137,8 +2127,7 @@ class Suspend : public Expression {
Expression* expression_;
using OnAbruptResumeField =
BitField<OnAbruptResume, Expression::kNextBitFieldIndex, 1>;
using OnAbruptResumeField = Expression::NextBitField<OnAbruptResume, 1>;
};
class Yield final : public Suspend {
......@@ -2375,17 +2364,15 @@ class FunctionLiteral final : public Expression {
body.CopyTo(&body_, zone);
}
using FunctionTypeBits =
BitField<FunctionType, Expression::kNextBitFieldIndex, 3>;
using Pretenure = BitField<bool, FunctionTypeBits::kNext, 1>;
using HasDuplicateParameters = BitField<bool, Pretenure::kNext, 1>;
using FunctionTypeBits = Expression::NextBitField<FunctionType, 3>;
using Pretenure = FunctionTypeBits::Next<bool, 1>;
using HasDuplicateParameters = Pretenure::Next<bool, 1>;
using DontOptimizeReasonField =
BitField<BailoutReason, HasDuplicateParameters::kNext, 8>;
HasDuplicateParameters::Next<BailoutReason, 8>;
using RequiresInstanceMembersInitializer =
BitField<bool, DontOptimizeReasonField::kNext, 1>;
using HasBracesField =
BitField<bool, RequiresInstanceMembersInitializer::kNext, 1>;
using OneshotIIFEBit = BitField<bool, HasBracesField::kNext, 1>;
DontOptimizeReasonField::Next<bool, 1>;
using HasBracesField = RequiresInstanceMembersInitializer::Next<bool, 1>;
using OneshotIIFEBit = HasBracesField::Next<bool, 1>;
// expected_property_count_ is the sum of instance fields and properties.
// It can vary depending on whether a function is lazily or eagerly parsed.
......@@ -2530,12 +2517,9 @@ class ClassLiteral final : public Expression {
ZonePtrList<Property>* properties_;
FunctionLiteral* static_fields_initializer_;
FunctionLiteral* instance_members_initializer_function_;
using HasNameStaticProperty =
BitField<bool, Expression::kNextBitFieldIndex, 1>;
using HasStaticComputedNames =
BitField<bool, HasNameStaticProperty::kNext, 1>;
using IsAnonymousExpression =
BitField<bool, HasStaticComputedNames::kNext, 1>;
using HasNameStaticProperty = Expression::NextBitField<bool, 1>;
using HasStaticComputedNames = HasNameStaticProperty::Next<bool, 1>;
using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>;
};
......
......@@ -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