Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_RUNTIME_METHOD_HANDLES_H_
     18 #define ART_RUNTIME_METHOD_HANDLES_H_
     19 
     20 #include <ostream>
     21 
     22 #include "dex/dex_instruction.h"
     23 #include "handle.h"
     24 #include "interpreter/shadow_frame.h"
     25 #include "jvalue.h"
     26 #include "mirror/class.h"
     27 
     28 namespace art {
     29 
     30 namespace mirror {
     31 class MethodHandle;
     32 class MethodType;
     33 }  // namespace mirror
     34 
     35 // Returns true if there is a possible conversion from |from| to |to|
     36 // for a MethodHandle parameter.
     37 bool IsParameterTypeConvertible(ObjPtr<mirror::Class> from,
     38                                 ObjPtr<mirror::Class> to);
     39 
     40 // Returns true if there is a possible conversion from |from| to |to|
     41 // for the return type of a MethodHandle.
     42 bool IsReturnTypeConvertible(ObjPtr<mirror::Class> from,
     43                              ObjPtr<mirror::Class> to);
     44 
     45 // Performs a conversion from type |from| to a distinct type |to| as
     46 // part of conversion of |caller_type| to |callee_type|. The value to
     47 // be converted is in |value|. Returns true on success and updates
     48 // |value| with the converted value, false otherwise.
     49 bool ConvertJValueCommon(Handle<mirror::MethodType> callsite_type,
     50                          Handle<mirror::MethodType> callee_type,
     51                          ObjPtr<mirror::Class> from,
     52                          ObjPtr<mirror::Class> to,
     53                          JValue* value)
     54     REQUIRES_SHARED(Locks::mutator_lock_);
     55 
     56 // Converts the value of the argument at position |index| from type
     57 // expected by |callee_type| to type used by |callsite_type|. |value|
     58 // represents the value to be converted. Returns true on success and
     59 // updates |value|, false otherwise.
     60 ALWAYS_INLINE bool ConvertArgumentValue(Handle<mirror::MethodType> callsite_type,
     61                                         Handle<mirror::MethodType> callee_type,
     62                                         int index,
     63                                         JValue* value)
     64     REQUIRES_SHARED(Locks::mutator_lock_);
     65 
     66 // Converts the return value from return type yielded by
     67 // |callee_type| to the return type yielded by
     68 // |callsite_type|. |value| represents the value to be
     69 // converted. Returns true on success and updates |value|, false
     70 // otherwise.
     71 ALWAYS_INLINE bool ConvertReturnValue(Handle<mirror::MethodType> callsite_type,
     72                                       Handle<mirror::MethodType> callee_type,
     73                                       JValue* value)
     74     REQUIRES_SHARED(Locks::mutator_lock_);
     75 
     76 // Perform argument conversions between |callsite_type| (the type of the
     77 // incoming arguments) and |callee_type| (the type of the method being
     78 // invoked). These include widening and narrowing conversions as well as
     79 // boxing and unboxing. Returns true on success, on false on failure. A
     80 // pending exception will always be set on failure.
     81 //
     82 // The values to be converted are read from an input source (of type G)
     83 // that provides three methods :
     84 //
     85 // class G {
     86 //   // Used to read the next boolean/short/int or float value from the
     87 //   // source.
     88 //   uint32_t Get();
     89 //
     90 //   // Used to the read the next reference value from the source.
     91 //   ObjPtr<mirror::Object> GetReference();
     92 //
     93 //   // Used to read the next double or long value from the source.
     94 //   int64_t GetLong();
     95 // }
     96 //
     97 // After conversion, the values are written to an output sink (of type S)
     98 // that provides three methods :
     99 //
    100 // class S {
    101 //   void Set(uint32_t);
    102 //   void SetReference(ObjPtr<mirror::Object>)
    103 //   void SetLong(int64_t);
    104 // }
    105 //
    106 // The semantics and usage of the Set methods are analagous to the getter
    107 // class.
    108 //
    109 // This method is instantiated in three different scenarions :
    110 // - <S = ShadowFrameSetter, G = ShadowFrameGetter> : copying from shadow
    111 //   frame to shadow frame, used in a regular polymorphic non-exact invoke.
    112 // - <S = EmulatedShadowFrameAccessor, G = ShadowFrameGetter> : entering into
    113 //   a transformer method from a polymorphic invoke.
    114 // - <S = ShadowFrameStter, G = EmulatedStackFrameAccessor> : entering into
    115 //   a regular poly morphic invoke from a transformer method.
    116 //
    117 // TODO(narayan): If we find that the instantiations of this function take
    118 // up too much space, we can make G / S abstract base classes that are
    119 // overridden by concrete classes.
    120 template <typename G, typename S>
    121 bool PerformConversions(Thread* self,
    122                         Handle<mirror::MethodType> callsite_type,
    123                         Handle<mirror::MethodType> callee_type,
    124                         G* getter,
    125                         S* setter,
    126                         int32_t start_index,
    127                         int32_t end_index) REQUIRES_SHARED(Locks::mutator_lock_);
    128 
    129 // A convenience class that allows for iteration through a list of
    130 // input argument registers. This is used to iterate over input
    131 // arguments while performing standard argument conversions.
    132 class ShadowFrameGetter {
    133  public:
    134   ShadowFrameGetter(const ShadowFrame& shadow_frame,
    135                     const InstructionOperands* const operands,
    136                     size_t operand_index = 0u)
    137       : shadow_frame_(shadow_frame), operands_(operands), operand_index_(operand_index)  {}
    138 
    139   ALWAYS_INLINE uint32_t Get() REQUIRES_SHARED(Locks::mutator_lock_) {
    140     return shadow_frame_.GetVReg(Next());
    141   }
    142 
    143   ALWAYS_INLINE int64_t GetLong() REQUIRES_SHARED(Locks::mutator_lock_) {
    144     return shadow_frame_.GetVRegLong(NextLong());
    145   }
    146 
    147   ALWAYS_INLINE ObjPtr<mirror::Object> GetReference() REQUIRES_SHARED(Locks::mutator_lock_) {
    148     return shadow_frame_.GetVRegReference(Next());
    149   }
    150 
    151  private:
    152   uint32_t Next() {
    153     const uint32_t next = operands_->GetOperand(operand_index_);
    154     operand_index_ += 1;
    155     return next;
    156   }
    157 
    158   uint32_t NextLong() {
    159     const uint32_t next = operands_->GetOperand(operand_index_);
    160     operand_index_ += 2;
    161     return next;
    162   }
    163 
    164   const ShadowFrame& shadow_frame_;
    165   const InstructionOperands* const operands_;  // the set of register operands to read
    166   size_t operand_index_;  // the next register operand to read from frame
    167 };
    168 
    169 // A convenience class that allows values to be written to a given shadow frame,
    170 // starting at location |first_dst_reg|.
    171 class ShadowFrameSetter {
    172  public:
    173   ShadowFrameSetter(ShadowFrame* shadow_frame, size_t first_dst_reg)
    174       : shadow_frame_(shadow_frame), arg_index_(first_dst_reg) {}
    175 
    176   ALWAYS_INLINE void Set(uint32_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
    177     shadow_frame_->SetVReg(arg_index_++, value);
    178   }
    179 
    180   ALWAYS_INLINE void SetReference(ObjPtr<mirror::Object> value)
    181       REQUIRES_SHARED(Locks::mutator_lock_) {
    182     shadow_frame_->SetVRegReference(arg_index_++, value.Ptr());
    183   }
    184 
    185   ALWAYS_INLINE void SetLong(int64_t value) REQUIRES_SHARED(Locks::mutator_lock_) {
    186     shadow_frame_->SetVRegLong(arg_index_, value);
    187     arg_index_ += 2;
    188   }
    189 
    190  private:
    191   ShadowFrame* shadow_frame_;
    192   size_t arg_index_;
    193 };
    194 
    195 bool MethodHandleInvoke(Thread* self,
    196                         ShadowFrame& shadow_frame,
    197                         Handle<mirror::MethodHandle> method_handle,
    198                         Handle<mirror::MethodType> callsite_type,
    199                         const InstructionOperands* const args,
    200                         JValue* result)
    201     REQUIRES_SHARED(Locks::mutator_lock_);
    202 
    203 bool MethodHandleInvokeExact(Thread* self,
    204                              ShadowFrame& shadow_frame,
    205                              Handle<mirror::MethodHandle> method_handle,
    206                              Handle<mirror::MethodType> callsite_type,
    207                              const InstructionOperands* const args,
    208                              JValue* result)
    209     REQUIRES_SHARED(Locks::mutator_lock_);
    210 
    211 }  // namespace art
    212 
    213 #endif  // ART_RUNTIME_METHOD_HANDLES_H_
    214