Home | History | Annotate | Download | only in quick
      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 #include "callee_save_frame.h"
     18 #include "dex_file-inl.h"
     19 #include "entrypoints/entrypoint_utils.h"
     20 #include "mirror/art_field-inl.h"
     21 #include "mirror/art_method-inl.h"
     22 #include "mirror/class-inl.h"
     23 
     24 #include <stdint.h>
     25 
     26 namespace art {
     27 
     28 extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
     29                                            const mirror::ArtMethod* referrer,
     30                                            Thread* self, mirror::ArtMethod** sp)
     31     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     32   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
     33                                           sizeof(int32_t));
     34   if (LIKELY(field != NULL)) {
     35     return field->Get32(field->GetDeclaringClass());
     36   }
     37   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
     38   field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int32_t), true);
     39   if (LIKELY(field != NULL)) {
     40     return field->Get32(field->GetDeclaringClass());
     41   }
     42   return 0;  // Will throw exception by checking with Thread::Current
     43 }
     44 
     45 extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
     46                                            const mirror::ArtMethod* referrer,
     47                                            Thread* self, mirror::ArtMethod** sp)
     48     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     49   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
     50                                           sizeof(int64_t));
     51   if (LIKELY(field != NULL)) {
     52     return field->Get64(field->GetDeclaringClass());
     53   }
     54   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
     55   field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveRead, sizeof(int64_t), true);
     56   if (LIKELY(field != NULL)) {
     57     return field->Get64(field->GetDeclaringClass());
     58   }
     59   return 0;  // Will throw exception by checking with Thread::Current
     60 }
     61 
     62 extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
     63                                                    const mirror::ArtMethod* referrer,
     64                                                    Thread* self, mirror::ArtMethod** sp)
     65     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     66   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
     67                                        sizeof(mirror::Object*));
     68   if (LIKELY(field != NULL)) {
     69     return field->GetObj(field->GetDeclaringClass());
     70   }
     71   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
     72   field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(mirror::Object*),
     73                             true);
     74   if (LIKELY(field != NULL)) {
     75     return field->GetObj(field->GetDeclaringClass());
     76   }
     77   return NULL;  // Will throw exception by checking with Thread::Current
     78 }
     79 
     80 extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
     81                                              const mirror::ArtMethod* referrer, Thread* self,
     82                                              mirror::ArtMethod** sp)
     83     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     84   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
     85                                           sizeof(int32_t));
     86   if (LIKELY(field != NULL && obj != NULL)) {
     87     return field->Get32(obj);
     88   }
     89   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
     90   field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int32_t),
     91                             true);
     92   if (LIKELY(field != NULL)) {
     93     if (UNLIKELY(obj == NULL)) {
     94       ThrowLocation throw_location = self->GetCurrentLocationForThrow();
     95       ThrowNullPointerExceptionForFieldAccess(throw_location, field, true);
     96     } else {
     97       return field->Get32(obj);
     98     }
     99   }
    100   return 0;  // Will throw exception by checking with Thread::Current
    101 }
    102 
    103 extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
    104                                              const mirror::ArtMethod* referrer, Thread* self,
    105                                              mirror::ArtMethod** sp)
    106     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    107   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
    108                                           sizeof(int64_t));
    109   if (LIKELY(field != NULL && obj != NULL)) {
    110     return field->Get64(obj);
    111   }
    112   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
    113   field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveRead, sizeof(int64_t),
    114                             true);
    115   if (LIKELY(field != NULL)) {
    116     if (UNLIKELY(obj == NULL)) {
    117       ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    118       ThrowNullPointerExceptionForFieldAccess(throw_location, field, true);
    119     } else {
    120       return field->Get64(obj);
    121     }
    122   }
    123   return 0;  // Will throw exception by checking with Thread::Current
    124 }
    125 
    126 extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
    127                                                      const mirror::ArtMethod* referrer,
    128                                                      Thread* self,
    129                                                      mirror::ArtMethod** sp)
    130     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    131   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
    132                                           sizeof(mirror::Object*));
    133   if (LIKELY(field != NULL && obj != NULL)) {
    134     return field->GetObj(obj);
    135   }
    136   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
    137   field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(mirror::Object*),
    138                             true);
    139   if (LIKELY(field != NULL)) {
    140     if (UNLIKELY(obj == NULL)) {
    141       ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    142       ThrowNullPointerExceptionForFieldAccess(throw_location, field, true);
    143     } else {
    144       return field->GetObj(obj);
    145     }
    146   }
    147   return NULL;  // Will throw exception by checking with Thread::Current
    148 }
    149 
    150 extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
    151                                       const mirror::ArtMethod* referrer, Thread* self,
    152                                       mirror::ArtMethod** sp)
    153     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    154   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
    155                                           sizeof(int32_t));
    156   if (LIKELY(field != NULL)) {
    157     field->Set32(field->GetDeclaringClass(), new_value);
    158     return 0;  // success
    159   }
    160   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
    161   field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int32_t), true);
    162   if (LIKELY(field != NULL)) {
    163     field->Set32(field->GetDeclaringClass(), new_value);
    164     return 0;  // success
    165   }
    166   return -1;  // failure
    167 }
    168 
    169 extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::ArtMethod* referrer,
    170                                       uint64_t new_value, Thread* self, mirror::ArtMethod** sp)
    171     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    172   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
    173                                           sizeof(int64_t));
    174   if (LIKELY(field != NULL)) {
    175     field->Set64(field->GetDeclaringClass(), new_value);
    176     return 0;  // success
    177   }
    178   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
    179   field = FindFieldFromCode(field_idx, referrer, self, StaticPrimitiveWrite, sizeof(int64_t), true);
    180   if (LIKELY(field != NULL)) {
    181     field->Set64(field->GetDeclaringClass(), new_value);
    182     return 0;  // success
    183   }
    184   return -1;  // failure
    185 }
    186 
    187 extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
    188                                        const mirror::ArtMethod* referrer, Thread* self,
    189                                        mirror::ArtMethod** sp)
    190     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    191   mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
    192                                           sizeof(mirror::Object*));
    193   if (LIKELY(field != NULL)) {
    194     if (LIKELY(!FieldHelper(field).IsPrimitiveType())) {
    195       field->SetObj(field->GetDeclaringClass(), new_value);
    196       return 0;  // success
    197     }
    198   }
    199   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
    200   field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(mirror::Object*), true);
    201   if (LIKELY(field != NULL)) {
    202     field->SetObj(field->GetDeclaringClass(), new_value);
    203     return 0;  // success
    204   }
    205   return -1;  // failure
    206 }
    207 
    208 extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
    209                                         const mirror::ArtMethod* referrer, Thread* self,
    210                                         mirror::ArtMethod** sp)
    211     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    212   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
    213                                           sizeof(int32_t));
    214   if (LIKELY(field != NULL && obj != NULL)) {
    215     field->Set32(obj, new_value);
    216     return 0;  // success
    217   }
    218   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
    219   field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int32_t),
    220                             true);
    221   if (LIKELY(field != NULL)) {
    222     if (UNLIKELY(obj == NULL)) {
    223       ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    224       ThrowNullPointerExceptionForFieldAccess(throw_location, field, false);
    225     } else {
    226       field->Set32(obj, new_value);
    227       return 0;  // success
    228     }
    229   }
    230   return -1;  // failure
    231 }
    232 
    233 extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value,
    234                                         Thread* self, mirror::ArtMethod** sp)
    235     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    236   mirror::ArtMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly);
    237   mirror::ArtMethod* referrer =
    238       sp[callee_save->GetFrameSizeInBytes() / sizeof(mirror::ArtMethod*)];
    239   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
    240                                           sizeof(int64_t));
    241   if (LIKELY(field != NULL  && obj != NULL)) {
    242     field->Set64(obj, new_value);
    243     return 0;  // success
    244   }
    245   *sp = callee_save;
    246   self->SetTopOfStack(sp, 0);
    247   field = FindFieldFromCode(field_idx, referrer, self, InstancePrimitiveWrite, sizeof(int64_t),
    248                             true);
    249   if (LIKELY(field != NULL)) {
    250     if (UNLIKELY(obj == NULL)) {
    251       ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    252       ThrowNullPointerExceptionForFieldAccess(throw_location, field, false);
    253     } else {
    254       field->Set64(obj, new_value);
    255       return 0;  // success
    256     }
    257   }
    258   return -1;  // failure
    259 }
    260 
    261 extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
    262                                          mirror::Object* new_value,
    263                                          const mirror::ArtMethod* referrer, Thread* self,
    264                                          mirror::ArtMethod** sp)
    265     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    266   mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
    267                                           sizeof(mirror::Object*));
    268   if (LIKELY(field != NULL && obj != NULL)) {
    269     field->SetObj(obj, new_value);
    270     return 0;  // success
    271   }
    272   FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
    273   field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite,
    274                             sizeof(mirror::Object*), true);
    275   if (LIKELY(field != NULL)) {
    276     if (UNLIKELY(obj == NULL)) {
    277       ThrowLocation throw_location = self->GetCurrentLocationForThrow();
    278       ThrowNullPointerExceptionForFieldAccess(throw_location, field, false);
    279     } else {
    280       field->SetObj(obj, new_value);
    281       return 0;  // success
    282     }
    283   }
    284   return -1;  // failure
    285 }
    286 
    287 }  // namespace art
    288