• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "runtime/interpreter/interpreter_impl.h"
17 
18 #include "libpandabase/macros.h"
19 #include "runtime/interpreter/interpreter-inl.h"
20 #include "runtime/interpreter/runtime_interface.h"
21 #include "irtoc_interpreter_utils.h"
22 #include "interpreter-inl_gen.h"
23 
24 extern "C" void ExecuteImplFast(void *, void *, void *, void *);
25 
26 namespace panda::interpreter {
27 
ExecuteImpl(ManagedThread * thread,const uint8_t * pc,Frame * frame,bool jump_to_eh)28 void ExecuteImpl(ManagedThread *thread, const uint8_t *pc, Frame *frame, bool jump_to_eh)
29 {
30     const uint8_t *inst_ = frame->GetMethod()->GetInstructions();
31     frame->SetInstruction(inst_);
32 // If it is GN Build with disabled asmjit and irtoc is not available
33 #if defined(PANDA_TARGET_AMD64) && !defined(PANDA_COMPILER_TARGET_X86_64)
34     bool with_irtoc = false;
35 #else
36     bool with_irtoc = true;
37 #endif
38     if ((Runtime::GetOptions().GetInterpreterType() == "irtoc") && with_irtoc) {
39         [[maybe_unused]] auto lang = thread->GetVM()->GetLanguageContext().GetLanguage();
40         ASSERT(Runtime::GetOptions().GetGcType(plugins::LangToRuntimeType(lang)) == "g1-gc");
41         auto dispath_table = SetupDispatchTableImpl();
42         ExecuteImplFast(thread, const_cast<uint8_t *>(pc), frame, dispath_table);
43     } else {
44         if (jump_to_eh) {
45             if (frame->IsDynamic()) {
46                 ExecuteImpl_Inner<RuntimeInterface, true, true>(thread, pc, frame);
47             } else {
48                 ExecuteImpl_Inner<RuntimeInterface, true, false>(thread, pc, frame);
49             }
50         } else {
51             if (frame->IsDynamic()) {
52                 ExecuteImpl_Inner<RuntimeInterface, false, true>(thread, pc, frame);
53             } else {
54                 ExecuteImpl_Inner<RuntimeInterface, false, false>(thread, pc, frame);
55             }
56         }
57     }
58 }
59 
60 // Methods for debugging
61 
62 template <class RuntimeIfaceT, bool is_dynamic>
DebugDump()63 void InstructionHandlerBase<RuntimeIfaceT, is_dynamic>::DebugDump()
64 {
65 #ifndef NDEBUG
66     auto frame = GetFrame();
67     auto method = frame->GetMethod();
68     PandaString pad = "     ";
69     std::cerr << "Method " << method->GetFullName(true) << std::endl;
70     std::cerr << pad << "nargs = " << method->GetNumArgs() << std::endl;
71     std::cerr << pad << "nregs = " << method->GetNumVregs() << std::endl;
72     std::cerr << pad << "total frame size = " << frame->GetSize() << std::endl;
73     std::cerr << "Frame:" << std::endl;
74     std::cerr << pad << "acc." << GetAccAsVReg<is_dynamic>().DumpVReg() << std::endl;
75     auto frame_handler = GetFrameHandler(frame);
76     for (size_t i = 0; i < frame->GetSize(); ++i) {
77         std::cerr << pad << "v" << i << "." << frame_handler.GetVReg(i).DumpVReg() << std::endl;
78     }
79     std::cerr << "Bytecode:" << std::endl;
80     size_t offset = 0;
81     BytecodeInstruction inst(method->GetInstructions());
82     while (offset < method->GetCodeSize()) {
83         if (inst.GetAddress() == GetInst().GetAddress()) {
84             std::cerr << "  -> ";
85         } else {
86             std::cerr << "     ";
87         }
88 
89         std::cerr << std::hex << std::setw(sizeof(uintptr_t)) << std::setfill('0')
90                   << reinterpret_cast<uintptr_t>(inst.GetAddress()) << std::dec << ": " << inst << std::endl;
91         offset += inst.GetSize();
92         inst = inst.GetNext();
93     }
94 #endif  // NDEBUG
95 }
96 
EnsureDebugMethodsInstantiation(void * handler)97 void EnsureDebugMethodsInstantiation(void *handler)
98 {
99     static_cast<InstructionHandlerBase<RuntimeInterface, false> *>(handler)->DebugDump();
100     static_cast<InstructionHandlerBase<RuntimeInterface, true> *>(handler)->DebugDump();
101 }
102 
103 }  // namespace panda::interpreter
104