1 /*
2 * Copyright (c) 2021-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 "graph.h"
17 #include "code_info/code_info.h"
18
19 namespace ark::compiler {
GetEpTableOffset() const20 intptr_t AotData::GetEpTableOffset() const
21 {
22 return -(static_cast<size_t>(RuntimeInterface::IntrinsicId::COUNT) * PointerSize(graph_->GetArch()));
23 }
24
GetSharedSlowPathOffset(RuntimeInterface::EntrypointId id,uintptr_t pc) const25 intptr_t AotData::GetSharedSlowPathOffset(RuntimeInterface::EntrypointId id, uintptr_t pc) const
26 {
27 auto offset = slowPathData_->GetSharedSlowPathOffset(id);
28 if (offset == 0) {
29 return 0;
30 }
31 return offset - (codeAddress_ + pc + CodeInfo::GetCodeOffset(graph_->GetArch()));
32 }
33
SetSharedSlowPathOffset(RuntimeInterface::EntrypointId id,uintptr_t pc)34 void AotData::SetSharedSlowPathOffset(RuntimeInterface::EntrypointId id, uintptr_t pc)
35 {
36 slowPathData_->SetSharedSlowPathOffset(id, codeAddress_ + pc + CodeInfo::GetCodeOffset(graph_->GetArch()));
37 }
38
GetEntrypointOffset(uint64_t pc,int32_t slotId) const39 intptr_t AotData::GetEntrypointOffset(uint64_t pc, int32_t slotId) const
40 {
41 // Initialize offset by offset to the origin of the entrypoint table
42 intptr_t offset = GetEpTableOffset();
43 // Increment/decrement offset to specified slot
44 offset += slotId * static_cast<intptr_t>(PointerSize(graph_->GetArch()));
45 // Decrement by sum of method code start address and current pc
46 offset -= static_cast<intptr_t>(codeAddress_ + pc);
47 // Decrement by header size that prepend method code
48 offset -= static_cast<intptr_t>(CodeInfo::GetCodeOffset(graph_->GetArch()));
49 return offset;
50 }
51
GetPltSlotOffset(uint64_t pc,uint32_t methodId)52 intptr_t AotData::GetPltSlotOffset(uint64_t pc, uint32_t methodId)
53 {
54 int32_t slotId = GetPltSlotId(methodId);
55 return GetEntrypointOffset(pc, slotId);
56 }
57
GetPltSlotId(uint32_t methodId)58 int32_t AotData::GetPltSlotId(uint32_t methodId)
59 {
60 int32_t slotId;
61 auto slot = gotPlt_->find({pfile_, methodId});
62 if (slot != gotPlt_->end()) {
63 slotId = slot->second;
64 } else {
65 slotId = GetSlotId();
66 gotPlt_->insert({{pfile_, methodId}, slotId});
67 }
68 return slotId;
69 }
70
GetVirtIndexSlotOffset(uint64_t pc,uint32_t methodId)71 intptr_t AotData::GetVirtIndexSlotOffset(uint64_t pc, uint32_t methodId)
72 {
73 int32_t slotId;
74 auto slot = gotVirtIndexes_->find({pfile_, methodId});
75 if (slot != gotVirtIndexes_->end()) {
76 slotId = slot->second;
77 } else {
78 slotId = GetSlotId();
79 gotVirtIndexes_->insert({{pfile_, methodId}, slotId});
80 }
81 return GetEntrypointOffset(pc, slotId);
82 }
83
GetClassSlotOffset(uint64_t pc,uint32_t klassId,bool init)84 intptr_t AotData::GetClassSlotOffset(uint64_t pc, uint32_t klassId, bool init)
85 {
86 int32_t slotId = GetClassSlotId(klassId);
87 return GetEntrypointOffset(pc, init ? slotId - 1 : slotId);
88 }
89
GetStringSlotOffset(uint64_t pc,uint32_t stringId)90 intptr_t AotData::GetStringSlotOffset(uint64_t pc, uint32_t stringId)
91 {
92 int32_t slotId = GetStringSlotId(stringId);
93 return GetEntrypointOffset(pc, slotId);
94 }
95
GetClassSlotId(uint32_t klassId)96 int32_t AotData::GetClassSlotId(uint32_t klassId)
97 {
98 int32_t slotId;
99 auto slot = gotClass_->find({pfile_, klassId});
100 if (slot != gotClass_->end()) {
101 slotId = slot->second;
102 } else {
103 slotId = GetSlotId();
104 gotClass_->insert({{pfile_, klassId}, slotId});
105 }
106 return slotId;
107 }
108
GetStringSlotId(uint32_t stringId)109 int32_t AotData::GetStringSlotId(uint32_t stringId)
110 {
111 int32_t slotId;
112 auto slot = gotString_->find({pfile_, stringId});
113 if (slot != gotString_->end()) {
114 slotId = slot->second;
115 } else {
116 slotId = GetSlotId();
117 gotString_->insert({{pfile_, stringId}, slotId});
118 }
119 return slotId;
120 }
121
GetCommonSlotOffset(uint64_t pc,uint32_t id)122 intptr_t AotData::GetCommonSlotOffset(uint64_t pc, uint32_t id)
123 {
124 int32_t slotId;
125 auto slot = gotCommon_->find({pfile_, id});
126 if (slot != gotCommon_->end()) {
127 slotId = slot->second;
128 } else {
129 slotId = GetSlotId();
130 gotCommon_->insert({{pfile_, id}, slotId});
131 }
132 return GetEntrypointOffset(pc, slotId);
133 }
134
GetInfInlineCacheSlotOffset(uint64_t pc,uint64_t cacheIdx)135 uint64_t AotData::GetInfInlineCacheSlotOffset(uint64_t pc, uint64_t cacheIdx)
136 {
137 int32_t slotId = GetIntfInlineCacheSlotId(cacheIdx);
138 return GetEntrypointOffset(pc, slotId);
139 }
140
GetIntfInlineCacheSlotId(uint64_t cacheIdx)141 int32_t AotData::GetIntfInlineCacheSlotId(uint64_t cacheIdx)
142 {
143 int32_t slotId;
144 auto slot = gotIntfInlineCache_->find({pfile_, cacheIdx});
145 if (slot != gotIntfInlineCache_->end()) {
146 slotId = slot->second;
147 } else {
148 slotId = GetSlotId();
149 gotIntfInlineCache_->insert({{pfile_, cacheIdx}, slotId});
150 }
151 return slotId;
152 }
153
GetSlotId() const154 int32_t AotData::GetSlotId() const
155 {
156 constexpr auto IMM_3 = 3;
157 constexpr auto IMM_2 = 2;
158 return -1 - IMM_3 * (gotPlt_->size() + gotClass_->size()) - IMM_2 * (gotVirtIndexes_->size() + gotString_->size()) -
159 gotIntfInlineCache_->size() - gotCommon_->size();
160 }
161 } // namespace ark::compiler
162