Skip to content

Commit bc8106d

Browse files
isheludkoCommit Bot
authored andcommitted
[ptr-compr][cleanup] Introduce TaggedField<T, kOffset> template
It will allow us to use knowledge about the type of field during value decompression upon field read. Use the new class for HeapObject::MapField. Bug: v8:9353 Change-Id: I1368426ec2e25fcec3af8d5cccd7a78d80423e72 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1658150 Commit-Queue: Igor Sheludko <ishell@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#62184}
1 parent 490c419 commit bc8106d

11 files changed

Lines changed: 262 additions & 35 deletions

File tree

BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,8 @@ v8_source_set("v8_base_without_compiler") {
26012601
"src/objects/string.h",
26022602
"src/objects/struct-inl.h",
26032603
"src/objects/struct.h",
2604+
"src/objects/tagged-field-inl.h",
2605+
"src/objects/tagged-field.h",
26042606
"src/objects/tagged-impl-inl.h",
26052607
"src/objects/tagged-impl.cc",
26062608
"src/objects/tagged-impl.h",

src/common/ptr-compr-inl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ V8_INLINE Address GetIsolateRoot(TOnHeapAddress on_heap_addr);
2525

2626
template <>
2727
V8_INLINE Address GetIsolateRoot<Address>(Address on_heap_addr) {
28+
// We subtract 1 here in order to let the compiler generate addition of 32-bit
29+
// signed constant instead of 64-bit constant (the problem is that 2Gb looks
30+
// like a negative 32-bit value). It's correct because we will never use
31+
// leftmost address of V8 heap as |on_heap_addr|.
2832
return RoundDown<kPtrComprIsolateRootAlignment>(on_heap_addr +
29-
kPtrComprIsolateRootBias);
33+
kPtrComprIsolateRootBias - 1);
3034
}
3135

3236
template <>

