Commit 4170e328 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ptr-compr][cleanup] Introduce TaggedImpl<> as a base for MaybeObject

This is a first step towards unification of Object and MaybeObject
definitions.

Having an TaggedImpl template will simplify adding compressed variants
of Object and MaybeObject which is required for avoiding unnecessary
value decompression in tight value copying loops and write barrier
implementations.

Bug: v8:7703, v8:9183
Change-Id: I4c1931c22359533d50cf4a2c7f1339dd55c0c707
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1588460Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61385}
parent ff2d4bc5
...@@ -2577,6 +2577,9 @@ v8_source_set("v8_base_without_compiler") { ...@@ -2577,6 +2577,9 @@ v8_source_set("v8_base_without_compiler") {
"src/objects/string.h", "src/objects/string.h",
"src/objects/struct-inl.h", "src/objects/struct-inl.h",
"src/objects/struct.h", "src/objects/struct.h",
"src/objects/tagged-impl-inl.h",
"src/objects/tagged-impl.cc",
"src/objects/tagged-impl.h",
"src/objects/template-objects-inl.h", "src/objects/template-objects-inl.h",
"src/objects/template-objects.cc", "src/objects/template-objects.cc",
"src/objects/template-objects.h", "src/objects/template-objects.h",
......
...@@ -548,6 +548,11 @@ static const intptr_t kPageAlignmentMask = (intptr_t{1} << kPageSizeBits) - 1; ...@@ -548,6 +548,11 @@ static const intptr_t kPageAlignmentMask = (intptr_t{1} << kPageSizeBits) - 1;
// If looking only at the top 32 bits, the QNaN mask is bits 19 to 30. // If looking only at the top 32 bits, the QNaN mask is bits 19 to 30.
constexpr uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32); constexpr uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32);
enum class HeapObjectReferenceType {
WEAK,
STRONG,
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Forward declarations for frequently used classes // Forward declarations for frequently used classes
...@@ -600,6 +605,8 @@ class NewSpace; ...@@ -600,6 +605,8 @@ class NewSpace;
class NewLargeObjectSpace; class NewLargeObjectSpace;
class NumberDictionary; class NumberDictionary;
class Object; class Object;
template <HeapObjectReferenceType kRefType, typename StorageType>
class TaggedImpl;
class CompressedObjectSlot; class CompressedObjectSlot;
class CompressedMaybeObjectSlot; class CompressedMaybeObjectSlot;
class CompressedMapWordSlot; class CompressedMapWordSlot;
...@@ -619,6 +626,7 @@ class Smi; ...@@ -619,6 +626,7 @@ class Smi;
template <typename Config, class Allocator = FreeStoreAllocationPolicy> template <typename Config, class Allocator = FreeStoreAllocationPolicy>
class SplayTree; class SplayTree;
class String; class String;
class StringStream;
class Struct; class Struct;
class Symbol; class Symbol;
class Variable; class Variable;
...@@ -1453,11 +1461,6 @@ enum IsolateAddressId { ...@@ -1453,11 +1461,6 @@ enum IsolateAddressId {
kIsolateAddressCount kIsolateAddressCount
}; };
enum class HeapObjectReferenceType {
WEAK,
STRONG,
};
enum class PoisoningMitigationLevel { enum class PoisoningMitigationLevel {
kPoisonAll, kPoisonAll,
kDontPoison, kDontPoison,
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "src/objects/fixed-array.h" #include "src/objects/fixed-array.h"
#include "src/objects/heap-object.h" #include "src/objects/heap-object.h"
#include "src/objects/maybe-object-inl.h" #include "src/objects/maybe-object-inl.h"
#include "src/objects/slots.h" #include "src/objects/slots-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
......
...@@ -14,9 +14,6 @@ namespace internal { ...@@ -14,9 +14,6 @@ namespace internal {
class Code; class Code;
class FixedArray; class FixedArray;
class Heap; class Heap;
class HeapObject;
class MaybeObject;
class Object;
class RelocInfo; class RelocInfo;
class EphemeronHashTable; class EphemeronHashTable;
......
...@@ -2396,13 +2396,15 @@ void InterpreterData::InterpreterDataPrint(std::ostream& os) { // NOLINT ...@@ -2396,13 +2396,15 @@ void InterpreterData::InterpreterDataPrint(std::ostream& os) { // NOLINT
os << "\n"; os << "\n";
} }
void MaybeObject::Print() { template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::Print() {
StdoutStream os; StdoutStream os;
this->Print(os); this->Print(os);
os << std::flush; os << std::flush;
} }
void MaybeObject::Print(std::ostream& os) { template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::Print(std::ostream& os) {
Smi smi; Smi smi;
HeapObject heap_object; HeapObject heap_object;
if (ToSmi(&smi)) { if (ToSmi(&smi)) {
......
...@@ -1804,22 +1804,6 @@ std::ostream& operator<<(std::ostream& os, const Object& obj) { ...@@ -1804,22 +1804,6 @@ std::ostream& operator<<(std::ostream& os, const Object& obj) {
return os; return os;
} }
void MaybeObject::ShortPrint(FILE* out) {
OFStream os(out);
os << Brief(*this);
}
void MaybeObject::ShortPrint(StringStream* accumulator) {
std::ostringstream os;
os << Brief(*this);
accumulator->Add(os.str().c_str());
}
void MaybeObject::ShortPrint(std::ostream& os) { os << Brief(*this); }
Brief::Brief(const Object v) : value(v->ptr()) {}
Brief::Brief(const MaybeObject v) : value(v.ptr()) {}
std::ostream& operator<<(std::ostream& os, const Brief& v) { std::ostream& operator<<(std::ostream& os, const Brief& v) {
MaybeObject maybe_object(v.value); MaybeObject maybe_object(v.value);
Smi smi; Smi smi;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "src/message-template.h" #include "src/message-template.h"
#include "src/objects-definitions.h" #include "src/objects-definitions.h"
#include "src/objects/object-list-macros.h" #include "src/objects/object-list-macros.h"
#include "src/objects/tagged-impl.h"
#include "src/property-details.h" #include "src/property-details.h"
#include "src/utils.h" #include "src/utils.h"
...@@ -716,8 +717,8 @@ bool Object::IsHeapObject() const { ...@@ -716,8 +717,8 @@ bool Object::IsHeapObject() const {
} }
struct Brief { struct Brief {
V8_EXPORT_PRIVATE explicit Brief(const Object v); template <typename TObject>
explicit Brief(const MaybeObject v); explicit Brief(TObject v) : value{v.ptr()} {}
// {value} is a tagged heap object reference (weak or strong), equivalent to // {value} is a tagged heap object reference (weak or strong), equivalent to
// a MaybeObject's payload. It has a plain Address type to keep #includes // a MaybeObject's payload. It has a plain Address type to keep #includes
// lightweight. // lightweight.
......
...@@ -22,7 +22,6 @@ class ByteArray; ...@@ -22,7 +22,6 @@ class ByteArray;
class BytecodeArray; class BytecodeArray;
class CodeDataContainer; class CodeDataContainer;
class CodeDesc; class CodeDesc;
class MaybeObject;
namespace interpreter { namespace interpreter {
class Register; class Register;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "src/lookup-cache-inl.h" #include "src/lookup-cache-inl.h"
#include "src/maybe-handles-inl.h" #include "src/maybe-handles-inl.h"
#include "src/objects/heap-object-inl.h" #include "src/objects/heap-object-inl.h"
#include "src/objects/maybe-object.h" #include "src/objects/maybe-object-inl.h"
#include "src/objects/struct-inl.h" #include "src/objects/struct-inl.h"
#include "src/property.h" #include "src/property.h"
......
...@@ -17,9 +17,6 @@ ...@@ -17,9 +17,6 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
OBJECT_CONSTRUCTORS_IMPL(HeapObject, Object)
CAST_ACCESSOR(HeapObject)
HeapObject::HeapObject(Address ptr, AllowInlineSmiStorage allow_smi) HeapObject::HeapObject(Address ptr, AllowInlineSmiStorage allow_smi)
: Object(ptr) { : Object(ptr) {
SLOW_DCHECK( SLOW_DCHECK(
...@@ -27,12 +24,6 @@ HeapObject::HeapObject(Address ptr, AllowInlineSmiStorage allow_smi) ...@@ -27,12 +24,6 @@ HeapObject::HeapObject(Address ptr, AllowInlineSmiStorage allow_smi)
IsHeapObject()); IsHeapObject());
} }
// static
HeapObject HeapObject::FromAddress(Address address) {
DCHECK_TAG_ALIGNED(address);
return HeapObject(address + kHeapObjectTag);
}
// static // static
Heap* NeverReadOnlySpaceObject::GetHeap(const HeapObject object) { Heap* NeverReadOnlySpaceObject::GetHeap(const HeapObject object) {
return GetHeapFromWritableObject(object); return GetHeapFromWritableObject(object);
......
...@@ -85,7 +85,10 @@ class HeapObject : public Object { ...@@ -85,7 +85,10 @@ class HeapObject : public Object {
#undef DECL_STRUCT_PREDICATE #undef DECL_STRUCT_PREDICATE
// Converts an address to a HeapObject pointer. // Converts an address to a HeapObject pointer.
static inline HeapObject FromAddress(Address address); static inline HeapObject FromAddress(Address address) {
DCHECK_TAG_ALIGNED(address);
return HeapObject(address + kHeapObjectTag);
}
// Returns the address of this HeapObject. // Returns the address of this HeapObject.
inline Address address() const { return ptr() - kHeapObjectTag; } inline Address address() const { return ptr() - kHeapObjectTag; }
...@@ -197,6 +200,9 @@ class HeapObject : public Object { ...@@ -197,6 +200,9 @@ class HeapObject : public Object {
OBJECT_CONSTRUCTORS(HeapObject, Object); OBJECT_CONSTRUCTORS(HeapObject, Object);
}; };
OBJECT_CONSTRUCTORS_IMPL(HeapObject, Object)
CAST_ACCESSOR(HeapObject)
// Helper class for objects that can never be in RO space. // Helper class for objects that can never be in RO space.
class NeverReadOnlySpaceObject { class NeverReadOnlySpaceObject {
public: public:
......
...@@ -10,107 +10,52 @@ ...@@ -10,107 +10,52 @@
#ifdef V8_COMPRESS_POINTERS #ifdef V8_COMPRESS_POINTERS
#include "src/isolate.h" #include "src/isolate.h"
#endif #endif
#include "src/objects/heap-object-inl.h"
#include "src/objects/slots-inl.h"
#include "src/objects/smi-inl.h" #include "src/objects/smi-inl.h"
#include "src/objects/tagged-impl-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
bool MaybeObject::ToSmi(Smi* value) { //
if (HAS_SMI_TAG(ptr_)) { // MaybeObject implementation.
*value = Smi::cast(Object(ptr_)); //
return true;
}
return false;
}
Smi MaybeObject::ToSmi() const {
DCHECK(HAS_SMI_TAG(ptr_));
return Smi::cast(Object(ptr_));
}
bool MaybeObject::IsStrongOrWeak() const {
if (IsSmi() || IsCleared()) {
return false;
}
return true;
}
bool MaybeObject::GetHeapObject(HeapObject* result) const {
if (IsSmi() || IsCleared()) {
return false;
}
*result = GetHeapObject();
return true;
}
bool MaybeObject::GetHeapObject(HeapObject* result, // static
HeapObjectReferenceType* reference_type) const { MaybeObject MaybeObject::FromSmi(Smi smi) {
if (IsSmi() || IsCleared()) { DCHECK(HAS_SMI_TAG(smi->ptr()));
return false; return MaybeObject(smi->ptr());
}
*reference_type = HAS_WEAK_HEAP_OBJECT_TAG(ptr_)
? HeapObjectReferenceType::WEAK
: HeapObjectReferenceType::STRONG;
*result = GetHeapObject();
return true;
}
bool MaybeObject::IsStrong() const { return HAS_STRONG_HEAP_OBJECT_TAG(ptr_); }
bool MaybeObject::GetHeapObjectIfStrong(HeapObject* result) const {
if (!HAS_WEAK_HEAP_OBJECT_TAG(ptr_) && !IsSmi()) {
*result = HeapObject::cast(Object(ptr_));
return true;
}
return false;
}
HeapObject MaybeObject::GetHeapObjectAssumeStrong() const {
DCHECK(IsStrong());
return HeapObject::cast(Object(ptr_));
}
bool MaybeObject::IsWeak() const {
return HAS_WEAK_HEAP_OBJECT_TAG(ptr_) && !IsCleared();
} }
bool MaybeObject::IsWeakOrCleared() const { // static
return HAS_WEAK_HEAP_OBJECT_TAG(ptr_); MaybeObject MaybeObject::FromObject(Object object) {
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(object.ptr()));
return MaybeObject(object.ptr());
} }
bool MaybeObject::GetHeapObjectIfWeak(HeapObject* result) const { MaybeObject MaybeObject::MakeWeak(MaybeObject object) {
if (IsWeak()) { DCHECK(object.IsStrongOrWeak());
*result = GetHeapObject(); return MaybeObject(object.ptr() | kWeakHeapObjectMask);
return true;
}
return false;
} }
HeapObject MaybeObject::GetHeapObjectAssumeWeak() const { //
DCHECK(IsWeak()); // HeapObjectReference implementation.
return GetHeapObject(); //
}
HeapObject MaybeObject::GetHeapObject() const { HeapObjectReference::HeapObjectReference(Object object)
DCHECK(!IsSmi()); : MaybeObject(object->ptr()) {}
DCHECK(!IsCleared());
return HeapObject::cast(Object(ptr_ & ~kWeakHeapObjectMask));
}
Object MaybeObject::GetHeapObjectOrSmi() const { // static
if (IsSmi()) { HeapObjectReference HeapObjectReference::Strong(Object object) {
return Object(ptr_); DCHECK(!object->IsSmi());
} DCHECK(!HasWeakHeapObjectTag(object));
return GetHeapObject(); return HeapObjectReference(object);
} }
bool MaybeObject::IsObject() const { return IsSmi() || IsStrong(); } // static
HeapObjectReference HeapObjectReference::Weak(Object object) {
MaybeObject MaybeObject::MakeWeak(MaybeObject object) { DCHECK(!object->IsSmi());
DCHECK(object.IsStrongOrWeak()); DCHECK(!HasWeakHeapObjectTag(object));
return MaybeObject(object.ptr_ | kWeakHeapObjectMask); return HeapObjectReference(object->ptr() | kWeakHeapObjectMask);
} }
// static // static
......
...@@ -5,121 +5,31 @@ ...@@ -5,121 +5,31 @@
#ifndef V8_OBJECTS_MAYBE_OBJECT_H_ #ifndef V8_OBJECTS_MAYBE_OBJECT_H_
#define V8_OBJECTS_MAYBE_OBJECT_H_ #define V8_OBJECTS_MAYBE_OBJECT_H_
#include "include/v8-internal.h" #include "src/objects/tagged-impl.h"
#include "include/v8.h"
#include "src/globals.h"
#include "src/objects.h"
#include "src/objects/smi.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class HeapObject;
class Isolate;
class StringStream;
// A MaybeObject is either a SMI, a strong reference to a HeapObject, a weak // A MaybeObject is either a SMI, a strong reference to a HeapObject, a weak
// reference to a HeapObject, or a cleared weak reference. It's used for // reference to a HeapObject, or a cleared weak reference. It's used for
// implementing in-place weak references (see design doc: goo.gl/j6SdcK ) // implementing in-place weak references (see design doc: goo.gl/j6SdcK )
class MaybeObject { class MaybeObject : public TaggedImpl<HeapObjectReferenceType::WEAK, Address> {
public: public:
MaybeObject() : ptr_(kNullAddress) {} constexpr MaybeObject() : TaggedImpl(kNullAddress) {}
explicit MaybeObject(Address ptr) : ptr_(ptr) {} constexpr explicit MaybeObject(Address ptr) : TaggedImpl(ptr) {}
bool operator==(const MaybeObject& other) const { return ptr_ == other.ptr_; }
bool operator!=(const MaybeObject& other) const { return ptr_ != other.ptr_; }
Address ptr() const { return ptr_; }
// Enable incremental transition of client code.
MaybeObject* operator->() { return this; }
const MaybeObject* operator->() const { return this; }
bool IsSmi() const { return HAS_SMI_TAG(ptr_); }
inline bool ToSmi(Smi* value);
inline Smi ToSmi() const;
bool IsCleared() const {
return static_cast<uint32_t>(ptr_) == kClearedWeakHeapObjectLower32;
}
inline bool IsStrongOrWeak() const;
inline bool IsStrong() const;
// If this MaybeObject is a strong pointer to a HeapObject, returns true and
// sets *result. Otherwise returns false.
inline bool GetHeapObjectIfStrong(HeapObject* result) const;
// DCHECKs that this MaybeObject is a strong pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeStrong() const;
inline bool IsWeak() const;
inline bool IsWeakOrCleared() const;
// If this MaybeObject is a weak pointer to a HeapObject, returns true and
// sets *result. Otherwise returns false.
inline bool GetHeapObjectIfWeak(HeapObject* result) const;
// DCHECKs that this MaybeObject is a weak pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeWeak() const;
// If this MaybeObject is a strong or weak pointer to a HeapObject, returns // These operator->() overloads are required for handlified code.
// true and sets *result. Otherwise returns false. constexpr const MaybeObject* operator->() const { return this; }
inline bool GetHeapObject(HeapObject* result) const;
inline bool GetHeapObject(HeapObject* result,
HeapObjectReferenceType* reference_type) const;
// DCHECKs that this MaybeObject is a strong or a weak pointer to a HeapObject V8_INLINE static MaybeObject FromSmi(Smi smi);
// and returns the HeapObject.
inline HeapObject GetHeapObject() const;
// DCHECKs that this MaybeObject is a strong or a weak pointer to a HeapObject V8_INLINE static MaybeObject FromObject(Object object);
// or a SMI and returns the HeapObject or SMI.
inline Object GetHeapObjectOrSmi() const;
inline bool IsObject() const; V8_INLINE static MaybeObject MakeWeak(MaybeObject object);
template <typename T>
T cast() const {
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
return T::cast(Object(ptr_));
}
static MaybeObject FromSmi(Smi smi) {
DCHECK(HAS_SMI_TAG(smi->ptr()));
return MaybeObject(smi->ptr());
}
static MaybeObject FromObject(Object object) {
DCHECK(!HasWeakHeapObjectTag(object));
return MaybeObject(object.ptr());
}
static inline MaybeObject MakeWeak(MaybeObject object);
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject p); static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject p);
#endif #endif
// Prints this object without details.
void ShortPrint(FILE* out = stdout);
// Prints this object without details to a message accumulator.
void ShortPrint(StringStream* accumulator);
void ShortPrint(std::ostream& os);
#ifdef OBJECT_PRINT
void Print();
void Print(std::ostream& os);
#else
void Print() { ShortPrint(); }
void Print(std::ostream& os) { ShortPrint(os); }
#endif
private:
Address ptr_;
}; };
// A HeapObjectReference is either a strong reference to a HeapObject, a weak // A HeapObjectReference is either a strong reference to a HeapObject, a weak
...@@ -127,19 +37,11 @@ class MaybeObject { ...@@ -127,19 +37,11 @@ class MaybeObject {
class HeapObjectReference : public MaybeObject { class HeapObjectReference : public MaybeObject {
public: public:
explicit HeapObjectReference(Address address) : MaybeObject(address) {} explicit HeapObjectReference(Address address) : MaybeObject(address) {}
explicit HeapObjectReference(Object object) : MaybeObject(object->ptr()) {} V8_INLINE explicit HeapObjectReference(Object object);
static HeapObjectReference Strong(Object object) { V8_INLINE static HeapObjectReference Strong(Object object);
DCHECK(!object->IsSmi());
DCHECK(!HasWeakHeapObjectTag(object)); V8_INLINE static HeapObjectReference Weak(Object object);
return HeapObjectReference(object);
}
static HeapObjectReference Weak(Object object) {
DCHECK(!object->IsSmi());
DCHECK(!HasWeakHeapObjectTag(object));
return HeapObjectReference(object->ptr() | kWeakHeapObjectMask);
}
V8_INLINE static HeapObjectReference ClearedValue(Isolate* isolate); V8_INLINE static HeapObjectReference ClearedValue(Isolate* isolate);
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "src/base/atomic-utils.h" #include "src/base/atomic-utils.h"
#include "src/memcopy.h" #include "src/memcopy.h"
#include "src/objects.h" #include "src/objects.h"
#include "src/objects/heap-object-inl.h" #include "src/objects/heap-object.h"
#include "src/objects/maybe-object.h" #include "src/objects/maybe-object.h"
#include "src/ptr-compr-inl.h" #include "src/ptr-compr-inl.h"
......
...@@ -13,9 +13,7 @@ ...@@ -13,9 +13,7 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
CAST_ACCESSOR(Smi) // TODO(ishell): remove this file
int Smi::ToInt(const Object object) { return Smi::cast(object)->value(); }
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -41,7 +41,9 @@ class Smi : public Object { ...@@ -41,7 +41,9 @@ class Smi : public Object {
} }
// Convert a Smi object to an int. // Convert a Smi object to an int.
static inline int ToInt(const Object object); static inline int ToInt(const Object object) {
return Smi::cast(object).value();
}
// Convert a value to a Smi object. // Convert a value to a Smi object.
static inline constexpr Smi FromInt(int value) { static inline constexpr Smi FromInt(int value) {
...@@ -107,6 +109,8 @@ class Smi : public Object { ...@@ -107,6 +109,8 @@ class Smi : public Object {
static constexpr int kMaxValue = kSmiMaxValue; static constexpr int kMaxValue = kSmiMaxValue;
}; };
CAST_ACCESSOR(Smi)
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
// 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_OBJECTS_TAGGED_IMPL_INL_H_
#define V8_OBJECTS_TAGGED_IMPL_INL_H_
#include "src/objects/tagged-impl.h"
#ifdef V8_COMPRESS_POINTERS
#include "src/isolate.h"
#endif
#include "src/objects/heap-object.h"
#include "src/objects/smi.h"
namespace v8 {
namespace internal {
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::ToSmi(Smi* value) const {
if (HAS_SMI_TAG(ptr_)) {
*value = Smi::cast(Object(ptr_));
return true;
}
return false;
}
template <HeapObjectReferenceType kRefType, typename StorageType>
Smi TaggedImpl<kRefType, StorageType>::ToSmi() const {
DCHECK(HAS_SMI_TAG(ptr_));
return Smi::cast(Object(ptr_));
}
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
HeapObject* result) const {
if (!IsStrongOrWeak()) return false;
*result = GetHeapObject();
return true;
}
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
HeapObject* result, HeapObjectReferenceType* reference_type) const {
if (!IsStrongOrWeak()) return false;
*reference_type = IsWeakOrCleared() ? HeapObjectReferenceType::WEAK
: HeapObjectReferenceType::STRONG;
*result = GetHeapObject();
return true;
}
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfStrong(
HeapObject* result) const {
if (IsStrong()) {
*result = HeapObject::cast(Object(ptr_));
return true;
}
return false;
}
template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeStrong()
const {
DCHECK(IsStrong());
return HeapObject::cast(Object(ptr_));
}
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfWeak(
HeapObject* result) const {
if (kCanBeWeak) {
if (IsWeak()) {
*result = GetHeapObject();
return true;
}
return false;
} else {
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
return false;
}
}
template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeWeak() const {
DCHECK(IsWeak());
return GetHeapObject();
}
template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObject() const {
DCHECK(!IsSmi());
if (kCanBeWeak) {
DCHECK(!IsCleared());
return HeapObject::cast(Object(ptr_ & ~kWeakHeapObjectMask));
} else {
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
return HeapObject::cast(Object(ptr_));
}
}
template <HeapObjectReferenceType kRefType, typename StorageType>
Object TaggedImpl<kRefType, StorageType>::GetHeapObjectOrSmi() const {
if (IsSmi()) {
return Object(ptr_);
}
return GetHeapObject();
}
} // namespace internal
} // namespace v8
#endif // V8_OBJECTS_TAGGED_IMPL_INL_H_
// 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.
#include "src/objects/tagged-impl.h"
#include <sstream>
#include "src/objects.h"
#include "src/ostreams.h"
#include "src/string-stream.h"
namespace v8 {
namespace internal {
template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::ShortPrint(FILE* out) {
OFStream os(out);
os << Brief(*this);
}
template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::ShortPrint(StringStream* accumulator) {
std::ostringstream os;
os << Brief(*this);
accumulator->Add(os.str().c_str());
}
template <HeapObjectReferenceType kRefType, typename StorageType>
void TaggedImpl<kRefType, StorageType>::ShortPrint(std::ostream& os) {
os << Brief(*this);
}
// Explicit instantiation declarations.
template class TaggedImpl<HeapObjectReferenceType::STRONG, Address>;
template class TaggedImpl<HeapObjectReferenceType::WEAK, Address>;
} // namespace internal
} // namespace v8
// 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_OBJECTS_TAGGED_IMPL_H_
#define V8_OBJECTS_TAGGED_IMPL_H_
#include "include/v8-internal.h"
#include "include/v8.h"
#include "src/globals.h"
namespace v8 {
namespace internal {
// An TaggedImpl is a base class for Object (which is either a Smi or a strong
// reference to a HeapObject) and MaybeObject (which is either a Smi, a strong
// reference to a HeapObject, a weak reference to a HeapObject, or a cleared
// weak reference.
// This class provides storage and one canonical implementation of various
// predicates that check Smi and heap object tags' values and also take into
// account whether the tagged value is expected to be weak reference to a
// HeapObject or cleared weak reference.
template <HeapObjectReferenceType kRefType, typename StorageType>
class TaggedImpl {
public:
static const bool kCanBeWeak = kRefType == HeapObjectReferenceType::WEAK;
constexpr TaggedImpl() : ptr_{} {}
explicit constexpr TaggedImpl(StorageType ptr) : ptr_(ptr) {}
// Make clang on Linux catch what MSVC complains about on Windows:
operator bool() const = delete;
constexpr bool operator==(TaggedImpl other) const {
return ptr_ == other.ptr_;
}
constexpr bool operator!=(TaggedImpl other) const {
return ptr_ != other.ptr_;
}
// For using in std::set and std::map.
constexpr bool operator<(TaggedImpl other) const {
return ptr_ < other.ptr();
}
constexpr StorageType ptr() const { return ptr_; }
// Returns true if this tagged value is a strong pointer to a HeapObject or
// Smi.
constexpr inline bool IsObject() const { return !IsWeakOrCleared(); }
// Returns true if this tagged value is a Smi.
constexpr bool IsSmi() const { return HAS_SMI_TAG(ptr_); }
inline bool ToSmi(Smi* value) const;
inline Smi ToSmi() const;
// Returns true if this tagged value is a strong pointer to a HeapObject.
constexpr inline bool IsHeapObject() const { return IsStrong(); }
// Returns true if this tagged value is a cleared weak reference.
constexpr inline bool IsCleared() const {
return kCanBeWeak &&
(static_cast<uint32_t>(ptr_) == kClearedWeakHeapObjectLower32);
}
// Returns true if this tagged value is a strong or weak pointer to a
// HeapObject.
constexpr inline bool IsStrongOrWeak() const {
return !IsSmi() && !IsCleared();
}
// Returns true if this tagged value is a strong pointer to a HeapObject.
constexpr inline bool IsStrong() const {
#ifdef V8_CAN_HAVE_DCHECK_IN_CONSTEXPR
DCHECK_IMPLIES(!kCanBeWeak, !IsSmi() == HAS_STRONG_HEAP_OBJECT_TAG(ptr_));
#endif
return kCanBeWeak ? HAS_STRONG_HEAP_OBJECT_TAG(ptr_) : !IsSmi();
}
// Returns true if this tagged value is a weak pointer to a HeapObject.
constexpr inline bool IsWeak() const {
return IsWeakOrCleared() && !IsCleared();
}
// Returns true if this tagged value is a weak pointer to a HeapObject or
// cleared weak reference.
constexpr inline bool IsWeakOrCleared() const {
return kCanBeWeak && HAS_WEAK_HEAP_OBJECT_TAG(ptr_);
}
// If this tagged value is a strong pointer to a HeapObject, returns true and
// sets *result. Otherwise returns false.
inline bool GetHeapObjectIfStrong(HeapObject* result) const;
// DCHECKs that this tagged value is a strong pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeStrong() const;
// If this tagged value is a weak pointer to a HeapObject, returns true and
// sets *result. Otherwise returns false.
inline bool GetHeapObjectIfWeak(HeapObject* result) const;
// DCHECKs that this tagged value is a weak pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeWeak() const;
// If this tagged value is a strong or weak pointer to a HeapObject, returns
// true and sets *result. Otherwise returns false.
inline bool GetHeapObject(HeapObject* result) const;
inline bool GetHeapObject(HeapObject* result,
HeapObjectReferenceType* reference_type) const;
// DCHECKs that this tagged value is a strong or a weak pointer to a
// HeapObject and returns the HeapObject.
inline HeapObject GetHeapObject() const;
// DCHECKs that this tagged value is a strong or a weak pointer to a
// HeapObject or a Smi and returns the HeapObject or Smi.
inline Object GetHeapObjectOrSmi() const;
template <typename T>
T cast() const {
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
return T::cast(Object(ptr_));
}
// Prints this object without details.
void ShortPrint(FILE* out = stdout);
// Prints this object without details to a message accumulator.
void ShortPrint(StringStream* accumulator);
void ShortPrint(std::ostream& os);
#ifdef OBJECT_PRINT
void Print();
void Print(std::ostream& os);
#else
void Print() { ShortPrint(); }
void Print(std::ostream& os) { ShortPrint(os); }
#endif
private:
friend class CompressedObjectSlot;
friend class FullObjectSlot;
StorageType ptr_;
};
} // namespace internal
} // namespace v8
#endif // V8_OBJECTS_TAGGED_IMPL_H_
...@@ -15,8 +15,6 @@ namespace v8 { ...@@ -15,8 +15,6 @@ namespace v8 {
namespace internal { namespace internal {
class CodeDataContainer; class CodeDataContainer;
class MaybeObject;
class Object;
#define ROOT_ID_LIST(V) \ #define ROOT_ID_LIST(V) \
V(kStringTable, "(Internalized strings)") \ V(kStringTable, "(Internalized strings)") \
......
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