Home | History | Annotate | Download | only in entrypoints
      1 /*
      2  * Copyright (C) 2012 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_ENTRYPOINTS_ENTRYPOINT_UTILS_H_
     18 #define ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_
     19 
     20 #include <jni.h>
     21 #include <stdint.h>
     22 
     23 #include "base/macros.h"
     24 #include "base/mutex.h"
     25 #include "dex_instruction.h"
     26 #include "gc/allocator_type.h"
     27 #include "invoke_type.h"
     28 #include "jvalue.h"
     29 #include "runtime.h"
     30 
     31 namespace art {
     32 
     33 namespace mirror {
     34   class Array;
     35   class Class;
     36   class Object;
     37   class String;
     38 }  // namespace mirror
     39 
     40 class ArtField;
     41 class ArtMethod;
     42 class OatQuickMethodHeader;
     43 class ScopedObjectAccessAlreadyRunnable;
     44 class Thread;
     45 
     46 template <const bool kAccessCheck>
     47 ALWAYS_INLINE inline mirror::Class* CheckObjectAlloc(uint32_t type_idx,
     48                                                      ArtMethod* method,
     49                                                      Thread* self, bool* slow_path)
     50     SHARED_REQUIRES(Locks::mutator_lock_);
     51 
     52 ALWAYS_INLINE inline mirror::Class* CheckClassInitializedForObjectAlloc(mirror::Class* klass,
     53                                                                         Thread* self,
     54                                                                         bool* slow_path)
     55     SHARED_REQUIRES(Locks::mutator_lock_);
     56 
     57 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it
     58 // cannot be resolved, throw an error. If it can, use it to create an instance.
     59 // When verification/compiler hasn't been able to verify access, optionally perform an access
     60 // check.
     61 template <bool kAccessCheck, bool kInstrumented>
     62 ALWAYS_INLINE inline mirror::Object* AllocObjectFromCode(uint32_t type_idx,
     63                                                          ArtMethod* method,
     64                                                          Thread* self,
     65                                                          gc::AllocatorType allocator_type)
     66     SHARED_REQUIRES(Locks::mutator_lock_);
     67 
     68 // Given the context of a calling Method and a resolved class, create an instance.
     69 template <bool kInstrumented>
     70 ALWAYS_INLINE inline mirror::Object* AllocObjectFromCodeResolved(mirror::Class* klass,
     71                                                                  Thread* self,
     72                                                                  gc::AllocatorType allocator_type)
     73     SHARED_REQUIRES(Locks::mutator_lock_);
     74 
     75 // Given the context of a calling Method and an initialized class, create an instance.
     76 template <bool kInstrumented>
     77 ALWAYS_INLINE inline mirror::Object* AllocObjectFromCodeInitialized(mirror::Class* klass,
     78                                                                     Thread* self,
     79                                                                     gc::AllocatorType allocator_type)
     80     SHARED_REQUIRES(Locks::mutator_lock_);
     81 
     82 
     83 template <bool kAccessCheck>
     84 ALWAYS_INLINE inline mirror::Class* CheckArrayAlloc(uint32_t type_idx,
     85                                                     int32_t component_count,
     86                                                     ArtMethod* method,
     87                                                     bool* slow_path)
     88     SHARED_REQUIRES(Locks::mutator_lock_);
     89 
     90 // Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If
     91 // it cannot be resolved, throw an error. If it can, use it to create an array.
     92 // When verification/compiler hasn't been able to verify access, optionally perform an access
     93 // check.
     94 template <bool kAccessCheck, bool kInstrumented>
     95 ALWAYS_INLINE inline mirror::Array* AllocArrayFromCode(uint32_t type_idx,
     96                                                        int32_t component_count,
     97                                                        ArtMethod* method,
     98                                                        Thread* self,
     99                                                        gc::AllocatorType allocator_type)
    100     SHARED_REQUIRES(Locks::mutator_lock_);
    101 
    102 template <bool kAccessCheck, bool kInstrumented>
    103 ALWAYS_INLINE inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
    104                                                                int32_t component_count,
    105                                                                ArtMethod* method,
    106                                                                Thread* self,
    107                                                                gc::AllocatorType allocator_type)
    108     SHARED_REQUIRES(Locks::mutator_lock_);
    109 
    110 extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, int32_t component_count,
    111                                                  ArtMethod* method, Thread* self,
    112                                                  bool access_check,
    113                                                  gc::AllocatorType allocator_type)
    114     SHARED_REQUIRES(Locks::mutator_lock_);
    115 
    116 extern mirror::Array* CheckAndAllocArrayFromCodeInstrumented(uint32_t type_idx,
    117                                                              int32_t component_count,
    118                                                              ArtMethod* method,
    119                                                              Thread* self,
    120                                                              bool access_check,
    121                                                              gc::AllocatorType allocator_type)
    122     SHARED_REQUIRES(Locks::mutator_lock_);
    123 
    124 // Type of find field operation for fast and slow case.
    125 enum FindFieldType {
    126   InstanceObjectRead,
    127   InstanceObjectWrite,
    128   InstancePrimitiveRead,
    129   InstancePrimitiveWrite,
    130   StaticObjectRead,
    131   StaticObjectWrite,
    132   StaticPrimitiveRead,
    133   StaticPrimitiveWrite,
    134 };
    135 
    136 template<FindFieldType type, bool access_check>
    137 inline ArtField* FindFieldFromCode(
    138     uint32_t field_idx, ArtMethod* referrer, Thread* self, size_t expected_size)
    139     SHARED_REQUIRES(Locks::mutator_lock_);
    140 
    141 template<InvokeType type, bool access_check>
    142 inline ArtMethod* FindMethodFromCode(
    143     uint32_t method_idx, mirror::Object** this_object, ArtMethod* referrer, Thread* self)
    144     SHARED_REQUIRES(Locks::mutator_lock_);
    145 
    146 // Fast path field resolution that can't initialize classes or throw exceptions.
    147 inline ArtField* FindFieldFast(
    148     uint32_t field_idx, ArtMethod* referrer, FindFieldType type, size_t expected_size)
    149     SHARED_REQUIRES(Locks::mutator_lock_);
    150 
    151 // Fast path method resolution that can't throw exceptions.
    152 inline ArtMethod* FindMethodFast(
    153     uint32_t method_idx, mirror::Object* this_object, ArtMethod* referrer, bool access_check,
    154     InvokeType type)
    155     SHARED_REQUIRES(Locks::mutator_lock_);
    156 
    157 inline mirror::Class* ResolveVerifyAndClinit(
    158     uint32_t type_idx, ArtMethod* referrer, Thread* self, bool can_run_clinit, bool verify_access)
    159     SHARED_REQUIRES(Locks::mutator_lock_);
    160 
    161 inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, uint32_t string_idx)
    162     SHARED_REQUIRES(Locks::mutator_lock_);
    163 
    164 // TODO: annotalysis disabled as monitor semantics are maintained in Java code.
    165 inline void UnlockJniSynchronizedMethod(jobject locked, Thread* self)
    166     NO_THREAD_SAFETY_ANALYSIS;
    167 
    168 void CheckReferenceResult(mirror::Object* o, Thread* self)
    169     SHARED_REQUIRES(Locks::mutator_lock_);
    170 
    171 JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, const char* shorty,
    172                                     jobject rcvr_jobj, jobject interface_art_method_jobj,
    173                                     std::vector<jvalue>& args)
    174     SHARED_REQUIRES(Locks::mutator_lock_);
    175 
    176 bool FillArrayData(mirror::Object* obj, const Instruction::ArrayDataPayload* payload)
    177     SHARED_REQUIRES(Locks::mutator_lock_);
    178 
    179 template <typename INT_TYPE, typename FLOAT_TYPE>
    180 inline INT_TYPE art_float_to_integral(FLOAT_TYPE f);
    181 
    182 ArtMethod* GetCalleeSaveMethodCaller(ArtMethod** sp,
    183                                      Runtime::CalleeSaveType type,
    184                                      bool do_caller_check = false);
    185 
    186 }  // namespace art
    187 
    188 #endif  // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_
    189