[base] Move EnumSet to its own header

EnumSet currently lives in src/utils.h, which is a conglomerate of many
different helper functions and classes. In order to remove unneeded
include, move the EnumSet to its own header.

R=titzer@chromium.org

Bug: v8:7490, v8:8562
Change-Id: I979814167e87b914e9807b03e342d8b34e514331
Reviewed-on: https://chromium-review.googlesource.com/c/1409430
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58818}
This commit is contained in:
Clemens Hammacher 2019-01-14 17:52:32 +01:00 committed by Commit Bot
parent 97cdf35f4a
commit 94fbd51b95
10 changed files with 83 additions and 62 deletions

View File

@ -3080,6 +3080,7 @@ v8_component("v8_libbase") {
"src/base/debug/stack_trace.h",
"src/base/division-by-constant.cc",
"src/base/division-by-constant.h",
"src/base/enum-set.h",
"src/base/export-template.h",
"src/base/file-utils.cc",
"src/base/file-utils.h",

View File

@ -10,6 +10,7 @@
#include "src/asmjs/asm-scanner.h"
#include "src/asmjs/asm-types.h"
#include "src/base/enum-set.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/zone/zone-containers.h"
@ -47,7 +48,7 @@ class AsmJsParser {
};
// clang-format on
typedef EnumSet<StandardMember, uint64_t> StdlibSet;
using StdlibSet = base::EnumSet<StandardMember, uint64_t>;
explicit AsmJsParser(Zone* zone, uintptr_t stack_limit,
Utf16CharacterStream* stream);

56
src/base/enum-set.h Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_BASE_ENUM_SET_H_
#define V8_BASE_ENUM_SET_H_
#include <type_traits>
#include "src/base/logging.h"
namespace v8 {
namespace base {
// A poor man's version of STL's bitset: A bit set of enums E (without explicit
// values), fitting into an integral type T.
template <class E, class T = int>
class EnumSet {
static_assert(std::is_enum<E>::value, "EnumSet can only be used with enums");
public:
explicit EnumSet(T bits = 0) : bits_(bits) {}
bool IsEmpty() const { return bits_ == 0; }
bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
bool ContainsAnyOf(const EnumSet& set) const {
return (bits_ & set.bits_) != 0;
}
void Add(E element) { bits_ |= Mask(element); }
void Add(const EnumSet& set) { bits_ |= set.bits_; }
void Remove(E element) { bits_ &= ~Mask(element); }
void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
void RemoveAll() { bits_ = 0; }
void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
T ToIntegral() const { return bits_; }
bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
bool operator!=(const EnumSet& set) { return bits_ != set.bits_; }
EnumSet operator|(const EnumSet& set) const {
return EnumSet(bits_ | set.bits_);
}
EnumSet operator&(const EnumSet& set) const {
return EnumSet(bits_ & set.bits_);
}
private:
static T Mask(E element) {
DCHECK_GT(sizeof(T) * 8, static_cast<int>(element));
return T{1} << static_cast<typename std::underlying_type<E>::type>(element);
}
T bits_ = 0;
};
} // namespace base
} // namespace v8
#endif // V8_BASE_ENUM_SET_H_

View File

@ -4,6 +4,7 @@
#include "src/base/adapters.h"
#include "src/base/bits.h"
#include "src/base/enum-set.h"
#include "src/compiler/backend/instruction-selector-impl.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
@ -2720,7 +2721,7 @@ InstructionSelector::SupportedMachineOperatorFlags() {
// static
MachineOperatorBuilder::AlignmentRequirements
InstructionSelector::AlignmentRequirements() {
EnumSet<MachineRepresentation> req_aligned;
base::EnumSet<MachineRepresentation> req_aligned;
req_aligned.Add(MachineRepresentation::kFloat32);
req_aligned.Add(MachineRepresentation::kFloat64);
return MachineOperatorBuilder::AlignmentRequirements::

View File

@ -7,8 +7,8 @@
#include <algorithm>
#include <set>
#include "src/base/enum-set.h"
#include "src/register-configuration.h"
#include "src/utils.h"
namespace v8 {
namespace internal {
@ -86,8 +86,8 @@ MoveOperandKind GetKind(const InstructionOperand& move) {
} // namespace
void GapResolver::Resolve(ParallelMove* moves) {
EnumSet<MoveOperandKind, uint8_t> source_kinds;
EnumSet<MoveOperandKind, uint8_t> destination_kinds;
base::EnumSet<MoveOperandKind, uint8_t> source_kinds;
base::EnumSet<MoveOperandKind, uint8_t> destination_kinds;
// Remove redundant moves, collect source kinds and destination kinds to
// detect simple non-overlapping moves, and collect FP move representations if

View File

@ -6,10 +6,10 @@
#define V8_COMPILER_MACHINE_OPERATOR_H_
#include "src/base/compiler-specific.h"
#include "src/base/enum-set.h"
#include "src/base/flags.h"
#include "src/globals.h"
#include "src/machine-type.h"
#include "src/utils.h"
#include "src/zone/zone.h"
namespace v8 {
@ -172,8 +172,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
return AlignmentRequirements(kNoSupport);
}
static AlignmentRequirements SomeUnalignedAccessUnsupported(
EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes,
EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes) {
base::EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes,
base::EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes) {
return AlignmentRequirements(kSomeSupport, unalignedLoadUnsupportedTypes,
unalignedStoreUnsupportedTypes);
}
@ -181,15 +181,15 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
private:
explicit AlignmentRequirements(
AlignmentRequirements::UnalignedAccessSupport unalignedAccessSupport,
EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes =
EnumSet<MachineRepresentation>(),
EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes =
EnumSet<MachineRepresentation>())
base::EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes =
base::EnumSet<MachineRepresentation>(),
base::EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes =
base::EnumSet<MachineRepresentation>())
: unalignedSupport_(unalignedAccessSupport),
unalignedLoadUnsupportedTypes_(unalignedLoadUnsupportedTypes),
unalignedStoreUnsupportedTypes_(unalignedStoreUnsupportedTypes) {}
bool IsUnalignedSupported(EnumSet<MachineRepresentation> unsupported,
bool IsUnalignedSupported(base::EnumSet<MachineRepresentation> unsupported,
MachineRepresentation rep) const {
// All accesses of bytes in memory are aligned.
DCHECK_NE(MachineRepresentation::kWord8, rep);
@ -205,8 +205,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
}
const AlignmentRequirements::UnalignedAccessSupport unalignedSupport_;
const EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes_;
const EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes_;
const base::EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes_;
const base::EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes_;
};
explicit MachineOperatorBuilder(

View File

@ -796,45 +796,6 @@ class SimpleStringBuilder {
DISALLOW_IMPLICIT_CONSTRUCTORS(SimpleStringBuilder);
};
// A poor man's version of STL's bitset: A bit set of enums E (without explicit
// values), fitting into an integral type T.
template <class E, class T = int>
class EnumSet {
public:
explicit EnumSet(T bits = 0) : bits_(bits) {}
bool IsEmpty() const { return bits_ == 0; }
bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
bool ContainsAnyOf(const EnumSet& set) const {
return (bits_ & set.bits_) != 0;
}
void Add(E element) { bits_ |= Mask(element); }
void Add(const EnumSet& set) { bits_ |= set.bits_; }
void Remove(E element) { bits_ &= ~Mask(element); }
void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
void RemoveAll() { bits_ = 0; }
void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
T ToIntegral() const { return bits_; }
bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
bool operator!=(const EnumSet& set) { return bits_ != set.bits_; }
EnumSet operator|(const EnumSet& set) const {
return EnumSet(bits_ | set.bits_);
}
EnumSet operator&(const EnumSet& set) const {
return EnumSet(bits_ & set.bits_);
}
private:
static_assert(std::is_enum<E>::value, "EnumSet can only be used with enums");
static T Mask(E element) {
DCHECK_GT(sizeof(T) * CHAR_BIT, static_cast<int>(element));
return T{1} << static_cast<typename std::underlying_type<E>::type>(element);
}
T bits_;
};
// Bit field extraction.
inline uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x) {
return (x >> lsb) & ((1 << (1 + msb - lsb)) - 1);

View File

@ -6,6 +6,7 @@
#include "src/api.h"
#include "src/asmjs/asm-js.h"
#include "src/base/enum-set.h"
#include "src/base/template-utils.h"
#include "src/base/utils/random-number-generator.h"
#include "src/compiler/wasm-compiler.h"
@ -1669,7 +1670,7 @@ void CompilationStateImpl::OnFinishedUnit(ExecutionTier tier, WasmCode* code) {
DCHECK_IMPLIES(!is_tiering_mode, outstanding_tiering_units_ == 0);
// Bitset of events to deliver.
EnumSet<CompilationEvent> events;
base::EnumSet<CompilationEvent> events;
if (is_tiering_unit) {
DCHECK_LT(0, outstanding_tiering_units_);

View File

@ -32,13 +32,13 @@
#include "include/libplatform/libplatform.h"
#include "include/v8-platform.h"
#include "src/base/enum-set.h"
#include "src/debug/debug-interface.h"
#include "src/flags.h"
#include "src/heap/factory.h"
#include "src/isolate.h"
#include "src/objects.h"
#include "src/register-configuration.h"
#include "src/utils.h"
#include "src/v8.h"
#include "src/zone/accounting-allocator.h"
@ -94,7 +94,7 @@ enum CcTestExtensionIds {
};
#undef DEFINE_EXTENSION_ID
typedef v8::internal::EnumSet<CcTestExtensionIds> CcTestExtensionFlags;
using CcTestExtensionFlags = v8::base::EnumSet<CcTestExtensionIds>;
#define DEFINE_EXTENSION_FLAG(Name, Ident) \
static const CcTestExtensionFlags Name(1 << Name##_ID);
static const CcTestExtensionFlags NO_EXTENSIONS(0);

View File

@ -36,6 +36,7 @@
#include "src/api-inl.h"
#include "src/ast/ast-value-factory.h"
#include "src/ast/ast.h"
#include "src/base/enum-set.h"
#include "src/compiler.h"
#include "src/execution.h"
#include "src/flags.h"
@ -49,7 +50,6 @@
#include "src/parsing/rewriter.h"
#include "src/parsing/scanner-character-streams.h"
#include "src/parsing/token.h"
#include "src/utils.h"
#include "test/cctest/cctest.h"
#include "test/cctest/scope-test-helper.h"
@ -1550,7 +1550,7 @@ enum ParserSyncTestResult {
kError
};
void SetGlobalFlags(i::EnumSet<ParserFlag> flags) {
void SetGlobalFlags(base::EnumSet<ParserFlag> flags) {
i::FLAG_allow_natives_syntax = flags.Contains(kAllowNatives);
i::FLAG_harmony_public_fields = flags.Contains(kAllowHarmonyPublicFields);
i::FLAG_harmony_private_fields = flags.Contains(kAllowHarmonyPrivateFields);
@ -1562,7 +1562,7 @@ void SetGlobalFlags(i::EnumSet<ParserFlag> flags) {
flags.Contains(kAllowHarmonyNumericSeparator);
}
void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) {
void SetParserFlags(i::PreParser* parser, base::EnumSet<ParserFlag> flags) {
parser->set_allow_natives(flags.Contains(kAllowNatives));
parser->set_allow_harmony_public_fields(
flags.Contains(kAllowHarmonyPublicFields));
@ -1581,7 +1581,7 @@ void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) {
}
void TestParserSyncWithFlags(i::Handle<i::String> source,
i::EnumSet<ParserFlag> flags,
base::EnumSet<ParserFlag> flags,
ParserSyncTestResult result,
bool is_module = false, bool test_preparser = true,
bool ignore_error_msg = false) {
@ -1705,7 +1705,7 @@ void TestParserSync(const char* source, const ParserFlag* varying_flags,
->NewStringFromUtf8(Vector<const char>(source, strlen(source)))
.ToHandleChecked();
for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
i::EnumSet<ParserFlag> flags;
base::EnumSet<ParserFlag> flags;
for (size_t flag_index = 0; flag_index < varying_flags_length;
++flag_index) {
if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]);