src/heap/mark-compact.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,8 +1366,7 @@ class EvacuateNewSpaceVisitor final : public EvacuateVisitorBase {
13661366
if (map.visitor_id() == kVisitThinString) {
13671367
HeapObject actual = ThinString::cast(object).unchecked_actual();
13681368
if (MarkCompactCollector::IsOnEvacuationCandidate(actual)) return false;
1369-
object.map_slot().Relaxed_Store(
1370-
MapWord::FromForwardingAddress(actual).ToMap());
1369+
object.set_map_word(MapWord::FromForwardingAddress(actual));
13711370
return true;
13721371
}
13731372
// TODO(mlippautz): Handle ConsString.

src/heap/scavenger-inl.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,8 @@ bool Scavenger::MigrateObject(Map map, HeapObject source, HeapObject target,
109109
heap()->CopyBlock(target.address() + kTaggedSize,
110110
source.address() + kTaggedSize, size - kTaggedSize);
111111

112-
Object old = source.map_slot().Release_CompareAndSwap(
113-
map, MapWord::FromForwardingAddress(target).ToMap());
114-
if (old != map) {
112+
if (!source.synchronized_compare_and_swap_map_word(
113+
MapWord::FromMap(map), MapWord::FromForwardingAddress(target))) {
115114
// Other task migrated the object.
116115
return false;
117116
}
@@ -215,8 +214,8 @@ bool Scavenger::HandleLargeObject(Map map, HeapObject object, int object_size,
215214
MemoryChunk::FromHeapObject(object)->InNewLargeObjectSpace())) {
216215
DCHECK_EQ(NEW_LO_SPACE,
217216
MemoryChunk::FromHeapObject(object)->owner_identity());
218-
if (object.map_slot().Release_CompareAndSwap(
219-
map, MapWord::FromForwardingAddress(object).ToMap()) == map) {
217+
if (object.synchronized_compare_and_swap_map_word(
218+
MapWord::FromMap(map), MapWord::FromForwardingAddress(object))) {
220219
surviving_new_large_objects_.insert({object, map});
221220
promoted_size_ += object_size;
222221
if (object_fields == ObjectFields::kMaybePointers) {
@@ -313,8 +312,7 @@ SlotCallbackResult Scavenger::EvacuateShortcutCandidate(Map map,
313312
HeapObjectReference::Update(slot, first);
314313

315314
if (!Heap::InYoungGeneration(first)) {
316-
object.map_slot().Release_Store(
317-
MapWord::FromForwardingAddress(first).ToMap());
315+
object.synchronized_set_map_word(MapWord::FromForwardingAddress(first));
318316
return REMOVE_SLOT;
319317
}
320318

@@ -323,16 +321,15 @@ SlotCallbackResult Scavenger::EvacuateShortcutCandidate(Map map,
323321
HeapObject target = first_word.ToForwardingAddress();
324322

325323
HeapObjectReference::Update(slot, target);
326-
object.map_slot().Release_Store(
327-
MapWord::FromForwardingAddress(target).ToMap());
324+
object.synchronized_set_map_word(MapWord::FromForwardingAddress(target));
328325
return Heap::InYoungGeneration(target) ? KEEP_SLOT : REMOVE_SLOT;
329326
}
330327
Map map = first_word.ToMap();
331328
SlotCallbackResult result =
332329
EvacuateObjectDefault(map, slot, first, first.SizeFromMap(map),
333330
Map::ObjectFieldsFrom(map.visitor_id()));
334-
object.map_slot().Release_Store(
335-
MapWord::FromForwardingAddress(slot.ToHeapObject()).ToMap());
331+
object.synchronized_set_map_word(
332+
MapWord::FromForwardingAddress(slot.ToHeapObject()));
336333
return result;
337334
}
338335
DCHECK_EQ(ObjectFields::kMaybePointers,

src/objects/heap-object.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "src/roots/roots.h"
1010

1111
#include "src/objects/objects.h"
12+
#include "src/objects/tagged-field.h"
1213

1314
// Has to be the last include (doesn't have include guards):
1415
#include "src/objects/object-macros.h"
@@ -45,6 +46,10 @@ class HeapObject : public Object {
4546
// Set the map using release store
4647
inline void synchronized_set_map(Map value);
4748
inline void synchronized_set_map_word(MapWord map_word);
49+
// Compare-and-swaps map word using release store, returns true if the map
50+
// word was actually swapped.
51+
inline bool synchronized_compare_and_swap_map_word(MapWord old_map_word,
52+
MapWord new_map_word);
4853

4954
// Initialize the map immediately after the object is allocated.
5055
// Do not use this outside Heap.
@@ -191,6 +196,8 @@ class HeapObject : public Object {
191196

192197
STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset);
193198

199+
using MapField = TaggedField<MapWord, HeapObject::kMapOffset>;
200+
194201
inline Address GetFieldAddress(int field_offset) const;
195202

196203
protected:

src/objects/maybe-object.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class MaybeObject : public TaggedImpl<HeapObjectReferenceType::WEAK, Address> {
3030
#ifdef VERIFY_HEAP
3131
static void VerifyMaybeObjectPointer(Isolate* isolate, MaybeObject p);
3232
#endif
33+
34+
private:
35+
template <typename TFieldType, int kFieldOffset>
36+
friend class TaggedField;
3337
};
3438

3539
// A HeapObjectReference is either a strong reference to a HeapObject, a weak

src/objects/object-macros.h

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818

1919
// Since this changes visibility, it should always be last in a class
2020
// definition.
21-
#define OBJECT_CONSTRUCTORS(Type, ...) \
22-
public: \
23-
constexpr Type() : __VA_ARGS__() {} \
24-
\
25-
protected: \
21+
#define OBJECT_CONSTRUCTORS(Type, ...) \
22+
public: \
23+
constexpr Type() : __VA_ARGS__() {} \
24+
\
25+
protected: \
26+
template <typename TFieldType, int kFieldOffset> \
27+
friend class TaggedField; \
28+
\
2629
explicit inline Type(Address ptr)
2730

2831
#define OBJECT_CONSTRUCTORS_IMPL(Type, Super) \
@@ -412,12 +415,15 @@
412415
set(IndexForEntry(i) + k##name##Offset, value); \
413416
}
414417

415-
#define TQ_OBJECT_CONSTRUCTORS(Type) \
416-
public: \
417-
constexpr Type() = default; \
418-
\
419-
protected: \
420-
inline explicit Type(Address ptr); \
418+
#define TQ_OBJECT_CONSTRUCTORS(Type) \
419+
public: \
420+
constexpr Type() = default; \
421+
\
422+
protected: \
423+
template <typename TFieldType, int kFieldOffset> \
424+
friend class TaggedField; \
425+
\
426+
inline explicit Type(Address ptr); \
421427
friend class TorqueGenerated##Type<Type, Super>;
422428

423429
#define TQ_OBJECT_CONSTRUCTORS_IMPL(Type) \

src/objects/objects-inl.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "src/objects/shared-function-info.h"
3939
#include "src/objects/slots-inl.h"
4040
#include "src/objects/smi-inl.h"
41+
#include "src/objects/tagged-field-inl.h"
4142
#include "src/objects/tagged-impl-inl.h"
4243
#include "src/objects/templates.h"
4344
#include "src/sanitizer/tsan.h"
@@ -709,23 +710,28 @@ void HeapObject::set_map_after_allocation(Map value, WriteBarrierMode mode) {
709710
}
710711

711712
MapWordSlot HeapObject::map_slot() const {
712-
return MapWordSlot(FIELD_ADDR(*this, kMapOffset));
713+
return MapWordSlot(MapField::address(*this));
713714
}
714715

715-
MapWord HeapObject::map_word() const {
716-
return MapWord(map_slot().Relaxed_Load().ptr());
717-
}
716+
MapWord HeapObject::map_word() const { return MapField::Relaxed_Load(*this); }
718717

719718
void HeapObject::set_map_word(MapWord map_word) {
720-
map_slot().Relaxed_Store(Object(map_word.value_));
719+
MapField::Relaxed_Store(*this, map_word);
721720
}
722721

723722
MapWord HeapObject::synchronized_map_word() const {
724-
return MapWord(map_slot().Acquire_Load().ptr());
723+
return MapField::Acquire_Load(*this);
725724
}
726725

727726
void HeapObject::synchronized_set_map_word(MapWord map_word) {
728-
map_slot().Release_Store(Object(map_word.value_));
727+
MapField::Release_Store(*this, map_word);
728+
}
729+
730+
bool HeapObject::synchronized_compare_and_swap_map_word(MapWord old_map_word,
731+
MapWord new_map_word) {
732+
Tagged_t result =
733+
MapField::Release_CompareAndSwap(*this, old_map_word, new_map_word);
734+
return result == static_cast<Tagged_t>(old_map_word.ptr());
729735
}
730736

731737
int HeapObject::Size() const { return SizeFromMap(map()); }

src/objects/objects.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -743,13 +743,13 @@ class MapWord {
743743
// View this map word as a forwarding address.
744744
inline HeapObject ToForwardingAddress();
745745

746-
static inline MapWord FromRawValue(uintptr_t value) { return MapWord(value); }
747-
748-
inline uintptr_t ToRawValue() { return value_; }
746+
inline Address ptr() { return value_; }
749747

750748
private:
751749
// HeapObject calls the private constructor and directly reads the value.
752750
friend class HeapObject;
751+
template <typename TFieldType, int kFieldOffset>
752+
friend class TaggedField;
753753

754754
explicit MapWord(Address value) : value_(value) {}
755755

src/objects/tagged-field-inl.h

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright 2019 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef V8_OBJECTS_TAGGED_FIELD_INL_H_
6+
#define V8_OBJECTS_TAGGED_FIELD_INL_H_
7+
8+
#include "src/objects/tagged-field.h"
9+
10+
#include "src/common/ptr-compr-inl.h"
11+
12+
namespace v8 {
13+
namespace internal {
14+
15+
// static
16+
template <typename T, int kFieldOffset>
17+
Address TaggedField<T, kFieldOffset>::address(HeapObject host) {
18+
return host.address() + kFieldOffset;
19+
}
20+
21+
// static
22+
template <typename T, int kFieldOffset>
23+
Tagged_t* TaggedField<T, kFieldOffset>::location(HeapObject host) {
24+
return reinterpret_cast<Tagged_t*>(address(host));
25+
}
26+
27+
// static
28+
template <typename T, int kFieldOffset>
29+
template <typename TOnHeapAddress>
30+
Address TaggedField<T, kFieldOffset>::tagged_to_full(
31+
TOnHeapAddress on_heap_addr, Tagged_t tagged_value) {
32+
#ifdef V8_COMPRESS_POINTERS
33+
if (kIsSmi) {
34+
return DecompressTaggedSigned(tagged_value);
35+
} else if (kIsHeapObject) {
36+
return DecompressTaggedPointer(on_heap_addr, tagged_value);
37+
} else {
38+
return DecompressTaggedAny(on_heap_addr, tagged_value);
39+
}
40+
#else
41+
return tagged_value;
42+
#endif
43+
}
44+
45+
// static
46+
template <typename T, int kFieldOffset>
47+
Tagged_t TaggedField<T, kFieldOffset>::full_to_tagged(Address value) {
48+
#ifdef V8_COMPRESS_POINTERS
49+
return CompressTagged(value);
50+
#else
51+
return value;
52+
#endif
53+
}
54+
55+
// static
56+
template <typename T, int kFieldOffset>
57+
T TaggedField<T, kFieldOffset>::load(HeapObject host) {
58+
Tagged_t value = *location(host);
59+
return T(tagged_to_full(host.ptr(), value));
60+
}
61+
62+
// static
63+
template <typename T, int kFieldOffset>
64+
T TaggedField<T, kFieldOffset>::load(Isolate* isolate, HeapObject host) {
65+
Tagged_t value = *location(host);
66+
return T(tagged_to_full(isolate, value));
67+
}
68+
69+
// static
70+
template <typename T, int kFieldOffset>
71+
void TaggedField<T, kFieldOffset>::store(HeapObject host, T value) {
72+
*location(host) = full_to_tagged(value.ptr());
73+
}
74+
75+
// static
76+
template <typename T, int kFieldOffset>
77+
T TaggedField<T, kFieldOffset>::Relaxed_Load(HeapObject host) {
78+
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host));
79+
return T(tagged_to_full(host.ptr(), value));
80+
}
81+
82+
// static
83+
template <typename T, int kFieldOffset>
84+
T TaggedField<T, kFieldOffset>::Relaxed_Load(Isolate* isolate,
85+
HeapObject host) {
86+
AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host));
87+
return T(tagged_to_full(isolate, value));
88+
}
89+
90+
// static
91+
template <typename T, int kFieldOffset>
92+
void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, T value) {
93+
AsAtomicTagged::Relaxed_Store(location(host), full_to_tagged(value.ptr()));
94+
}
95+
96+
// static
97+
template <typename T, int kFieldOffset>
98+
T TaggedField<T, kFieldOffset>::Acquire_Load(HeapObject host) {
99+
AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host));
100+
return T(tagged_to_full(host.ptr(), value));
101+
}
102+
103+
// static
104+
template <typename T, int kFieldOffset>
105+
T TaggedField<T, kFieldOffset>::Acquire_Load(Isolate* isolate,
106+
HeapObject host) {
107+
AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host));
108+
return T(tagged_to_full(isolate, value));
109+
}
110+
111+
// static
112+
template <typename T, int kFieldOffset>
113+
void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, T value) {
114+
AsAtomicTagged::Release_Store(location(host), full_to_tagged(value.ptr()));
115+
}
116+
117+
// static
118+
template <typename T, int kFieldOffset>
119+
Tagged_t TaggedField<T, kFieldOffset>::Release_CompareAndSwap(HeapObject host,
120+
T old, T value) {
121+
Tagged_t old_value = full_to_tagged(old.ptr());
122+
Tagged_t new_value = full_to_tagged(value.ptr());
123+
Tagged_t result = AsAtomicTagged::Release_CompareAndSwap(
124+
location(host), old_value, new_value);
125+
return result;
126+
}
127+
128+
} // namespace internal
129+
} // namespace v8
130+
131+
#endif // V8_OBJECTS_TAGGED_FIELD_INL_H_

0 commit comments

Comments
 (0)