[ptr-compr] Introduce StrongTaggedValue and TaggedValue
... which represent potentially compressed Object and MaybeObject
values respectively. They provide methods for checking the smi/weak
tags which don't require decompression and conversion to Smi/HeapObject
combined with tag checks.
The new classes should help to write a bit more efficient runtime (C++)
code for the cases when we don't need the full decompressed value
immediately.
Drive-by-fix: fix ptr-compr build after Object::operator->() removal.
Bug: v8:7703
Change-Id: I7a3d747ab6679120a2cca14e45b0d8bcf33fc496
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1624786
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61804}
diff --git a/BUILD.gn b/BUILD.gn
index b9149e3..029a66a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2628,6 +2628,8 @@
"src/objects/tagged-impl-inl.h",
"src/objects/tagged-impl.cc",
"src/objects/tagged-impl.h",
+ "src/objects/tagged-value-inl.h",
+ "src/objects/tagged-value.h",
"src/objects/template-objects-inl.h",
"src/objects/template-objects.cc",
"src/objects/template-objects.h",
diff --git a/src/execution/frames.cc b/src/execution/frames.cc
index 4eef4aa..cff51de 100644
--- a/src/execution/frames.cc
+++ b/src/execution/frames.cc
@@ -977,9 +977,7 @@
parameters_limit);
}
-#ifdef V8_COMPRESS_POINTERS
- Address isolate_root = isolate()->isolate_root();
-#endif
+ DEFINE_ROOT_VALUE(isolate());
// Visit pointer spill slots and locals.
for (unsigned index = 0; index < stack_slots; index++) {
int byte_index = index >> kBitsPerByteLog2;
@@ -998,8 +996,7 @@
if (!HAS_SMI_TAG(compressed_value)) {
// We don't need to update smi values.
*spill_slot.location() =
- DecompressTaggedPointer<OnHeapAddressKind::kIsolateRoot>(
- isolate_root, compressed_value);
+ DecompressTaggedPointer(ROOT_VALUE, compressed_value);
}
#endif
v->VisitRootPointer(Root::kTop, nullptr, spill_slot);
diff --git a/src/globals.h b/src/globals.h
index c5a1525..229123a 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -212,6 +212,15 @@
STATIC_ASSERT(kSystemPointerSize == (1 << kSystemPointerSizeLog2));
+// This macro is used for declaring and defining HeapObject getter methods that
+// are a bit more efficient for the pointer compression case than the default
+// parameterless getters because isolate root doesn't have to be computed from
+// arbitrary field address but it comes "for free" instead.
+// These alternatives are always defined (in order to avoid #ifdef mess but
+// are not supposed to be used when pointer compression is not enabled.
+#define ROOT_VALUE isolate_for_root
+#define ROOT_PARAM Isolate* const ROOT_VALUE
+
#ifdef V8_COMPRESS_POINTERS
static_assert(
kSystemPointerSize == kInt64Size,
@@ -225,6 +234,11 @@
using Tagged_t = int32_t;
using AtomicTagged_t = base::Atomic32;
+#define DEFINE_ROOT_VALUE(isolate) ROOT_PARAM = isolate
+#define WITH_ROOT_PARAM(...) ROOT_PARAM, ##__VA_ARGS__
+#define WITH_ROOT_VALUE(...) ROOT_VALUE, ##__VA_ARGS__
+#define WITH_ROOT(isolate_for_root, ...) isolate_for_root, ##__VA_ARGS__
+
#else
constexpr int kTaggedSize = kSystemPointerSize;
@@ -235,6 +249,11 @@
using Tagged_t = Address;
using AtomicTagged_t = base::AtomicWord;
+#define DEFINE_ROOT_VALUE(isolate)
+#define WITH_ROOT_PARAM(...) __VA_ARGS__
+#define WITH_ROOT_VALUE(...) __VA_ARGS__
+#define WITH_ROOT(isolate_for_root, ...) __VA_ARGS__
+
#endif // V8_COMPRESS_POINTERS
// Defines whether the branchless or branchful implementation of pointer
@@ -614,6 +633,8 @@
class Object;
template <HeapObjectReferenceType kRefType, typename StorageType>
class TaggedImpl;
+class StrongTaggedValue;
+class TaggedValue;
class CompressedObjectSlot;
class CompressedMaybeObjectSlot;
class CompressedMapWordSlot;
diff --git a/src/objects-body-descriptors-inl.h b/src/objects-body-descriptors-inl.h
index 6009f6b..b08c7ca 100644
--- a/src/objects-body-descriptors-inl.h
+++ b/src/objects-body-descriptors-inl.h
@@ -41,7 +41,7 @@
#ifdef V8_COMPRESS_POINTERS
STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kTaggedSize);
int embedder_fields_offset = JSObject::GetEmbedderFieldsStartOffset(map);
- int inobject_fields_offset = map->GetInObjectPropertyOffset(0);
+ int inobject_fields_offset = map.GetInObjectPropertyOffset(0);
// |embedder_fields_offset| may be greater than |inobject_fields_offset| if
// the object does not have embedder fields but the check handles this
// case properly.
@@ -77,7 +77,7 @@
#ifdef V8_COMPRESS_POINTERS
STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kTaggedSize);
int header_size = JSObject::GetHeaderSize(map);
- int inobject_fields_offset = map->GetInObjectPropertyOffset(0);
+ int inobject_fields_offset = map.GetInObjectPropertyOffset(0);
// We are always requested to process header and embedder fields.
DCHECK_LE(inobject_fields_offset, end_offset);
// Embedder fields are located between header and inobject properties.
diff --git a/src/objects/compressed-slots-inl.h b/src/objects/compressed-slots-inl.h
index 9c55de9..70638e0 100644
--- a/src/objects/compressed-slots-inl.h
+++ b/src/objects/compressed-slots-inl.h
@@ -28,7 +28,7 @@
}
void CompressedObjectSlot::store(Object value) const {
- *location() = CompressTagged(value->ptr());
+ *location() = CompressTagged(value.ptr());
}
Object CompressedObjectSlot::Acquire_Load() const {
@@ -42,19 +42,19 @@
}
void CompressedObjectSlot::Relaxed_Store(Object value) const {
- Tagged_t ptr = CompressTagged(value->ptr());
+ Tagged_t ptr = CompressTagged(value.ptr());
AsAtomicTagged::Relaxed_Store(location(), ptr);
}
void CompressedObjectSlot::Release_Store(Object value) const {
- Tagged_t ptr = CompressTagged(value->ptr());
+ Tagged_t ptr = CompressTagged(value.ptr());
AsAtomicTagged::Release_Store(location(), ptr);
}
Object CompressedObjectSlot::Release_CompareAndSwap(Object old,
Object target) const {
- Tagged_t old_ptr = CompressTagged(old->ptr());
- Tagged_t target_ptr = CompressTagged(target->ptr());
+ Tagged_t old_ptr = CompressTagged(old.ptr());
+ Tagged_t target_ptr = CompressTagged(target.ptr());
Tagged_t result =
AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr);
return Object(DecompressTaggedAny(address(), result));
@@ -95,14 +95,14 @@
}
void CompressedMapWordSlot::Release_Store(Object value) const {
- Tagged_t ptr = CompressTagged(value->ptr());
+ Tagged_t ptr = CompressTagged(value.ptr());
AsAtomicTagged::Release_Store(location(), ptr);
}
Object CompressedMapWordSlot::Release_CompareAndSwap(Object old,
Object target) const {
- Tagged_t old_ptr = CompressTagged(old->ptr());
- Tagged_t target_ptr = CompressTagged(target->ptr());
+ Tagged_t old_ptr = CompressTagged(old.ptr());
+ Tagged_t target_ptr = CompressTagged(target.ptr());
Tagged_t result =
AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr);
return Object(DecompressTaggedPointer(address(), result));
@@ -118,7 +118,7 @@
}
void CompressedMaybeObjectSlot::store(MaybeObject value) const {
- *location() = CompressTagged(value->ptr());
+ *location() = CompressTagged(value.ptr());
}
MaybeObject CompressedMaybeObjectSlot::Relaxed_Load() const {
@@ -127,14 +127,14 @@
}
void CompressedMaybeObjectSlot::Relaxed_Store(MaybeObject value) const {
- Tagged_t ptr = CompressTagged(value->ptr());
+ Tagged_t ptr = CompressTagged(value.ptr());
AsAtomicTagged::Relaxed_Store(location(), ptr);
}
void CompressedMaybeObjectSlot::Release_CompareAndSwap(
MaybeObject old, MaybeObject target) const {
- Tagged_t old_ptr = CompressTagged(old->ptr());
- Tagged_t target_ptr = CompressTagged(target->ptr());
+ Tagged_t old_ptr = CompressTagged(old.ptr());
+ Tagged_t target_ptr = CompressTagged(target.ptr());
AsAtomicTagged::Release_CompareAndSwap(location(), old_ptr, target_ptr);
}
@@ -158,7 +158,7 @@
}
void CompressedHeapObjectSlot::StoreHeapObject(HeapObject value) const {
- *location() = CompressTagged(value->ptr());
+ *location() = CompressTagged(value.ptr());
}
} // namespace internal
diff --git a/src/objects/elements.cc b/src/objects/elements.cc
index a08f1c5..f2a5998 100644
--- a/src/objects/elements.cc
+++ b/src/objects/elements.cc
@@ -476,8 +476,9 @@
AtomicSlot end(start + sort_size);
std::sort(start, end, [isolate](Tagged_t elementA, Tagged_t elementB) {
#ifdef V8_COMPRESS_POINTERS
- Object a(DecompressTaggedAny(isolate->isolate_root(), elementA));
- Object b(DecompressTaggedAny(isolate->isolate_root(), elementB));
+ DEFINE_ROOT_VALUE(isolate);
+ Object a(DecompressTaggedAny(ROOT_VALUE, elementA));
+ Object b(DecompressTaggedAny(ROOT_VALUE, elementB));
#else
Object a(elementA);
Object b(elementB);
diff --git a/src/objects/tagged-impl-inl.h b/src/objects/tagged-impl-inl.h
index 83437e3..a1b91e9 100644
--- a/src/objects/tagged-impl-inl.h
+++ b/src/objects/tagged-impl-inl.h
@@ -12,6 +12,8 @@
#endif
#include "src/objects/heap-object.h"
#include "src/objects/smi.h"
+#include "src/ptr-compr-inl.h"
+#include "src/roots-inl.h"
namespace v8 {
namespace internal {
@@ -19,7 +21,7 @@
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::ToSmi(Smi* value) const {
if (HAS_SMI_TAG(ptr_)) {
- *value = Smi::cast(Object(ptr_));
+ *value = ToSmi();
return true;
}
return false;
@@ -28,12 +30,21 @@
template <HeapObjectReferenceType kRefType, typename StorageType>
Smi TaggedImpl<kRefType, StorageType>::ToSmi() const {
DCHECK(HAS_SMI_TAG(ptr_));
- return Smi::cast(Object(ptr_));
+ if (kIsFull) {
+ return Smi(ptr_);
+ }
+ // Implementation for compressed pointers.
+ return Smi(DecompressTaggedSigned(static_cast<Tagged_t>(ptr_)));
}
+//
+// TaggedImpl::GetHeapObject(HeapObject* result) implementation.
+//
+
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
HeapObject* result) const {
+ CHECK(kIsFull);
if (!IsStrongOrWeak()) return false;
*result = GetHeapObject();
return true;
@@ -41,7 +52,24 @@
template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
+ ROOT_PARAM, HeapObject* result) const {
+ if (kIsFull) return GetHeapObject(result);
+ // Implementation for compressed pointers.
+ if (!IsStrongOrWeak()) return false;
+ *result = GetHeapObject(ROOT_VALUE);
+ return true;
+}
+
+//
+// TaggedImpl::GetHeapObject(HeapObject* result,
+// HeapObjectReferenceType* reference_type)
+// implementation.
+//
+
+template <HeapObjectReferenceType kRefType, typename StorageType>
+bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
HeapObject* result, HeapObjectReferenceType* reference_type) const {
+ CHECK(kIsFull);
if (!IsStrongOrWeak()) return false;
*reference_type = IsWeakOrCleared() ? HeapObjectReferenceType::WEAK
: HeapObjectReferenceType::STRONG;
@@ -50,8 +78,26 @@
}
template <HeapObjectReferenceType kRefType, typename StorageType>
+bool TaggedImpl<kRefType, StorageType>::GetHeapObject(
+ ROOT_PARAM, HeapObject* result,
+ HeapObjectReferenceType* reference_type) const {
+ if (kIsFull) return GetHeapObject(result, reference_type);
+ // Implementation for compressed pointers.
+ if (!IsStrongOrWeak()) return false;
+ *reference_type = IsWeakOrCleared() ? HeapObjectReferenceType::WEAK
+ : HeapObjectReferenceType::STRONG;
+ *result = GetHeapObject(ROOT_VALUE);
+ return true;
+}
+
+//
+// TaggedImpl::GetHeapObjectIfStrong(HeapObject* result) implementation.
+//
+
+template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfStrong(
HeapObject* result) const {
+ CHECK(kIsFull);
if (IsStrong()) {
*result = HeapObject::cast(Object(ptr_));
return true;
@@ -60,15 +106,47 @@
}
template <HeapObjectReferenceType kRefType, typename StorageType>
+bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfStrong(
+ ROOT_PARAM, HeapObject* result) const {
+ if (kIsFull) return GetHeapObjectIfStrong(result);
+ // Implementation for compressed pointers.
+ if (IsStrong()) {
+ *result =
+ HeapObject::cast(Object(DecompressTaggedPointer(ROOT_VALUE, ptr_)));
+ return true;
+ }
+ return false;
+}
+
+//
+// TaggedImpl::GetHeapObjectAssumeStrong() implementation.
+//
+
+template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeStrong()
const {
+ CHECK(kIsFull);
DCHECK(IsStrong());
return HeapObject::cast(Object(ptr_));
}
template <HeapObjectReferenceType kRefType, typename StorageType>
+HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeStrong(
+ ROOT_PARAM) const {
+ if (kIsFull) return GetHeapObjectAssumeStrong();
+ // Implementation for compressed pointers.
+ DCHECK(IsStrong());
+ return HeapObject::cast(Object(DecompressTaggedPointer(ROOT_VALUE, ptr_)));
+}
+
+//
+// TaggedImpl::GetHeapObjectIfWeak(HeapObject* result) implementation
+//
+
+template <HeapObjectReferenceType kRefType, typename StorageType>
bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfWeak(
HeapObject* result) const {
+ CHECK(kIsFull);
if (kCanBeWeak) {
if (IsWeak()) {
*result = GetHeapObject();
@@ -82,13 +160,49 @@
}
template <HeapObjectReferenceType kRefType, typename StorageType>
+bool TaggedImpl<kRefType, StorageType>::GetHeapObjectIfWeak(
+ ROOT_PARAM, HeapObject* result) const {
+ if (kIsFull) return GetHeapObjectIfWeak(result);
+ // Implementation for compressed pointers.
+ if (kCanBeWeak) {
+ if (IsWeak()) {
+ *result = GetHeapObject(ROOT_VALUE);
+ return true;
+ }
+ return false;
+ } else {
+ DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
+ return false;
+ }
+}
+
+//
+// TaggedImpl::GetHeapObjectAssumeWeak() implementation.
+//
+
+template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeWeak() const {
+ CHECK(kIsFull);
DCHECK(IsWeak());
return GetHeapObject();
}
template <HeapObjectReferenceType kRefType, typename StorageType>
+HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObjectAssumeWeak(
+ ROOT_PARAM) const {
+ if (kIsFull) return GetHeapObjectAssumeWeak();
+ // Implementation for compressed pointers.
+ DCHECK(IsWeak());
+ return GetHeapObject(ROOT_VALUE);
+}
+
+//
+// TaggedImpl::GetHeapObject() implementation.
+//
+
+template <HeapObjectReferenceType kRefType, typename StorageType>
HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObject() const {
+ CHECK(kIsFull);
DCHECK(!IsSmi());
if (kCanBeWeak) {
DCHECK(!IsCleared());
@@ -100,13 +214,43 @@
}
template <HeapObjectReferenceType kRefType, typename StorageType>
+HeapObject TaggedImpl<kRefType, StorageType>::GetHeapObject(ROOT_PARAM) const {
+ if (kIsFull) return GetHeapObject();
+ // Implementation for compressed pointers.
+ DCHECK(!IsSmi());
+ if (kCanBeWeak) {
+ DCHECK(!IsCleared());
+ return HeapObject::cast(Object(
+ DecompressTaggedPointer(ROOT_VALUE, ptr_ & ~kWeakHeapObjectMask)));
+ } else {
+ DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
+ return HeapObject::cast(Object(DecompressTaggedPointer(ROOT_VALUE, ptr_)));
+ }
+}
+
+//
+// TaggedImpl::GetHeapObjectOrSmi() implementation.
+//
+
+template <HeapObjectReferenceType kRefType, typename StorageType>
Object TaggedImpl<kRefType, StorageType>::GetHeapObjectOrSmi() const {
+ CHECK(kIsFull);
if (IsSmi()) {
return Object(ptr_);
}
return GetHeapObject();
}
+template <HeapObjectReferenceType kRefType, typename StorageType>
+Object TaggedImpl<kRefType, StorageType>::GetHeapObjectOrSmi(ROOT_PARAM) const {
+ if (kIsFull) return GetHeapObjectOrSmi();
+ // Implementation for compressed pointers.
+ if (IsSmi()) {
+ return Object(DecompressTaggedSigned(ptr_));
+ }
+ return GetHeapObject(ROOT_VALUE);
+}
+
} // namespace internal
} // namespace v8
diff --git a/src/objects/tagged-impl.h b/src/objects/tagged-impl.h
index 8e62cf5..8802698 100644
--- a/src/objects/tagged-impl.h
+++ b/src/objects/tagged-impl.h
@@ -23,6 +23,15 @@
template <HeapObjectReferenceType kRefType, typename StorageType>
class TaggedImpl {
public:
+ static_assert(std::is_same<StorageType, Address>::value ||
+ std::is_same<StorageType, Tagged_t>::value,
+ "StorageType must be either Address or Tagged_t");
+
+ // True for those TaggedImpl instantiations that represent uncompressed
+ // tagged values and false for TaggedImpl instantiations that represent
+ // compressed tagged values.
+ static const bool kIsFull = sizeof(StorageType) == kSystemPointerSize;
+
static const bool kCanBeWeak = kRefType == HeapObjectReferenceType::WEAK;
constexpr TaggedImpl() : ptr_{} {}
@@ -88,38 +97,57 @@
return kCanBeWeak && HAS_WEAK_HEAP_OBJECT_TAG(ptr_);
}
+ //
+ // The following set of methods get HeapObject out of the tagged value
+ // which may involve decompression in which case the ROOT_PARAM is required.
+ // If the pointer compression is not enabled then the variants with
+ // ROOT_PARAM will be exactly the same as non-ROOT_PARAM ones.
+ //
+
// 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;
+ inline bool GetHeapObjectIfStrong(ROOT_PARAM, HeapObject* result) const;
// DCHECKs that this tagged value is a strong pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeStrong() const;
+ inline HeapObject GetHeapObjectAssumeStrong(ROOT_PARAM) 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;
+ inline bool GetHeapObjectIfWeak(ROOT_PARAM, HeapObject* result) const;
// DCHECKs that this tagged value is a weak pointer to a HeapObject and
// returns the HeapObject.
inline HeapObject GetHeapObjectAssumeWeak() const;
+ inline HeapObject GetHeapObjectAssumeWeak(ROOT_PARAM) 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(ROOT_PARAM, HeapObject* result) const;
+
inline bool GetHeapObject(HeapObject* result,
HeapObjectReferenceType* reference_type) const;
+ inline bool GetHeapObject(ROOT_PARAM, 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;
+ inline HeapObject GetHeapObject(ROOT_PARAM) 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;
+ inline Object GetHeapObjectOrSmi(ROOT_PARAM) const;
+ // Cast operation is available only for full non-weak tagged values.
template <typename T>
T cast() const {
+ CHECK(kIsFull);
DCHECK(!HAS_WEAK_HEAP_OBJECT_TAG(ptr_));
return T::cast(Object(ptr_));
}
diff --git a/src/objects/tagged-value-inl.h b/src/objects/tagged-value-inl.h
new file mode 100644
index 0000000..2569fa9
--- /dev/null
+++ b/src/objects/tagged-value-inl.h
@@ -0,0 +1,39 @@
+// 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_VALUE_INL_H_
+#define V8_OBJECTS_TAGGED_VALUE_INL_H_
+
+#include "src/objects/tagged-value.h"
+
+#include "include/v8-internal.h"
+#include "src/objects/heap-object-inl.h"
+#include "src/objects/oddball.h"
+#include "src/objects/tagged-impl-inl.h"
+#include "src/ptr-compr-inl.h"
+#include "src/roots-inl.h"
+
+namespace v8 {
+namespace internal {
+
+Object StrongTaggedValue::ToObject(WITH_ROOT_PARAM(StrongTaggedValue object)) {
+#ifdef V8_COMPRESS_POINTERS
+ return Object(DecompressTaggedAny(ROOT_VALUE, object.ptr()));
+#else
+ return Object(object.ptr());
+#endif
+}
+
+MaybeObject TaggedValue::ToMaybeObject(WITH_ROOT_PARAM(TaggedValue object)) {
+#ifdef V8_COMPRESS_POINTERS
+ return MaybeObject(DecompressTaggedAny(ROOT_VALUE, object.ptr()));
+#else
+ return MaybeObject(object.ptr());
+#endif
+}
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_OBJECTS_TAGGED_VALUE_INL_H_
diff --git a/src/objects/tagged-value.h b/src/objects/tagged-value.h
new file mode 100644
index 0000000..bb7609f
--- /dev/null
+++ b/src/objects/tagged-value.h
@@ -0,0 +1,42 @@
+// 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_VALUE_H_
+#define V8_OBJECTS_TAGGED_VALUE_H_
+
+#include "src/objects/objects.h"
+
+#include "include/v8-internal.h"
+#include "src/objects/tagged-impl.h"
+
+namespace v8 {
+namespace internal {
+
+// Almost same as Object but this one deals with in-heap and potentially
+// compressed representation of Objects and provide only limited functionality
+// which doesn't require decompression.
+class StrongTaggedValue
+ : public TaggedImpl<HeapObjectReferenceType::STRONG, Tagged_t> {
+ public:
+ constexpr StrongTaggedValue() : TaggedImpl() {}
+ explicit constexpr StrongTaggedValue(Tagged_t ptr) : TaggedImpl(ptr) {}
+
+ inline static Object ToObject(WITH_ROOT_PARAM(StrongTaggedValue object));
+};
+
+// Almost same as MaybeObject but this one deals with in-heap and potentially
+// compressed representation of Objects and provide only limited functionality
+// which doesn't require decompression.
+class TaggedValue : public TaggedImpl<HeapObjectReferenceType::WEAK, Tagged_t> {
+ public:
+ constexpr TaggedValue() : TaggedImpl() {}
+ explicit constexpr TaggedValue(Tagged_t ptr) : TaggedImpl(ptr) {}
+
+ inline static MaybeObject ToMaybeObject(WITH_ROOT_PARAM(TaggedValue object));
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_OBJECTS_TAGGED_VALUE_H_
diff --git a/src/ptr-compr-inl.h b/src/ptr-compr-inl.h
index 98f94b3..d05650f 100644
--- a/src/ptr-compr-inl.h
+++ b/src/ptr-compr-inl.h
@@ -5,8 +5,8 @@
#ifndef V8_PTR_COMPR_INL_H_
#define V8_PTR_COMPR_INL_H_
-
#include "include/v8-internal.h"
+#include "src/execution/isolate.h"
#include "src/ptr-compr.h"
namespace v8 {
@@ -19,34 +19,49 @@
return static_cast<Tagged_t>(static_cast<uint32_t>(tagged));
}
-enum class OnHeapAddressKind {
- kAnyOnHeapAddress,
- kIsolateRoot,
-};
-
// Calculates isolate root value from any on-heap address.
-template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress>
-V8_INLINE Address GetRootFromOnHeapAddress(Address on_heap_addr) {
- if (kAddressKind == OnHeapAddressKind::kIsolateRoot) return on_heap_addr;
- return RoundDown(on_heap_addr + kPtrComprIsolateRootBias,
- kPtrComprIsolateRootAlignment);
+template <typename TOnHeapAddress>
+V8_INLINE Address GetIsolateRoot(TOnHeapAddress on_heap_addr);
+
+template <>
+V8_INLINE Address GetIsolateRoot<Address>(Address on_heap_addr) {
+ return RoundDown<kPtrComprIsolateRootAlignment>(on_heap_addr +
+ kPtrComprIsolateRootBias);
+}
+
+template <>
+V8_INLINE Address GetIsolateRoot<Isolate*>(Isolate* isolate) {
+ return isolate->isolate_root();
+}
+
+template <>
+V8_INLINE Address GetIsolateRoot<const Isolate*>(const Isolate* isolate) {
+ return isolate->isolate_root();
+}
+
+// Decompresses smi value.
+V8_INLINE Address DecompressTaggedSigned(Tagged_t raw_value) {
+ // Current compression scheme requires |raw_value| to be sign-extended
+ // from int32_t to intptr_t.
+ intptr_t value = static_cast<intptr_t>(static_cast<int32_t>(raw_value));
+ return static_cast<Address>(value);
}
// Decompresses weak or strong heap object pointer or forwarding pointer,
// preserving both weak- and smi- tags.
-template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress>
-V8_INLINE Address DecompressTaggedPointer(Address on_heap_addr,
+template <typename TOnHeapAddress>
+V8_INLINE Address DecompressTaggedPointer(TOnHeapAddress on_heap_addr,
Tagged_t raw_value) {
// Current compression scheme requires |raw_value| to be sign-extended
// from int32_t to intptr_t.
intptr_t value = static_cast<intptr_t>(static_cast<int32_t>(raw_value));
- Address root = GetRootFromOnHeapAddress<kAddressKind>(on_heap_addr);
+ Address root = GetIsolateRoot(on_heap_addr);
return root + static_cast<Address>(value);
}
// Decompresses any tagged value, preserving both weak- and smi- tags.
-template <OnHeapAddressKind kAddressKind = OnHeapAddressKind::kAnyOnHeapAddress>
-V8_INLINE Address DecompressTaggedAny(Address on_heap_addr,
+template <typename TOnHeapAddress>
+V8_INLINE Address DecompressTaggedAny(TOnHeapAddress on_heap_addr,
Tagged_t raw_value) {
// Current compression scheme requires |raw_value| to be sign-extended
// from int32_t to intptr_t.
@@ -54,14 +69,12 @@
if (kUseBranchlessPtrDecompression) {
// |root_mask| is 0 if the |value| was a smi or -1 otherwise.
Address root_mask = static_cast<Address>(-(value & kSmiTagMask));
- Address root_or_zero =
- root_mask & GetRootFromOnHeapAddress<kAddressKind>(on_heap_addr);
+ Address root_or_zero = root_mask & GetIsolateRoot(on_heap_addr);
return root_or_zero + static_cast<Address>(value);
} else {
return HAS_SMI_TAG(value)
? static_cast<Address>(value)
- : (GetRootFromOnHeapAddress<kAddressKind>(on_heap_addr) +
- static_cast<Address>(value));
+ : (GetIsolateRoot(on_heap_addr) + static_cast<Address>(value));
}
}
@@ -79,6 +92,20 @@
V8_INLINE Tagged_t CompressTagged(Address tagged) { UNREACHABLE(); }
+V8_INLINE Address DecompressTaggedSigned(Tagged_t raw_value) { UNREACHABLE(); }
+
+template <typename TOnHeapAddress>
+V8_INLINE Address DecompressTaggedPointer(TOnHeapAddress on_heap_addr,
+ Tagged_t raw_value) {
+ UNREACHABLE();
+}
+
+template <typename TOnHeapAddress>
+V8_INLINE Address DecompressTaggedAny(TOnHeapAddress on_heap_addr,
+ Tagged_t raw_value) {
+ UNREACHABLE();
+}
+
#endif // V8_TARGET_ARCH_64_BIT
} // namespace internal
} // namespace v8
diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h
index 0370ef9..07b4baf 100644
--- a/src/x64/assembler-x64-inl.h
+++ b/src/x64/assembler-x64-inl.h
@@ -326,11 +326,10 @@
HeapObject RelocInfo::target_object_no_host(Isolate* isolate) {
DCHECK(IsCodeTarget(rmode_) || IsEmbeddedObjectMode(rmode_));
if (IsCompressedEmbeddedObject(rmode_)) {
- Address root = isolate->isolate_root();
- Object o = static_cast<Object>(
- DecompressTaggedPointer<OnHeapAddressKind::kIsolateRoot>(
- root, ReadUnalignedValue<Tagged_t>(pc_)));
- return HeapObject::cast(o);
+ Tagged_t compressed = ReadUnalignedValue<Tagged_t>(pc_);
+ DCHECK(!HAS_SMI_TAG(compressed));
+ Object obj(DecompressTaggedPointer(isolate, compressed));
+ return HeapObject::cast(obj);
}
return HeapObject::cast(Object(ReadUnalignedValue<Address>(pc_)));
}
@@ -377,10 +376,9 @@
ICacheFlushMode icache_flush_mode) {
DCHECK(IsCodeTarget(rmode_) || IsEmbeddedObjectMode(rmode_));
if (IsCompressedEmbeddedObject(rmode_)) {
-#ifdef V8_COMPRESS_POINTERS
- Tagged_t tagged = CompressTagged(target->ptr());
+ DCHECK(COMPRESS_POINTERS_BOOL);
+ Tagged_t tagged = CompressTagged(target.ptr());
WriteUnalignedValue(pc_, tagged);
-#endif // V8_COMPRESS_POINTERS
} else {
WriteUnalignedValue(pc_, target.ptr());
}