1 // Copyright 2018 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_PROPERTY_ARRAY_INL_H_
6 #define V8_OBJECTS_PROPERTY_ARRAY_INL_H_
7
8 #include "src/objects/property-array.h"
9
10 #include "src/heap/heap-write-barrier-inl.h"
11 #include "src/objects/heap-object-inl.h"
12 #include "src/objects/objects-inl.h"
13 #include "src/objects/smi-inl.h"
14
15 // Has to be the last include (doesn't have include guards):
16 #include "src/objects/object-macros.h"
17
18 namespace v8 {
19 namespace internal {
20
21 #include "torque-generated/src/objects/property-array-tq-inl.inc"
22
23 TQ_OBJECT_CONSTRUCTORS_IMPL(PropertyArray)
24
SMI_ACCESSORS(PropertyArray,length_and_hash,kLengthAndHashOffset)25 SMI_ACCESSORS(PropertyArray, length_and_hash, kLengthAndHashOffset)
26 RELEASE_ACQUIRE_SMI_ACCESSORS(PropertyArray, length_and_hash,
27 kLengthAndHashOffset)
28
29 Object PropertyArray::get(int index) const {
30 PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
31 return get(cage_base, index);
32 }
33
get(PtrComprCageBase cage_base,int index)34 Object PropertyArray::get(PtrComprCageBase cage_base, int index) const {
35 DCHECK_LT(static_cast<unsigned>(index),
36 static_cast<unsigned>(this->length(kAcquireLoad)));
37 return TaggedField<Object>::Relaxed_Load(cage_base, *this,
38 OffsetOfElementAt(index));
39 }
40
get(int index,SeqCstAccessTag tag)41 Object PropertyArray::get(int index, SeqCstAccessTag tag) const {
42 PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
43 return get(cage_base, index, tag);
44 }
45
get(PtrComprCageBase cage_base,int index,SeqCstAccessTag tag)46 Object PropertyArray::get(PtrComprCageBase cage_base, int index,
47 SeqCstAccessTag tag) const {
48 DCHECK_LT(static_cast<unsigned>(index),
49 static_cast<unsigned>(this->length(kAcquireLoad)));
50 return TaggedField<Object>::SeqCst_Load(cage_base, *this,
51 OffsetOfElementAt(index));
52 }
53
set(int index,Object value)54 void PropertyArray::set(int index, Object value) {
55 DCHECK(IsPropertyArray());
56 DCHECK_LT(static_cast<unsigned>(index),
57 static_cast<unsigned>(this->length(kAcquireLoad)));
58 int offset = OffsetOfElementAt(index);
59 RELAXED_WRITE_FIELD(*this, offset, value);
60 WRITE_BARRIER(*this, offset, value);
61 }
62
set(int index,Object value,WriteBarrierMode mode)63 void PropertyArray::set(int index, Object value, WriteBarrierMode mode) {
64 DCHECK_LT(static_cast<unsigned>(index),
65 static_cast<unsigned>(this->length(kAcquireLoad)));
66 int offset = OffsetOfElementAt(index);
67 RELAXED_WRITE_FIELD(*this, offset, value);
68 CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
69 }
70
set(int index,Object value,SeqCstAccessTag tag)71 void PropertyArray::set(int index, Object value, SeqCstAccessTag tag) {
72 DCHECK(IsPropertyArray());
73 DCHECK_LT(static_cast<unsigned>(index),
74 static_cast<unsigned>(this->length(kAcquireLoad)));
75 DCHECK(value.IsShared());
76 int offset = OffsetOfElementAt(index);
77 SEQ_CST_WRITE_FIELD(*this, offset, value);
78 // JSSharedStructs are allocated in the shared old space, which is currently
79 // collected by stopping the world, so the incremental write barrier is not
80 // needed. They can only store Smis and other HeapObjects in the shared old
81 // space, so the generational write barrier is also not needed.
82 }
83
Swap(int index,Object value,SeqCstAccessTag tag)84 Object PropertyArray::Swap(int index, Object value, SeqCstAccessTag tag) {
85 PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
86 return Swap(cage_base, index, value, tag);
87 }
88
Swap(PtrComprCageBase cage_base,int index,Object value,SeqCstAccessTag tag)89 Object PropertyArray::Swap(PtrComprCageBase cage_base, int index, Object value,
90 SeqCstAccessTag tag) {
91 DCHECK(IsPropertyArray());
92 DCHECK_LT(static_cast<unsigned>(index),
93 static_cast<unsigned>(this->length(kAcquireLoad)));
94 DCHECK(value.IsShared());
95 return TaggedField<Object>::SeqCst_Swap(cage_base, *this,
96 OffsetOfElementAt(index), value);
97 // JSSharedStructs are allocated in the shared old space, which is currently
98 // collected by stopping the world, so the incremental write barrier is not
99 // needed. They can only store Smis and other HeapObjects in the shared old
100 // space, so the generational write barrier is also not needed.
101 }
102
data_start()103 ObjectSlot PropertyArray::data_start() { return RawField(kHeaderSize); }
104
length()105 int PropertyArray::length() const {
106 return LengthField::decode(length_and_hash());
107 }
108
initialize_length(int len)109 void PropertyArray::initialize_length(int len) {
110 DCHECK(LengthField::is_valid(len));
111 set_length_and_hash(len);
112 }
113
length(AcquireLoadTag)114 int PropertyArray::length(AcquireLoadTag) const {
115 return LengthField::decode(length_and_hash(kAcquireLoad));
116 }
117
Hash()118 int PropertyArray::Hash() const { return HashField::decode(length_and_hash()); }
119
SetHash(int hash)120 void PropertyArray::SetHash(int hash) {
121 int value = length_and_hash();
122 value = HashField::update(value, hash);
123 set_length_and_hash(value, kReleaseStore);
124 }
125
CopyElements(Isolate * isolate,int dst_index,PropertyArray src,int src_index,int len,WriteBarrierMode mode)126 void PropertyArray::CopyElements(Isolate* isolate, int dst_index,
127 PropertyArray src, int src_index, int len,
128 WriteBarrierMode mode) {
129 if (len == 0) return;
130 DisallowGarbageCollection no_gc;
131
132 ObjectSlot dst_slot(data_start() + dst_index);
133 ObjectSlot src_slot(src.data_start() + src_index);
134 isolate->heap()->CopyRange(*this, dst_slot, src_slot, len, mode);
135 }
136
137 } // namespace internal
138 } // namespace v8
139
140 #include "src/objects/object-macros-undef.h"
141
142 #endif // V8_OBJECTS_PROPERTY_ARRAY_INL_H_
143