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
16 #include "graph.h"
17 #include "code_info/code_info.h"
18
19 namespace panda::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 = slow_path_data_->GetSharedSlowPathOffset(id);
28 if (offset == 0) {
29 return 0;
30 }
31 return offset - (code_address_ + 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 slow_path_data_->SetSharedSlowPathOffset(id, code_address_ + pc + CodeInfo::GetCodeOffset(graph_->GetArch()));
37 }
38
GetEntrypointOffset(uint64_t pc,int32_t slot_id) const39 intptr_t AotData::GetEntrypointOffset(uint64_t pc, int32_t slot_id) 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 += slot_id * PointerSize(graph_->GetArch());
45 // Decrement by sum of method code start address and current pc
46 offset -= (code_address_ + pc);
47 // Decrement by header size that prepend method code
48 offset -= CodeInfo::GetCodeOffset(graph_->GetArch());
49 return offset;
50 }
51
GetPltSlotOffset(uint64_t pc,uint32_t method_id)52 intptr_t AotData::GetPltSlotOffset(uint64_t pc, uint32_t method_id)
53 {
54 int32_t slot_id;
55 auto slot = got_plt_->find({pfile_, method_id});
56 if (slot != got_plt_->end()) {
57 slot_id = slot->second;
58 } else {
59 slot_id = GetSlotId();
60 got_plt_->insert({{pfile_, method_id}, slot_id});
61 }
62 return GetEntrypointOffset(pc, slot_id);
63 }
64
GetVirtIndexSlotOffset(uint64_t pc,uint32_t method_id)65 intptr_t AotData::GetVirtIndexSlotOffset(uint64_t pc, uint32_t method_id)
66 {
67 int32_t slot_id;
68 auto slot = got_virt_indexes_->find({pfile_, method_id});
69 if (slot != got_virt_indexes_->end()) {
70 slot_id = slot->second;
71 } else {
72 slot_id = GetSlotId();
73 got_virt_indexes_->insert({{pfile_, method_id}, slot_id});
74 }
75 return GetEntrypointOffset(pc, slot_id);
76 }
77
GetClassSlotOffset(uint64_t pc,uint32_t klass_id,bool init)78 intptr_t AotData::GetClassSlotOffset(uint64_t pc, uint32_t klass_id, bool init)
79 {
80 int32_t slot_id;
81 auto slot = got_class_->find({pfile_, klass_id});
82 if (slot != got_class_->end()) {
83 slot_id = slot->second;
84 } else {
85 slot_id = GetSlotId();
86 got_class_->insert({{pfile_, klass_id}, slot_id});
87 }
88 return GetEntrypointOffset(pc, init ? slot_id - 1 : slot_id);
89 }
90
GetStringSlotOffset(uint64_t pc,uint32_t string_id)91 intptr_t AotData::GetStringSlotOffset(uint64_t pc, uint32_t string_id)
92 {
93 int32_t slot_id;
94 auto slot = got_string_->find({pfile_, string_id});
95 if (slot != got_string_->end()) {
96 slot_id = slot->second;
97 } else {
98 slot_id = GetSlotId();
99 got_string_->insert({{pfile_, string_id}, slot_id});
100 }
101 return GetEntrypointOffset(pc, slot_id);
102 }
103
GetInfInlineCacheSlotOffset(uint64_t pc,uint64_t index)104 uint64_t AotData::GetInfInlineCacheSlotOffset(uint64_t pc, uint64_t index)
105 {
106 uint32_t slot_id;
107 auto slot = got_intf_inline_cache_->find({pfile_, index});
108 if (slot != got_intf_inline_cache_->end()) {
109 slot_id = slot->second;
110 } else {
111 slot_id = GetSlotId();
112 got_intf_inline_cache_->insert({{pfile_, index}, slot_id});
113 }
114 return GetEntrypointOffset(pc, slot_id);
115 }
116
GetSlotId() const117 int32_t AotData::GetSlotId() const
118 {
119 constexpr auto IMM_3 = 3;
120 constexpr auto IMM_2 = 2;
121 return -1 - IMM_3 * (got_plt_->size() + got_class_->size()) -
122 IMM_2 * (got_virt_indexes_->size() + got_string_->size()) - got_intf_inline_cache_->size();
123 }
124 } // namespace panda::compiler
125