1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_H_
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #include "base/locks.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
22*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file.h"
23*795d594fSAndroid Build Coastguard Worker #include "dex/code_item_accessors.h"
24*795d594fSAndroid Build Coastguard Worker #include "jvalue.h"
25*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h"
26*795d594fSAndroid Build Coastguard Worker
27*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker class ShadowFrame;
30*795d594fSAndroid Build Coastguard Worker class Thread;
31*795d594fSAndroid Build Coastguard Worker
32*795d594fSAndroid Build Coastguard Worker namespace interpreter {
33*795d594fSAndroid Build Coastguard Worker
34*795d594fSAndroid Build Coastguard Worker // Group all the data that is needed in the switch interpreter.
35*795d594fSAndroid Build Coastguard Worker // We need to pass it to the hand-written assembly and back,
36*795d594fSAndroid Build Coastguard Worker // so it is easier to pass it through a single pointer.
37*795d594fSAndroid Build Coastguard Worker // Similarly, returning the JValue type would be non-trivial.
38*795d594fSAndroid Build Coastguard Worker struct SwitchImplContext {
39*795d594fSAndroid Build Coastguard Worker Thread* self;
40*795d594fSAndroid Build Coastguard Worker const CodeItemDataAccessor& accessor;
41*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame;
42*795d594fSAndroid Build Coastguard Worker JValue& result_register;
43*795d594fSAndroid Build Coastguard Worker JValue result;
44*795d594fSAndroid Build Coastguard Worker };
45*795d594fSAndroid Build Coastguard Worker
46*795d594fSAndroid Build Coastguard Worker // The actual internal implementation of the switch interpreter.
47*795d594fSAndroid Build Coastguard Worker template<bool transaction_active>
48*795d594fSAndroid Build Coastguard Worker void ExecuteSwitchImplCpp(SwitchImplContext* ctx)
49*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
50*795d594fSAndroid Build Coastguard Worker
51*795d594fSAndroid Build Coastguard Worker // Hand-written assembly method which wraps the C++ implementation,
52*795d594fSAndroid Build Coastguard Worker // while defining the DEX PC in the CFI so that libunwind can resolve it.
53*795d594fSAndroid Build Coastguard Worker extern "C" void ExecuteSwitchImplAsm(
54*795d594fSAndroid Build Coastguard Worker SwitchImplContext* ctx, const void* impl, const uint16_t* dexpc)
55*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_);
56*795d594fSAndroid Build Coastguard Worker
57*795d594fSAndroid Build Coastguard Worker // Wrapper around the switch interpreter which ensures we can unwind through it.
ExecuteSwitchImpl(Thread * self,const CodeItemDataAccessor & accessor,ShadowFrame & shadow_frame,JValue result_register,const void * switch_impl_cpp)58*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE inline JValue ExecuteSwitchImpl(Thread* self,
59*795d594fSAndroid Build Coastguard Worker const CodeItemDataAccessor& accessor,
60*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame,
61*795d594fSAndroid Build Coastguard Worker JValue result_register,
62*795d594fSAndroid Build Coastguard Worker const void* switch_impl_cpp)
63*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
64*795d594fSAndroid Build Coastguard Worker SwitchImplContext ctx {
65*795d594fSAndroid Build Coastguard Worker .self = self,
66*795d594fSAndroid Build Coastguard Worker .accessor = accessor,
67*795d594fSAndroid Build Coastguard Worker .shadow_frame = shadow_frame,
68*795d594fSAndroid Build Coastguard Worker .result_register = result_register,
69*795d594fSAndroid Build Coastguard Worker .result = JValue(),
70*795d594fSAndroid Build Coastguard Worker };
71*795d594fSAndroid Build Coastguard Worker const uint16_t* dex_pc = ctx.accessor.Insns();
72*795d594fSAndroid Build Coastguard Worker ExecuteSwitchImplAsm(&ctx, switch_impl_cpp, dex_pc);
73*795d594fSAndroid Build Coastguard Worker return ctx.result;
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker
76*795d594fSAndroid Build Coastguard Worker } // namespace interpreter
77*795d594fSAndroid Build Coastguard Worker } // namespace art
78*795d594fSAndroid Build Coastguard Worker
79*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_H_
80