• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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