• 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 #ifndef ECMASCRIPT_MEM_MACHINE_CODE_H
16 #define ECMASCRIPT_MEM_MACHINE_CODE_H
17 
18 #include "ecmascript/ecma_macros.h"
19 #include "ecmascript/js_tagged_value.h"
20 #include "ecmascript/mem/barriers.h"
21 #include "ecmascript/mem/tagged_object.h"
22 #include "ecmascript/mem/visitor.h"
23 #include "ecmascript/stackmap/ark_stackmap.h"
24 #include "ecmascript/method.h"
25 
26 #include "libpandabase/macros.h"
27 
28 namespace panda::ecmascript {
29 struct MachineCodeDesc {
30     uintptr_t rodataAddrBeforeText {0};
31     size_t rodataSizeBeforeText {0};
32     uintptr_t rodataAddrAfterText {0};
33     size_t rodataSizeAfterText {0};
34 
35     uintptr_t codeAddr {0};
36     size_t codeSize {0};
37     uintptr_t funcEntryDesAddr {0};
38     size_t funcEntryDesSize {0};
39     uintptr_t stackMapAddr {0};
40     size_t stackMapSize {0};
41 };
42 // JitCode object layout:
43 //                      +-----------------------------------+
44 //                      |              MarkWord             | 8 bytes
45 //      INS_SIZE_OFFSET +-----------------------------------+
46 //                      |          machine payload size     | 4 bytes
47 //                      +-----------------------------------+
48 //                      |          FuncEntryDesc size       | 4 bytes
49 //                      +-----------------------------------+
50 //                      |          instructions size        | 4 bytes
51 //                      +-----------------------------------+
52 //                      |           stack map size          | 4 bytes
53 //                      +-----------------------------------+
54 //                      |             func addr             | 8 bytes
55 //       PAYLOAD_OFFSET +-----------------------------------+
56 //       (8 byte align) |           FuncEntryDesc           |
57 //                      |              ...                  |
58 //       INSTR_OFFSET   +-----------------------------------+
59 //       (16 byte align)|     machine instructions(text)    |
60 //                      |              ...                  |
61 //      STACKMAP_OFFSET +-----------------------------------+
62 //                      |            ArkStackMap            |
63 //                      |              ...                  |
64 //                      +-----------------------------------+
65 class MachineCode : public TaggedObject {
66 public:
67     NO_COPY_SEMANTIC(MachineCode);
68     NO_MOVE_SEMANTIC(MachineCode);
Cast(TaggedObject * object)69     static MachineCode *Cast(TaggedObject *object)
70     {
71         ASSERT(JSTaggedValue(object).IsMachineCodeObject());
72         return static_cast<MachineCode *>(object);
73     }
74 
75     static constexpr size_t INS_SIZE_OFFSET = TaggedObjectSize();
76     ACCESSORS_PRIMITIVE_FIELD(PayLoadSizeInBytes, uint32_t, INS_SIZE_OFFSET, FUNCENTRYDESSIZE_OFFSET);
77     ACCESSORS_PRIMITIVE_FIELD(FuncEntryDesSize, uint32_t, FUNCENTRYDESSIZE_OFFSET, INSTRSIZ_OFFSET);
78     ACCESSORS_PRIMITIVE_FIELD(InstructionsSize, uint32_t, INSTRSIZ_OFFSET, STACKMAPSIZE_OFFSET);
79     ACCESSORS_PRIMITIVE_FIELD(StackMapSize, uint32_t, STACKMAPSIZE_OFFSET, FUNCADDR_OFFSET);
80     ACCESSORS_PRIMITIVE_FIELD(FuncAddr, uint64_t, FUNCADDR_OFFSET, PADDING_OFFSET);
81     ACCESSORS_PRIMITIVE_FIELD(Padding, uint64_t, PADDING_OFFSET, LAST_OFFSET);
82     DEFINE_ALIGN_SIZE(LAST_OFFSET);
83     static constexpr size_t PAYLOAD_OFFSET = SIZE;
84     static constexpr uint32_t DATA_ALIGN = 8;
85     static constexpr uint32_t TEXT_ALIGN = 16;
86 
DECL_DUMP()87     DECL_DUMP()
88 
89     uintptr_t GetFuncEntryDesAddress() const
90     {
91         uintptr_t paddingAddr = reinterpret_cast<const uintptr_t>(this) + PADDING_OFFSET;
92         return IsAligned(paddingAddr, TEXT_ALIGN) ? paddingAddr : reinterpret_cast<const uintptr_t>(this) +
93             PAYLOAD_OFFSET;
94     }
95 
GetText()96     uintptr_t GetText() const
97     {
98         return GetFuncEntryDesAddress() + GetFuncEntryDesSize();
99     }
100 
GetStackMapAddress()101     uint8_t *GetStackMapAddress() const
102     {
103         return reinterpret_cast<uint8_t*>(GetText() + GetInstructionsSize());
104     }
105 
GetTextSize()106     size_t GetTextSize() const
107     {
108         return GetInstructionsSize();
109     }
110 
111     void SetData(const MachineCodeDesc *desc, JSHandle<Method> &method, size_t dataSize);
112 
113     template <VisitType visitType>
VisitRangeSlot(const EcmaObjectRangeVisitor & visitor)114     void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor)
115     {
116         if (visitType == VisitType::ALL_VISIT) {
117             visitor(this, ObjectSlot(ToUintPtr(this)),
118                 ObjectSlot(ToUintPtr(this) + GetMachineCodeObjectSize()), VisitObjectArea::RAW_DATA);
119         }
120     }
121 
GetMachineCodeObjectSize()122     size_t GetMachineCodeObjectSize()
123     {
124         return SIZE + this->GetPayLoadSizeInBytes();
125     }
126 
GetInstructionSizeInBytes()127     uint32_t GetInstructionSizeInBytes() const
128     {
129         return GetPayLoadSizeInBytes();
130     }
131 
132     bool IsInText(const uintptr_t pc) const;
133     uintptr_t GetFuncEntryDes() const;
134 
135     std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
136 };
137 }  // namespace panda::ecmascript
138 #endif  // ECMASCRIPT_MEM_MACHINE_CODE_H
139