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