Commit 808a3f23 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ptr-compr] Introduce TaggedIndex class

... a Smi-looking type containing properly sign-extended int31 integer.

The idea is to use this kind of tagged integers for the cases where
the value is guaranteed to fit into int31. For example, feedback vector
slots is one of the candidates for using TaggedIndex representation.

Bug: v8:10047
Change-Id: Ifaa2978a5d42467578ff243dc44d327536efbe93
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1960292Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66170}
parent 2877a2ad
......@@ -2689,6 +2689,7 @@ v8_source_set("v8_base_without_compiler") {
"src/objects/tagged-impl-inl.h",
"src/objects/tagged-impl.cc",
"src/objects/tagged-impl.h",
"src/objects/tagged-index.h",
"src/objects/tagged-value-inl.h",
"src/objects/tagged-value.h",
"src/objects/template-objects-inl.h",
......
......@@ -1625,6 +1625,7 @@ Address CheckObjectType(Address raw_value, Address raw_type,
TYPE_CASE(Object)
TYPE_CASE(Smi)
TYPE_CASE(TaggedIndex)
TYPE_CASE(HeapObject)
OBJECT_TYPE_LIST(TYPE_CASE)
HEAP_OBJECT_TYPE_LIST(TYPE_CASE)
......
......@@ -86,6 +86,7 @@ class Signature;
enum class ObjectType {
ENUM_ELEMENT(Object) //
ENUM_ELEMENT(Smi) //
ENUM_ELEMENT(TaggedIndex) //
ENUM_ELEMENT(HeapObject) //
OBJECT_TYPE_LIST(ENUM_ELEMENT) //
HEAP_OBJECT_TYPE_LIST(ENUM_ELEMENT) //
......
......@@ -138,6 +138,10 @@ void Smi::SmiVerify(Isolate* isolate) {
CHECK(!IsConstructor());
}
void TaggedIndex::TaggedIndexVerify(Isolate* isolate) {
CHECK(IsTaggedIndex());
}
void HeapObject::HeapObjectVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::HeapObjectVerify(*this, isolate);
......
......@@ -40,6 +40,7 @@
#include "src/objects/smi-inl.h"
#include "src/objects/tagged-field-inl.h"
#include "src/objects/tagged-impl-inl.h"
#include "src/objects/tagged-index.h"
#include "src/objects/templates.h"
#include "src/sanitizer/tsan.h"
#include "torque-generated/class-definitions-tq-inl.h"
......@@ -74,6 +75,10 @@ DEF_GETTER(HeapObject, IsClassBoilerplate, bool) {
return IsFixedArrayExact(isolate);
}
bool Object::IsTaggedIndex() const {
return IsSmi() && TaggedIndex::IsValid(TaggedIndex(ptr()).value());
}
#define IS_TYPE_FUNCTION_DEF(type_) \
bool Object::Is##type_() const { \
return IsHeapObject() && HeapObject::cast(*this).Is##type_(); \
......
......@@ -38,6 +38,7 @@
// Inheritance hierarchy:
// - Object
// - Smi (immediate small integer)
// - TaggedIndex (properly sign-extended immediate small integer)
// - HeapObject (superclass for everything allocated in the heap)
// - JSReceiver (suitable for property access)
// - JSObject
......@@ -275,6 +276,8 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> {
constexpr Object() : TaggedImpl(kNullAddress) {}
explicit constexpr Object(Address ptr) : TaggedImpl(ptr) {}
V8_INLINE bool IsTaggedIndex() const;
#define IS_TYPE_FUNCTION_DECL(Type) \
V8_INLINE bool Is##Type() const; \
V8_INLINE bool Is##Type(const Isolate* isolate) const;
......
// Copyright 2020 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_INDEX_H_
#define V8_OBJECTS_TAGGED_INDEX_H_
#include "src/common/globals.h"
#include "src/objects/heap-object.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
// TaggedIndex represents integer values that can be stored in 31 bits.
// The on 32-bit architectures ptr_ value has the following format:
// [31 bit signed int] 0
// The on 64-bit architectures ptr_ value has the following format:
// [32 bits of sign-extended lower part][31 bit signed int] 0
// Thus, on 32-bit architectures TaggedIndex is exactly the same as Smi but
// on 64-bit architectures TaggedIndex differs from Smi in the following
// aspects:
// 1) TaggedIndex payload is always 31 bit independent of the Smi payload size
// 2) TaggedIndex is always properly sign-extended independent of whether
// pointer compression is enabled or not. In the former case, upper 32 bits
// of a Smi value may contain 0 or sign or isolate root value.
//
// Given the above constraints TaggedIndex has the following properties:
// 1) it still looks like a Smi from GC point of view and therefore it's safe
// to pass TaggedIndex values to runtime functions or builtins on the stack
// 2) since the TaggedIndex values are already properly sign-extended it's
// safe to use them as indices in offset-computation functions.
class TaggedIndex : public Object {
public:
// This replaces the OBJECT_CONSTRUCTORS macro, because TaggedIndex are
// special in that we want them to be constexprs.
constexpr TaggedIndex() : Object() {}
explicit constexpr TaggedIndex(Address ptr) : Object(ptr) {
#if V8_HAS_CXX14_CONSTEXPR
DCHECK(HAS_SMI_TAG(ptr));
#endif
}
// Returns the integer value.
inline intptr_t value() const {
// Truncate and shift down (requires >> to be sign extending).
return static_cast<intptr_t>(ptr()) >> kSmiTagSize;
}
// Convert a value to a TaggedIndex object.
static inline TaggedIndex FromIntptr(intptr_t value) {
#if V8_HAS_CXX14_CONSTEXPR
DCHECK(TaggedIndex::IsValid(value));
#endif
return TaggedIndex((static_cast<Address>(value) << kSmiTagSize) | kSmiTag);
}
// Returns whether value can be represented in a TaggedIndex.
static inline bool constexpr IsValid(intptr_t value) {
// Is value in range [kMinValue, kMaxValue].
// Use unsigned operations in order to avoid undefined behaviour in case of
// signed integer overflow.
return (static_cast<uintptr_t>(value) -
static_cast<uintptr_t>(kMinValue)) <=
(static_cast<uintptr_t>(kMaxValue) -
static_cast<uintptr_t>(kMinValue));
}
DECL_CAST(TaggedIndex)
// Dispatched behavior.
DECL_VERIFIER(TaggedIndex)
STATIC_ASSERT(kSmiTagSize == 1);
static constexpr int kTaggedValueSize = 31;
static constexpr intptr_t kMinValue =
static_cast<intptr_t>(kUintptrAllBitsSet << (kTaggedValueSize - 1));
static constexpr intptr_t kMaxValue = -(kMinValue + 1);
};
CAST_ACCESSOR(TaggedIndex)
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_TAGGED_INDEX_H_
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