1 /**
2 * Copyright (c) 2021-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 "global_object_storage.h"
16
17 #include <libpandabase/os/mutex.h>
18 #include "runtime/include/runtime.h"
19 #include "runtime/include/mem/panda_containers.h"
20 #include "runtime/include/object_header.h"
21 #include "runtime/mem/object_helpers.h"
22 #include "runtime/mem/gc/gc.h"
23 #include "runtime/mem/gc/gc_root.h"
24 #include "runtime/mem/gc/gc_phase.h"
25 #include "runtime/include/class.h"
26 #include "reference.h"
27 #include "utils/logger.h"
28
29 namespace panda::mem {
30
GlobalObjectStorage(mem::InternalAllocatorPtr allocator,size_t max_size,bool enable_size_check)31 GlobalObjectStorage::GlobalObjectStorage(mem::InternalAllocatorPtr allocator, size_t max_size, bool enable_size_check)
32 : allocator_(allocator)
33 {
34 global_storage_ = allocator->New<ArrayStorage>(allocator, max_size, enable_size_check);
35 weak_storage_ = allocator->New<ArrayStorage>(allocator, max_size, enable_size_check);
36 }
37
~GlobalObjectStorage()38 GlobalObjectStorage::~GlobalObjectStorage()
39 {
40 allocator_->Delete(global_storage_);
41 allocator_->Delete(weak_storage_);
42 }
43
IsValidGlobalRef(const Reference * ref) const44 bool GlobalObjectStorage::IsValidGlobalRef(const Reference *ref) const
45 {
46 ASSERT(ref != nullptr);
47 Reference::ObjectType type = Reference::GetType(ref);
48 AssertType(type);
49 if (type == Reference::ObjectType::GLOBAL) {
50 if (!global_storage_->IsValidGlobalRef(ref)) {
51 return false;
52 }
53 } else {
54 if (!weak_storage_->IsValidGlobalRef(ref)) {
55 return false;
56 }
57 }
58 return true;
59 }
60
Add(const ObjectHeader * object,Reference::ObjectType type) const61 Reference *GlobalObjectStorage::Add(const ObjectHeader *object, Reference::ObjectType type) const
62 {
63 AssertType(type);
64 if (object == nullptr) {
65 return nullptr;
66 }
67 Reference *ref = nullptr;
68 if (type == Reference::ObjectType::GLOBAL) {
69 ref = global_storage_->Add(object);
70 } else {
71 ref = weak_storage_->Add(object);
72 }
73 if (ref != nullptr) {
74 ref = Reference::SetType(ref, type);
75 }
76 return ref;
77 }
78
Get(const Reference * reference) const79 ObjectHeader *GlobalObjectStorage::Get(const Reference *reference) const
80 {
81 if (reference == nullptr) {
82 return nullptr;
83 }
84 auto type = reference->GetType();
85 reference = Reference::GetRefWithoutType(reference);
86 AssertType(type);
87 ObjectHeader *result = nullptr;
88 if (type == Reference::ObjectType::GLOBAL) {
89 result = global_storage_->Get(reference);
90 } else {
91 result = weak_storage_->Get(reference);
92 }
93 return result;
94 }
95
Remove(const Reference * reference)96 void GlobalObjectStorage::Remove(const Reference *reference)
97 {
98 if (reference == nullptr) {
99 return;
100 }
101 auto type = reference->GetType();
102 AssertType(type);
103 reference = Reference::GetRefWithoutType(reference);
104 if (type == Reference::ObjectType::GLOBAL) {
105 global_storage_->Remove(reference);
106 } else {
107 weak_storage_->Remove(reference);
108 }
109 }
110
GetAllObjects()111 PandaVector<ObjectHeader *> GlobalObjectStorage::GetAllObjects()
112 {
113 auto objects = PandaVector<ObjectHeader *>(allocator_->Adapter());
114
115 auto global_objects = global_storage_->GetAllObjects();
116 objects.insert(objects.end(), global_objects.begin(), global_objects.end());
117
118 auto weak_objects = weak_storage_->GetAllObjects();
119 objects.insert(objects.end(), weak_objects.begin(), weak_objects.end());
120
121 return objects;
122 }
123
VisitObjects(const GCRootVisitor & gc_root_visitor,mem::RootType rootType)124 void GlobalObjectStorage::VisitObjects(const GCRootVisitor &gc_root_visitor, mem::RootType rootType)
125 {
126 global_storage_->VisitObjects(gc_root_visitor, rootType);
127 }
128
UpdateMovedRefs()129 void GlobalObjectStorage::UpdateMovedRefs()
130 {
131 LOG(DEBUG, GC) << "=== GlobalStorage Update moved. BEGIN ===";
132 global_storage_->UpdateMovedRefs();
133 weak_storage_->UpdateMovedRefs();
134 LOG(DEBUG, GC) << "=== GlobalStorage Update moved. END ===";
135 }
136
ClearUnmarkedWeakRefs(const GC * gc,const mem::GC::ReferenceClearPredicateT & pred)137 void GlobalObjectStorage::ClearUnmarkedWeakRefs(const GC *gc, const mem::GC::ReferenceClearPredicateT &pred)
138 {
139 weak_storage_->ClearUnmarkedWeakRefs(gc, pred);
140 }
141
GetSize()142 size_t GlobalObjectStorage::GetSize()
143 {
144 return global_storage_->GetSizeWithLock() + weak_storage_->GetSizeWithLock();
145 }
146
Dump()147 void GlobalObjectStorage::Dump()
148 {
149 global_storage_->DumpWithLock();
150 }
151 } // namespace panda::mem
152