From 7bda2df68831b0e64773dd9ac811c80539a09e20 Mon Sep 17 00:00:00 2001 From: Michael Lippautz Date: Wed, 2 Mar 2022 20:17:45 +0100 Subject: [PATCH] Move utils/pointer-with-payload.h -> base/pointer-with-payload.h The utility type is independent of V8 and useful for cppgc as well. Move to base/ to allow reusing. Change-Id: I9de9b4a87bb113fb4c2232d90253afb0f38faa68 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3497336 Reviewed-by: Leszek Swirski Commit-Queue: Michael Lippautz Cr-Commit-Position: refs/heads/main@{#79346} --- BUILD.bazel | 2 +- BUILD.gn | 2 +- src/ast/ast.h | 3 +- src/ast/scopes.h | 26 +++++---- src/{utils => base}/pointer-with-payload.h | 64 +++++++++++----------- src/maglev/maglev-regalloc-data.h | 4 +- src/parsing/func-name-inferrer.h | 22 +++++--- src/parsing/parser-base.h | 4 +- src/parsing/parser.h | 4 +- src/parsing/scanner.h | 1 - 10 files changed, 72 insertions(+), 60 deletions(-) rename src/{utils => base}/pointer-with-payload.h (68%) diff --git a/BUILD.bazel b/BUILD.bazel index 161737a5ef..33baed46b1 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -590,6 +590,7 @@ filegroup( "src/base/platform/semaphore.h", "src/base/platform/time.cc", "src/base/platform/time.h", + "src/base/pointer-with-payload.h", "src/base/platform/wrappers.h", "src/base/region-allocator.cc", "src/base/region-allocator.h", @@ -2050,7 +2051,6 @@ filegroup( "src/utils/memcopy.h", "src/utils/ostreams.cc", "src/utils/ostreams.h", - "src/utils/pointer-with-payload.h", "src/utils/scoped-list.h", "src/utils/utils-inl.h", "src/utils/utils.cc", diff --git a/BUILD.gn b/BUILD.gn index 21eeb17aff..eaf48e436d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -3438,7 +3438,6 @@ v8_header_set("v8_internal_headers") { "src/utils/locked-queue.h", "src/utils/memcopy.h", "src/utils/ostreams.h", - "src/utils/pointer-with-payload.h", "src/utils/scoped-list.h", "src/utils/utils-inl.h", "src/utils/utils.h", @@ -5143,6 +5142,7 @@ v8_component("v8_libbase") { "src/base/platform/time.h", "src/base/platform/wrappers.h", "src/base/platform/yield-processor.h", + "src/base/pointer-with-payload.h", "src/base/region-allocator.cc", "src/base/region-allocator.h", "src/base/ring-buffer.h", diff --git a/src/ast/ast.h b/src/ast/ast.h index 7fc74e4aba..ba2b87f30d 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -10,6 +10,7 @@ #include "src/ast/ast-value-factory.h" #include "src/ast/modules.h" #include "src/ast/variables.h" +#include "src/base/pointer-with-payload.h" #include "src/base/threaded-list.h" #include "src/codegen/bailout-reason.h" #include "src/codegen/label.h" @@ -1185,7 +1186,7 @@ class LiteralProperty : public ZoneObject { LiteralProperty(Expression* key, Expression* value, bool is_computed_name) : key_and_is_computed_name_(key, is_computed_name), value_(value) {} - PointerWithPayload key_and_is_computed_name_; + base::PointerWithPayload key_and_is_computed_name_; Expression* value_; }; diff --git a/src/ast/scopes.h b/src/ast/scopes.h index c2df57e14b..6f701ead0b 100644 --- a/src/ast/scopes.h +++ b/src/ast/scopes.h @@ -10,16 +10,28 @@ #include "src/ast/ast.h" #include "src/base/compiler-specific.h" #include "src/base/hashmap.h" +#include "src/base/pointer-with-payload.h" #include "src/base/threaded-list.h" #include "src/common/globals.h" #include "src/objects/function-kind.h" #include "src/objects/objects.h" -#include "src/utils/pointer-with-payload.h" #include "src/utils/utils.h" #include "src/zone/zone-hashmap.h" #include "src/zone/zone.h" namespace v8 { + +namespace internal { +class Scope; +} // namespace internal + +namespace base { +template <> +struct PointerWithPayloadTraits { + static constexpr int kAvailableBits = 1; +}; +} // namespace base + namespace internal { class AstNodeFactory; @@ -64,13 +76,6 @@ class VariableMap : public ZoneHashMap { Zone* zone() const { return allocator().zone(); } }; -class Scope; - -template <> -struct PointerWithPayloadTraits { - static constexpr int value = 1; -}; - // Global invariants after AST construction: Each reference (i.e. identifier) // to a JavaScript variable (including global properties) is represented by a // VariableProxy node. Immediately after AST construction and before variable @@ -155,7 +160,7 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // Upon move assignment we store whether the new inner scope calls eval into // the move target calls_eval bit, and restore calls eval on the outer // scope. - PointerWithPayload outer_scope_and_calls_eval_; + base::PointerWithPayload outer_scope_and_calls_eval_; Scope* top_inner_scope_; UnresolvedList::Iterator top_unresolved_; base::ThreadedList::Iterator top_local_; @@ -1548,7 +1553,8 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope { rare_data_and_is_parsing_heritage_.SetPayload(v); } - PointerWithPayload rare_data_and_is_parsing_heritage_; + base::PointerWithPayload + rare_data_and_is_parsing_heritage_; Variable* class_variable_ = nullptr; // These are only maintained when the scope is parsed, not when the // scope is deserialized. diff --git a/src/utils/pointer-with-payload.h b/src/base/pointer-with-payload.h similarity index 68% rename from src/utils/pointer-with-payload.h rename to src/base/pointer-with-payload.h index 6200f41077..94801a9af7 100644 --- a/src/utils/pointer-with-payload.h +++ b/src/base/pointer-with-payload.h @@ -2,21 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef V8_UTILS_POINTER_WITH_PAYLOAD_H_ -#define V8_UTILS_POINTER_WITH_PAYLOAD_H_ +#ifndef V8_BASE_POINTER_WITH_PAYLOAD_H_ +#define V8_BASE_POINTER_WITH_PAYLOAD_H_ #include #include -#include "include/v8config.h" #include "src/base/logging.h" namespace v8 { -namespace internal { +namespace base { template struct PointerWithPayloadTraits { - static constexpr int value = + static constexpr int kAvailableBits = alignof(PointerType) >= 8 ? 3 : alignof(PointerType) >= 4 ? 2 : 1; }; @@ -37,82 +36,83 @@ struct PointerWithPayloadTraits : public PointerWithPayloadTraits { // // Here we store a bool that needs 1 bit of storage state into the lower bits // of int *, which points to some int data; - template class PointerWithPayload { - // We have log2(ptr alignment) kAvailBits free to use - static constexpr int kAvailBits = PointerWithPayloadTraits< - typename std::remove_const::type>::value; - static_assert( - kAvailBits >= NumPayloadBits, - "Ptr does not have sufficient alignment for the selected amount of " - "storage bits."); - - static constexpr uintptr_t kPayloadMask = - (uintptr_t{1} << NumPayloadBits) - 1; - static constexpr uintptr_t kPointerMask = ~kPayloadMask; - public: PointerWithPayload() = default; explicit PointerWithPayload(PointerType* pointer) - : pointer_(reinterpret_cast(pointer)) { + : pointer_with_payload_(reinterpret_cast(pointer)) { DCHECK_EQ(GetPointer(), pointer); DCHECK_EQ(GetPayload(), static_cast(0)); } explicit PointerWithPayload(PayloadType payload) - : pointer_(static_cast(payload)) { + : pointer_with_payload_(static_cast(payload)) { DCHECK_EQ(GetPointer(), nullptr); DCHECK_EQ(GetPayload(), payload); } PointerWithPayload(PointerType* pointer, PayloadType payload) { - update(pointer, payload); + Update(pointer, payload); } V8_INLINE PointerType* GetPointer() const { - return reinterpret_cast(pointer_ & kPointerMask); + return reinterpret_cast(pointer_with_payload_ & kPointerMask); } // An optimized version of GetPointer for when we know the payload value. V8_INLINE PointerType* GetPointerWithKnownPayload(PayloadType payload) const { DCHECK_EQ(GetPayload(), payload); - return reinterpret_cast(pointer_ - + return reinterpret_cast(pointer_with_payload_ - static_cast(payload)); } V8_INLINE PointerType* operator->() const { return GetPointer(); } - V8_INLINE void update(PointerType* new_pointer, PayloadType new_payload) { - pointer_ = reinterpret_cast(new_pointer) | - static_cast(new_payload); + V8_INLINE void Update(PointerType* new_pointer, PayloadType new_payload) { + pointer_with_payload_ = reinterpret_cast(new_pointer) | + static_cast(new_payload); DCHECK_EQ(GetPayload(), new_payload); DCHECK_EQ(GetPointer(), new_pointer); } V8_INLINE void SetPointer(PointerType* newptr) { DCHECK_EQ(reinterpret_cast(newptr) & kPayloadMask, 0); - pointer_ = reinterpret_cast(newptr) | (pointer_ & kPayloadMask); + pointer_with_payload_ = reinterpret_cast(newptr) | + (pointer_with_payload_ & kPayloadMask); DCHECK_EQ(GetPointer(), newptr); } V8_INLINE PayloadType GetPayload() const { - return static_cast(pointer_ & kPayloadMask); + return static_cast(pointer_with_payload_ & kPayloadMask); } V8_INLINE void SetPayload(PayloadType new_payload) { uintptr_t new_payload_ptr = static_cast(new_payload); DCHECK_EQ(new_payload_ptr & kPayloadMask, new_payload_ptr); - pointer_ = (pointer_ & kPointerMask) | new_payload_ptr; + pointer_with_payload_ = + (pointer_with_payload_ & kPointerMask) | new_payload_ptr; DCHECK_EQ(GetPayload(), new_payload); } private: - uintptr_t pointer_ = 0; + static constexpr int kAvailableBits = PointerWithPayloadTraits< + typename std::remove_const::type>::kAvailableBits; + static_assert( + kAvailableBits >= NumPayloadBits, + "Ptr does not have sufficient alignment for the selected amount of " + "storage bits. Override PointerWithPayloadTraits to guarantee available " + "bits manually."); + + static constexpr uintptr_t kPayloadMask = + (uintptr_t{1} << NumPayloadBits) - 1; + static constexpr uintptr_t kPointerMask = ~kPayloadMask; + + uintptr_t pointer_with_payload_ = 0; }; -} // namespace internal +} // namespace base } // namespace v8 -#endif // V8_UTILS_POINTER_WITH_PAYLOAD_H_ +#endif // V8_BASE_POINTER_WITH_PAYLOAD_H_ diff --git a/src/maglev/maglev-regalloc-data.h b/src/maglev/maglev-regalloc-data.h index bf9aa42b30..455febb271 100644 --- a/src/maglev/maglev-regalloc-data.h +++ b/src/maglev/maglev-regalloc-data.h @@ -5,9 +5,9 @@ #ifndef V8_MAGLEV_MAGLEV_REGALLOC_DATA_H_ #define V8_MAGLEV_MAGLEV_REGALLOC_DATA_H_ +#include "src/base/pointer-with-payload.h" #include "src/codegen/register.h" #include "src/compiler/backend/instruction.h" -#include "src/utils/pointer-with-payload.h" namespace v8 { namespace internal { @@ -70,7 +70,7 @@ constexpr bool operator==(const RegisterStateFlags& left, left.is_merge == right.is_merge; } -typedef PointerWithPayload RegisterState; +typedef base::PointerWithPayload RegisterState; struct RegisterMerge { compiler::AllocatedOperand* operands() { diff --git a/src/parsing/func-name-inferrer.h b/src/parsing/func-name-inferrer.h index a8ebe59474..2c7f1d5817 100644 --- a/src/parsing/func-name-inferrer.h +++ b/src/parsing/func-name-inferrer.h @@ -8,23 +8,29 @@ #include #include "src/base/macros.h" -#include "src/utils/pointer-with-payload.h" +#include "src/base/pointer-with-payload.h" namespace v8 { + +namespace internal { +class AstRawString; +} + +namespace base { +template <> +struct PointerWithPayloadTraits { + static constexpr int kAvailableBits = 2; +}; +} // namespace base + namespace internal { class AstConsString; -class AstRawString; class AstValueFactory; class FunctionLiteral; enum class InferName { kYes, kNo }; -template <> -struct PointerWithPayloadTraits { - static constexpr int value = 2; -}; - // FuncNameInferrer is a stateful class that is used to perform name // inference for anonymous functions during static analysis of source code. // Inference is performed in cases when an anonymous function is assigned @@ -105,7 +111,7 @@ class FuncNameInferrer { Name(const AstRawString* name, NameType type) : name_and_type_(name, type) {} - PointerWithPayload name_and_type_; + base::PointerWithPayload name_and_type_; inline const AstRawString* name() const { return name_and_type_.GetPointer(); } diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h index decb5ac8e2..3c6559691a 100644 --- a/src/parsing/parser-base.h +++ b/src/parsing/parser-base.h @@ -15,6 +15,7 @@ #include "src/ast/scopes.h" #include "src/base/flags.h" #include "src/base/hashmap.h" +#include "src/base/pointer-with-payload.h" #include "src/base/v8-fallthrough.h" #include "src/codegen/bailout-reason.h" #include "src/common/globals.h" @@ -28,7 +29,6 @@ #include "src/parsing/scanner.h" #include "src/parsing/token.h" #include "src/regexp/regexp.h" -#include "src/utils/pointer-with-payload.h" #include "src/zone/zone-chunk-list.h" namespace v8 { @@ -482,7 +482,7 @@ class ParserBase { } private: - PointerWithPayload state_and_prev_value_; + base::PointerWithPayload state_and_prev_value_; }; class V8_NODISCARD LoopScope final { diff --git a/src/parsing/parser.h b/src/parsing/parser.h index 0895112f92..1d8fa2515d 100644 --- a/src/parsing/parser.h +++ b/src/parsing/parser.h @@ -12,6 +12,7 @@ #include "src/ast/ast.h" #include "src/ast/scopes.h" #include "src/base/compiler-specific.h" +#include "src/base/pointer-with-payload.h" #include "src/base/small-vector.h" #include "src/base/threaded-list.h" #include "src/common/globals.h" @@ -20,7 +21,6 @@ #include "src/parsing/parser-base.h" #include "src/parsing/parsing.h" #include "src/parsing/preparser.h" -#include "src/utils/pointer-with-payload.h" #include "src/zone/zone-chunk-list.h" namespace v8 { @@ -51,7 +51,7 @@ struct ParserFormalParameters : FormalParametersBase { position(position), initializer_end_position(initializer_end_position) {} - PointerWithPayload initializer_and_is_rest; + base::PointerWithPayload initializer_and_is_rest; Expression* pattern; Expression* initializer() const { diff --git a/src/parsing/scanner.h b/src/parsing/scanner.h index cc2ef52ce3..0fe907632d 100644 --- a/src/parsing/scanner.h +++ b/src/parsing/scanner.h @@ -21,7 +21,6 @@ #include "src/strings/char-predicates.h" #include "src/strings/unicode.h" #include "src/utils/allocation.h" -#include "src/utils/pointer-with-payload.h" namespace v8 { namespace internal {