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 <leszeks@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79346}
This commit is contained in:
Michael Lippautz 2022-03-02 20:17:45 +01:00 committed by V8 LUCI CQ
parent bceaab28a2
commit 7bda2df688
10 changed files with 72 additions and 60 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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<Expression, bool, 1> key_and_is_computed_name_;
base::PointerWithPayload<Expression, bool, 1> key_and_is_computed_name_;
Expression* value_;
};

View File

@ -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<v8::internal::Scope> {
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<Scope> {
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<Scope, bool, 1> outer_scope_and_calls_eval_;
base::PointerWithPayload<Scope, bool, 1> outer_scope_and_calls_eval_;
Scope* top_inner_scope_;
UnresolvedList::Iterator top_unresolved_;
base::ThreadedList<Variable>::Iterator top_local_;
@ -1548,7 +1553,8 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope {
rare_data_and_is_parsing_heritage_.SetPayload(v);
}
PointerWithPayload<RareData, bool, 1> rare_data_and_is_parsing_heritage_;
base::PointerWithPayload<RareData, bool, 1>
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.

View File

@ -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 <cstdint>
#include <type_traits>
#include "include/v8config.h"
#include "src/base/logging.h"
namespace v8 {
namespace internal {
namespace base {
template <typename PointerType>
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<void> : public PointerWithPayloadTraits<void*> {
//
// 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 <typename PointerType, typename PayloadType, int NumPayloadBits>
class PointerWithPayload {
// We have log2(ptr alignment) kAvailBits free to use
static constexpr int kAvailBits = PointerWithPayloadTraits<
typename std::remove_const<PointerType>::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<uintptr_t>(pointer)) {
: pointer_with_payload_(reinterpret_cast<uintptr_t>(pointer)) {
DCHECK_EQ(GetPointer(), pointer);
DCHECK_EQ(GetPayload(), static_cast<PayloadType>(0));
}
explicit PointerWithPayload(PayloadType payload)
: pointer_(static_cast<uintptr_t>(payload)) {
: pointer_with_payload_(static_cast<uintptr_t>(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<PointerType*>(pointer_ & kPointerMask);
return reinterpret_cast<PointerType*>(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<PointerType*>(pointer_ -
return reinterpret_cast<PointerType*>(pointer_with_payload_ -
static_cast<uintptr_t>(payload));
}
V8_INLINE PointerType* operator->() const { return GetPointer(); }
V8_INLINE void update(PointerType* new_pointer, PayloadType new_payload) {
pointer_ = reinterpret_cast<uintptr_t>(new_pointer) |
static_cast<uintptr_t>(new_payload);
V8_INLINE void Update(PointerType* new_pointer, PayloadType new_payload) {
pointer_with_payload_ = reinterpret_cast<uintptr_t>(new_pointer) |
static_cast<uintptr_t>(new_payload);
DCHECK_EQ(GetPayload(), new_payload);
DCHECK_EQ(GetPointer(), new_pointer);
}
V8_INLINE void SetPointer(PointerType* newptr) {
DCHECK_EQ(reinterpret_cast<uintptr_t>(newptr) & kPayloadMask, 0);
pointer_ = reinterpret_cast<uintptr_t>(newptr) | (pointer_ & kPayloadMask);
pointer_with_payload_ = reinterpret_cast<uintptr_t>(newptr) |
(pointer_with_payload_ & kPayloadMask);
DCHECK_EQ(GetPointer(), newptr);
}
V8_INLINE PayloadType GetPayload() const {
return static_cast<PayloadType>(pointer_ & kPayloadMask);
return static_cast<PayloadType>(pointer_with_payload_ & kPayloadMask);
}
V8_INLINE void SetPayload(PayloadType new_payload) {
uintptr_t new_payload_ptr = static_cast<uintptr_t>(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<PointerType>::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_

View File

@ -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<void, RegisterStateFlags, 2> RegisterState;
typedef base::PointerWithPayload<void, RegisterStateFlags, 2> RegisterState;
struct RegisterMerge {
compiler::AllocatedOperand* operands() {

View File

@ -8,23 +8,29 @@
#include <vector>
#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<v8::internal::AstRawString> {
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<AstRawString> {
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<const AstRawString, NameType, 2> name_and_type_;
base::PointerWithPayload<const AstRawString, NameType, 2> name_and_type_;
inline const AstRawString* name() const {
return name_and_type_.GetPointer();
}

View File

@ -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<FunctionState, bool, 1> state_and_prev_value_;
base::PointerWithPayload<FunctionState, bool, 1> state_and_prev_value_;
};
class V8_NODISCARD LoopScope final {

View File

@ -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<Expression, bool, 1> initializer_and_is_rest;
base::PointerWithPayload<Expression, bool, 1> initializer_and_is_rest;
Expression* pattern;
Expression* initializer() const {

View File

@ -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 {