• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include "ecmascript/snapshot/mem/snapshot_env.h"
17 
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/global_env.h"
20 
21 namespace panda::ecmascript {
Initialize()22 void SnapshotEnv::Initialize()
23 {
24 #if ECMASCRIPT_ENABLE_SNAPSHOT
25     InitGlobalConst();
26     InitGlobalEnv();
27 #endif
28 }
29 
InitGlobalConst()30 void SnapshotEnv::InitGlobalConst()
31 {
32     auto globalConst = const_cast<GlobalEnvConstants *>(vm_->GetJSThread()->GlobalConstants());
33     size_t constantCount = globalConst->GetConstantCount();
34     for (size_t index = 0; index < constantCount; index++) {
35         JSTaggedValue objectValue = globalConst->GetGlobalConstantObject(index);
36         if (objectValue.IsHeapObject() && !objectValue.IsString()) {
37             TaggedObject *object = objectValue.GetTaggedObject();
38             object->GetClass()->SetGlobalConstOrBuiltinsObject(true);
39             objectVector_.emplace_back(ToUintPtr(object));
40         }
41     }
42 }
43 
InitGlobalEnv()44 void SnapshotEnv::InitGlobalEnv()
45 {
46     auto globalEnv = vm_->GetGlobalEnv();
47     CQueue<TaggedObject *> objectQueue;
48     std::set<TaggedObject *> objectSet;
49     objectQueue.emplace(*globalEnv);
50     objectSet.emplace(*globalEnv);
51     while (!objectQueue.empty()) {
52         auto taggedObject = objectQueue.front();
53         if (taggedObject == nullptr) {
54             break;
55         }
56         taggedObject->GetClass()->SetGlobalConstOrBuiltinsObject(true);
57         objectVector_.emplace_back(ToUintPtr(taggedObject));
58         objectQueue.pop();
59         HandleObjectField(taggedObject, &objectQueue, &objectSet);
60     }
61 }
62 
HandleObjectField(TaggedObject * objectHeader,CQueue<TaggedObject * > * objectQueue,std::set<TaggedObject * > * objectSet)63 void SnapshotEnv::HandleObjectField(TaggedObject *objectHeader, CQueue<TaggedObject *> *objectQueue,
64                                     std::set<TaggedObject *> *objectSet)
65 {
66     auto visitor = [objectQueue, objectSet](TaggedObject *root, ObjectSlot start, ObjectSlot end,
67                                             VisitObjectArea area) {
68         auto hclass = root->GetClass();
69         int index = 0;
70         for (ObjectSlot slot = start; slot < end; slot++) {
71             if (area == VisitObjectArea::IN_OBJECT && !hclass->IsAllTaggedProp()) {
72                 auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
73                 auto attr = layout->GetAttr(index++);
74                 if (!attr.IsTaggedRep()) {
75                     continue;
76                 }
77             }
78             auto fieldAddr = reinterpret_cast<JSTaggedType *>(slot.SlotAddress());
79             JSTaggedValue fieldValue(*fieldAddr);
80             if (fieldValue.IsHeapObject() && !fieldValue.IsWeak() && !fieldValue.IsString()
81                 && objectSet->find(fieldValue.GetTaggedObject()) == objectSet->end()) {
82                 auto object = fieldValue.GetTaggedObject();
83                 objectQueue->emplace(object);
84                 objectSet->emplace(object);
85             }
86         }
87     };
88     objXRay_.VisitObjectBody<VisitType::OLD_GC_VISIT>(objectHeader, objectHeader->GetClass(), visitor);
89 }
90 
Iterate(const RootVisitor & v)91 void SnapshotEnv::Iterate(const RootVisitor &v)
92 {
93     uint64_t length = objectVector_.size();
94     for (uint64_t i = 0; i < length; i++) {
95         v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&(objectVector_.data()[i]))));
96     }
97 }
98 }  // namespace panda::ecmascript
99 
100