tagged-field-inl.h 5.04 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// 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_FIELD_INL_H_
#define V8_OBJECTS_TAGGED_FIELD_INL_H_

#include "src/objects/tagged-field.h"

#include "src/common/ptr-compr-inl.h"

namespace v8 {
namespace internal {

// static
template <typename T, int kFieldOffset>
17 18
Address TaggedField<T, kFieldOffset>::address(HeapObject host, int offset) {
  return host.address() + kFieldOffset + offset;
19 20 21 22
}

// static
template <typename T, int kFieldOffset>
23 24
Tagged_t* TaggedField<T, kFieldOffset>::location(HeapObject host, int offset) {
  return reinterpret_cast<Tagged_t*>(address(host, offset));
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
}

// static
template <typename T, int kFieldOffset>
template <typename TOnHeapAddress>
Address TaggedField<T, kFieldOffset>::tagged_to_full(
    TOnHeapAddress on_heap_addr, Tagged_t tagged_value) {
#ifdef V8_COMPRESS_POINTERS
  if (kIsSmi) {
    return DecompressTaggedSigned(tagged_value);
  } else if (kIsHeapObject) {
    return DecompressTaggedPointer(on_heap_addr, tagged_value);
  } else {
    return DecompressTaggedAny(on_heap_addr, tagged_value);
  }
#else
  return tagged_value;
#endif
}

// static
template <typename T, int kFieldOffset>
Tagged_t TaggedField<T, kFieldOffset>::full_to_tagged(Address value) {
#ifdef V8_COMPRESS_POINTERS
  return CompressTagged(value);
#else
  return value;
#endif
}

// static
template <typename T, int kFieldOffset>
57 58
T TaggedField<T, kFieldOffset>::load(HeapObject host, int offset) {
  Tagged_t value = *location(host, offset);
59 60 61 62 63
  return T(tagged_to_full(host.ptr(), value));
}

// static
template <typename T, int kFieldOffset>
64
T TaggedField<T, kFieldOffset>::load(IsolateRoot isolate, HeapObject host,
65 66
                                     int offset) {
  Tagged_t value = *location(host, offset);
67 68 69 70 71 72
  return T(tagged_to_full(isolate, value));
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::store(HeapObject host, T value) {
73
#ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
74 75
  Relaxed_Store(host, value);
#else
76
  *location(host) = full_to_tagged(value.ptr());
77
#endif
78 79
}

80 81 82
// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::store(HeapObject host, int offset, T value) {
83
#ifdef V8_ATOMIC_OBJECT_FIELD_WRITES
84 85
  Relaxed_Store(host, offset, value);
#else
86
  *location(host, offset) = full_to_tagged(value.ptr());
87
#endif
88 89
}

90 91 92 93 94 95 96
// static
template <typename T, int kFieldOffset>
T TaggedField<T, kFieldOffset>::Relaxed_Load(HeapObject host, int offset) {
  AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
  return T(tagged_to_full(host.ptr(), value));
}

97 98
// static
template <typename T, int kFieldOffset>
99
T TaggedField<T, kFieldOffset>::Relaxed_Load(IsolateRoot isolate,
100
                                             HeapObject host, int offset) {
101 102 103 104
  AtomicTagged_t value = AsAtomicTagged::Relaxed_Load(location(host, offset));
  return T(tagged_to_full(isolate, value));
}

105 106 107 108 109 110
// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, T value) {
  AsAtomicTagged::Relaxed_Store(location(host), full_to_tagged(value.ptr()));
}

111 112 113 114 115 116 117 118
// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Relaxed_Store(HeapObject host, int offset,
                                                 T value) {
  AsAtomicTagged::Relaxed_Store(location(host, offset),
                                full_to_tagged(value.ptr()));
}

119 120
// static
template <typename T, int kFieldOffset>
121 122
T TaggedField<T, kFieldOffset>::Acquire_Load(HeapObject host, int offset) {
  AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
123 124 125 126 127
  return T(tagged_to_full(host.ptr(), value));
}

// static
template <typename T, int kFieldOffset>
128
T TaggedField<T, kFieldOffset>::Acquire_Load(IsolateRoot isolate,
129
                                             HeapObject host, int offset) {
130
  AtomicTagged_t value = AsAtomicTagged::Acquire_Load(location(host, offset));
131 132 133 134 135 136 137 138 139
  return T(tagged_to_full(isolate, value));
}

// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, T value) {
  AsAtomicTagged::Release_Store(location(host), full_to_tagged(value.ptr()));
}

140 141 142 143 144 145 146 147
// static
template <typename T, int kFieldOffset>
void TaggedField<T, kFieldOffset>::Release_Store(HeapObject host, int offset,
                                                 T value) {
  AsAtomicTagged::Release_Store(location(host, offset),
                                full_to_tagged(value.ptr()));
}

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
// static
template <typename T, int kFieldOffset>
Tagged_t TaggedField<T, kFieldOffset>::Release_CompareAndSwap(HeapObject host,
                                                              T old, T value) {
  Tagged_t old_value = full_to_tagged(old.ptr());
  Tagged_t new_value = full_to_tagged(value.ptr());
  Tagged_t result = AsAtomicTagged::Release_CompareAndSwap(
      location(host), old_value, new_value);
  return result;
}

}  // namespace internal
}  // namespace v8

#endif  // V8_OBJECTS_TAGGED_FIELD_INL_H_