• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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/sustaining_js_handle.h"
17 #include "ecmascript/jit/jit_thread.h"
18 #include "ecmascript/jit/jit_task.h"
19 
20 namespace panda::ecmascript {
SustainingJSHandle(EcmaVM * vm)21 SustainingJSHandle::SustainingJSHandle(EcmaVM *vm) : vm_(vm)
22 {
23     vm_->AddSustainingJSHandle(this);
24 }
25 
~SustainingJSHandle()26 SustainingJSHandle::~SustainingJSHandle()
27 {
28     vm_->RemoveSustainingJSHandle(this);
29     for (auto block : handleBlocks_) {
30         delete block;
31     }
32     handleBlocks_.clear();
33 }
34 
GetJsHandleSlot(const JitThread * jitThread,JSTaggedType value)35 uintptr_t SustainingJSHandle::GetJsHandleSlot(const JitThread *jitThread, JSTaggedType value)
36 {
37     // new handle from jit current task sustaining jshandle
38     auto jitTask = jitThread->GetCurrentTask();
39     ASSERT(jitTask != nullptr);
40     auto sustainingJSHandle = jitTask->GetSustainingJSHandle();
41     ASSERT(sustainingJSHandle != nullptr);
42     return sustainingJSHandle->GetJsHandleSlot(value);
43 }
44 
GetJsHandleSlot(JSTaggedType value)45 uintptr_t SustainingJSHandle::GetJsHandleSlot(JSTaggedType value)
46 {
47     if (blockNext_ == blockLimit_) {
48         Expand();
49     }
50     ASSERT(blockNext_ != blockLimit_);
51 
52     *blockNext_ = value;
53     uintptr_t slot = reinterpret_cast<uintptr_t>(blockNext_);
54     blockNext_++;
55     return slot;
56 }
57 
Expand()58 uintptr_t SustainingJSHandle::Expand()
59 {
60     auto block = new std::array<JSTaggedType, BLOCK_SIZE>();
61     handleBlocks_.push_back(block);
62 
63     blockNext_ = &block->data()[0];
64     blockLimit_ = &block->data()[BLOCK_SIZE];
65     return reinterpret_cast<uintptr_t>(blockNext_);
66 }
67 
Iterate(RootVisitor & v)68 void SustainingJSHandle::Iterate(RootVisitor &v)
69 {
70     size_t size = handleBlocks_.size();
71     for (size_t i = 0; i < size; ++i) {
72         auto block = handleBlocks_.at(i);
73         auto start = block->data();
74         auto end = (i != (size - 1)) ? &(block->data()[BLOCK_SIZE]) : blockNext_;
75         v.VisitRangeRoot(Root::ROOT_HANDLE, ObjectSlot(ToUintPtr(start)), ObjectSlot(ToUintPtr(end)));
76     }
77 }
78 
AddSustainingJSHandle(SustainingJSHandle * sustainingJSHandle)79 void SustainingJSHandleList::AddSustainingJSHandle(SustainingJSHandle *sustainingJSHandle)
80 {
81     LockHolder lock(mutex_);
82     if (sustainingJSHandle == nullptr) {
83         return;
84     }
85 
86     if (listHead_ == nullptr) {
87         listHead_ = sustainingJSHandle;
88         return;
89     }
90     sustainingJSHandle->next_ = listHead_;
91     listHead_->pre_ = sustainingJSHandle;
92     listHead_ = sustainingJSHandle;
93 }
94 
RemoveSustainingJSHandle(SustainingJSHandle * sustainingJSHandle)95 void SustainingJSHandleList::RemoveSustainingJSHandle(SustainingJSHandle *sustainingJSHandle)
96 {
97     LockHolder lock(mutex_);
98     if (sustainingJSHandle == nullptr) {
99         return;
100     }
101 
102     auto next = sustainingJSHandle->next_;
103     auto pre = sustainingJSHandle->pre_;
104     if (pre != nullptr) {
105         pre->next_ = next;
106     }
107     if (next != nullptr) {
108         next->pre_ = pre;
109     }
110 
111     if (listHead_ == sustainingJSHandle) {
112         listHead_ = sustainingJSHandle->next_;
113     }
114 }
115 
Iterate(RootVisitor & v)116 void SustainingJSHandleList::Iterate(RootVisitor &v)
117 {
118     LockHolder lock(mutex_);
119     for (auto handles = listHead_; handles != nullptr; handles = handles->next_) {
120         handles->Iterate(v);
121     }
122 }
123 }  // namespace panda::ecmascript
124