1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "ecmascript/runtime.h"
16
17 namespace panda::ecmascript {
UpdateWithoutEden(const JSThread * thread,uintptr_t slotAddr,Region * objectRegion,TaggedObject * value,Region * valueRegion,WriteBarrierType writeType)18 void Barriers::UpdateWithoutEden(const JSThread *thread, uintptr_t slotAddr, Region *objectRegion, TaggedObject *value,
19 Region *valueRegion, WriteBarrierType writeType)
20 {
21 ASSERT(!valueRegion->InSharedHeap());
22 auto heap = thread->GetEcmaVM()->GetHeap();
23 if (heap->IsConcurrentFullMark()) {
24 if (valueRegion->InCollectSet() && !objectRegion->InGeneralNewSpaceOrCSet()) {
25 objectRegion->AtomicInsertCrossRegionRSet(slotAddr);
26 }
27 } else {
28 if (!valueRegion->InYoungSpace()) {
29 return;
30 }
31 }
32
33 // Weak ref record and concurrent mark record maybe conflict.
34 // This conflict is solved by keeping alive weak reference. A small amount of floating garbage may be added.
35 TaggedObject *heapValue = JSTaggedValue(value).GetHeapObject();
36 if (valueRegion->IsFreshRegion()) {
37 valueRegion->NonAtomicMark(heapValue);
38 } else if (writeType != WriteBarrierType::DESERIALIZE && valueRegion->AtomicMark(heapValue)) {
39 heap->GetWorkManager()->Push(MAIN_THREAD_INDEX, heapValue);
40 }
41 }
42
Update(const JSThread * thread,uintptr_t slotAddr,Region * objectRegion,TaggedObject * value,Region * valueRegion,WriteBarrierType writeType)43 void Barriers::Update(const JSThread *thread, uintptr_t slotAddr, Region *objectRegion, TaggedObject *value,
44 Region *valueRegion, WriteBarrierType writeType)
45 {
46 if (valueRegion->InSharedHeap()) {
47 return;
48 }
49 auto heap = thread->GetEcmaVM()->GetHeap();
50 if (heap->IsConcurrentFullMark()) {
51 if (valueRegion->InCollectSet() && !objectRegion->InGeneralNewSpaceOrCSet()) {
52 objectRegion->AtomicInsertCrossRegionRSet(slotAddr);
53 }
54 } else if (heap->IsYoungMark()) {
55 if (!valueRegion->InGeneralNewSpace()) {
56 return;
57 }
58 } else {
59 if (!valueRegion->InEdenSpace()) {
60 return;
61 }
62 }
63
64 // Weak ref record and concurrent mark record maybe conflict.
65 // This conflict is solved by keeping alive weak reference. A small amount of floating garbage may be added.
66 TaggedObject *heapValue = JSTaggedValue(value).GetHeapObject();
67 if (valueRegion->IsFreshRegion()) {
68 valueRegion->NonAtomicMark(heapValue);
69 } else if (writeType != WriteBarrierType::DESERIALIZE && valueRegion->AtomicMark(heapValue)) {
70 heap->GetWorkManager()->Push(MAIN_THREAD_INDEX, heapValue);
71 }
72 }
73
UpdateShared(const JSThread * thread,TaggedObject * value,Region * valueRegion)74 void Barriers::UpdateShared(const JSThread *thread, TaggedObject *value, Region *valueRegion)
75 {
76 ASSERT(DaemonThread::GetInstance()->IsConcurrentMarkingOrFinished());
77 ASSERT(valueRegion->InSharedSweepableSpace());
78
79 // Weak ref record and concurrent mark record maybe conflict.
80 // This conflict is solved by keeping alive weak reference. A small amount of floating garbage may be added.
81 TaggedObject *heapValue = JSTaggedValue(value).GetHeapObject();
82 if (valueRegion->AtomicMark(heapValue)) {
83 Heap *heap = const_cast<Heap*>(thread->GetEcmaVM()->GetHeap());
84 WorkNode *&localBuffer = heap->GetMarkingObjectLocalBuffer();
85 SharedHeap::GetInstance()->GetWorkManager()->PushToLocalMarkingBuffer(localBuffer, heapValue);
86 }
87 }
88 } // namespace panda::ecmascript
89