Home | History | Annotate | Download | only in mirror
      1 /*
      2  * Copyright (C) 2017 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 "var_handle.h"
     18 
     19 #include "array-inl.h"
     20 #include "art_field-inl.h"
     21 #include "base/casts.h"
     22 #include "class-inl.h"
     23 #include "class_linker.h"
     24 #include "class_root.h"
     25 #include "intrinsics_enum.h"
     26 #include "jni/jni_internal.h"
     27 #include "jvalue-inl.h"
     28 #include "method_handles-inl.h"
     29 #include "method_type-inl.h"
     30 #include "object_array-alloc-inl.h"
     31 #include "obj_ptr-inl.h"
     32 #include "well_known_classes.h"
     33 
     34 namespace art {
     35 namespace mirror {
     36 
     37 static constexpr bool kTransactionActive = true;
     38 static constexpr bool kTransactionInactive = !kTransactionActive;
     39 
     40 namespace {
     41 
     42 struct VarHandleAccessorToAccessModeEntry {
     43   const char* method_name;
     44   VarHandle::AccessMode access_mode;
     45 
     46   // Binary predicate function for finding access_mode by
     47   // method_name. The access_mode field is ignored.
     48   static bool CompareName(const VarHandleAccessorToAccessModeEntry& lhs,
     49                           const VarHandleAccessorToAccessModeEntry& rhs) {
     50     return strcmp(lhs.method_name, rhs.method_name) < 0;
     51   }
     52 };
     53 
     54 // Map of VarHandle accessor method names to access mode values. The list is alpha-sorted to support
     55 // binary search. For the usage scenario - lookups in the verifier - a linear scan would likely
     56 // suffice since we expect VarHandles to be a lesser encountered class. We could use a std::hashmap
     57 // here and this would be easier to maintain if new values are added here. However, this entails
     58 // CPU cycles initializing the structure on every execution and uses O(N) more memory for
     59 // intermediate nodes and makes that memory dirty. Compile-time magic using constexpr is possible
     60 // here, but that's a tax when this code is recompiled.
     61 const VarHandleAccessorToAccessModeEntry kAccessorToAccessMode[VarHandle::kNumberOfAccessModes] = {
     62   { "compareAndExchange", VarHandle::AccessMode::kCompareAndExchange },
     63   { "compareAndExchangeAcquire", VarHandle::AccessMode::kCompareAndExchangeAcquire },
     64   { "compareAndExchangeRelease", VarHandle::AccessMode::kCompareAndExchangeRelease },
     65   { "compareAndSet", VarHandle::AccessMode::kCompareAndSet },
     66   { "get", VarHandle::AccessMode::kGet },
     67   { "getAcquire", VarHandle::AccessMode::kGetAcquire },
     68   { "getAndAdd", VarHandle::AccessMode::kGetAndAdd },
     69   { "getAndAddAcquire", VarHandle::AccessMode::kGetAndAddAcquire },
     70   { "getAndAddRelease", VarHandle::AccessMode::kGetAndAddRelease },
     71   { "getAndBitwiseAnd", VarHandle::AccessMode::kGetAndBitwiseAnd },
     72   { "getAndBitwiseAndAcquire", VarHandle::AccessMode::kGetAndBitwiseAndAcquire },
     73   { "getAndBitwiseAndRelease", VarHandle::AccessMode::kGetAndBitwiseAndRelease },
     74   { "getAndBitwiseOr", VarHandle::AccessMode::kGetAndBitwiseOr },
     75   { "getAndBitwiseOrAcquire", VarHandle::AccessMode::kGetAndBitwiseOrAcquire },
     76   { "getAndBitwiseOrRelease", VarHandle::AccessMode::kGetAndBitwiseOrRelease },
     77   { "getAndBitwiseXor", VarHandle::AccessMode::kGetAndBitwiseXor },
     78   { "getAndBitwiseXorAcquire", VarHandle::AccessMode::kGetAndBitwiseXorAcquire },
     79   { "getAndBitwiseXorRelease", VarHandle::AccessMode::kGetAndBitwiseXorRelease },
     80   { "getAndSet", VarHandle::AccessMode::kGetAndSet },
     81   { "getAndSetAcquire", VarHandle::AccessMode::kGetAndSetAcquire },
     82   { "getAndSetRelease", VarHandle::AccessMode::kGetAndSetRelease },
     83   { "getOpaque", VarHandle::AccessMode::kGetOpaque },
     84   { "getVolatile", VarHandle::AccessMode::kGetVolatile },
     85   { "set", VarHandle::AccessMode::kSet },
     86   { "setOpaque", VarHandle::AccessMode::kSetOpaque },
     87   { "setRelease", VarHandle::AccessMode::kSetRelease },
     88   { "setVolatile", VarHandle::AccessMode::kSetVolatile },
     89   { "weakCompareAndSet", VarHandle::AccessMode::kWeakCompareAndSet },
     90   { "weakCompareAndSetAcquire", VarHandle::AccessMode::kWeakCompareAndSetAcquire },
     91   { "weakCompareAndSetPlain", VarHandle::AccessMode::kWeakCompareAndSetPlain },
     92   { "weakCompareAndSetRelease", VarHandle::AccessMode::kWeakCompareAndSetRelease },
     93 };
     94 
     95 // Enumeration for describing the parameter and return types of an AccessMode.
     96 enum class AccessModeTemplate : uint32_t {
     97   kGet,                 // T Op(C0..CN)
     98   kSet,                 // void Op(C0..CN, T)
     99   kCompareAndSet,       // boolean Op(C0..CN, T, T)
    100   kCompareAndExchange,  // T Op(C0..CN, T, T)
    101   kGetAndUpdate,        // T Op(C0..CN, T)
    102 };
    103 
    104 // Look up the AccessModeTemplate for a given VarHandle
    105 // AccessMode. This simplifies finding the correct signature for a
    106 // VarHandle accessor method.
    107 AccessModeTemplate GetAccessModeTemplate(VarHandle::AccessMode access_mode) {
    108   switch (access_mode) {
    109     case VarHandle::AccessMode::kGet:
    110       return AccessModeTemplate::kGet;
    111     case VarHandle::AccessMode::kSet:
    112       return AccessModeTemplate::kSet;
    113     case VarHandle::AccessMode::kGetVolatile:
    114       return AccessModeTemplate::kGet;
    115     case VarHandle::AccessMode::kSetVolatile:
    116       return AccessModeTemplate::kSet;
    117     case VarHandle::AccessMode::kGetAcquire:
    118       return AccessModeTemplate::kGet;
    119     case VarHandle::AccessMode::kSetRelease:
    120       return AccessModeTemplate::kSet;
    121     case VarHandle::AccessMode::kGetOpaque:
    122       return AccessModeTemplate::kGet;
    123     case VarHandle::AccessMode::kSetOpaque:
    124       return AccessModeTemplate::kSet;
    125     case VarHandle::AccessMode::kCompareAndSet:
    126       return AccessModeTemplate::kCompareAndSet;
    127     case VarHandle::AccessMode::kCompareAndExchange:
    128       return AccessModeTemplate::kCompareAndExchange;
    129     case VarHandle::AccessMode::kCompareAndExchangeAcquire:
    130       return AccessModeTemplate::kCompareAndExchange;
    131     case VarHandle::AccessMode::kCompareAndExchangeRelease:
    132       return AccessModeTemplate::kCompareAndExchange;
    133     case VarHandle::AccessMode::kWeakCompareAndSetPlain:
    134       return AccessModeTemplate::kCompareAndSet;
    135     case VarHandle::AccessMode::kWeakCompareAndSet:
    136       return AccessModeTemplate::kCompareAndSet;
    137     case VarHandle::AccessMode::kWeakCompareAndSetAcquire:
    138       return AccessModeTemplate::kCompareAndSet;
    139     case VarHandle::AccessMode::kWeakCompareAndSetRelease:
    140       return AccessModeTemplate::kCompareAndSet;
    141     case VarHandle::AccessMode::kGetAndSet:
    142       return AccessModeTemplate::kGetAndUpdate;
    143     case VarHandle::AccessMode::kGetAndSetAcquire:
    144       return AccessModeTemplate::kGetAndUpdate;
    145     case VarHandle::AccessMode::kGetAndSetRelease:
    146       return AccessModeTemplate::kGetAndUpdate;
    147     case VarHandle::AccessMode::kGetAndAdd:
    148       return AccessModeTemplate::kGetAndUpdate;
    149     case VarHandle::AccessMode::kGetAndAddAcquire:
    150       return AccessModeTemplate::kGetAndUpdate;
    151     case VarHandle::AccessMode::kGetAndAddRelease:
    152       return AccessModeTemplate::kGetAndUpdate;
    153     case VarHandle::AccessMode::kGetAndBitwiseOr:
    154       return AccessModeTemplate::kGetAndUpdate;
    155     case VarHandle::AccessMode::kGetAndBitwiseOrRelease:
    156       return AccessModeTemplate::kGetAndUpdate;
    157     case VarHandle::AccessMode::kGetAndBitwiseOrAcquire:
    158       return AccessModeTemplate::kGetAndUpdate;
    159     case VarHandle::AccessMode::kGetAndBitwiseAnd:
    160       return AccessModeTemplate::kGetAndUpdate;
    161     case VarHandle::AccessMode::kGetAndBitwiseAndRelease:
    162       return AccessModeTemplate::kGetAndUpdate;
    163     case VarHandle::AccessMode::kGetAndBitwiseAndAcquire:
    164       return AccessModeTemplate::kGetAndUpdate;
    165     case VarHandle::AccessMode::kGetAndBitwiseXor:
    166       return AccessModeTemplate::kGetAndUpdate;
    167     case VarHandle::AccessMode::kGetAndBitwiseXorRelease:
    168       return AccessModeTemplate::kGetAndUpdate;
    169     case VarHandle::AccessMode::kGetAndBitwiseXorAcquire:
    170       return AccessModeTemplate::kGetAndUpdate;
    171   }
    172 }
    173 
    174 int32_t GetNumberOfVarTypeParameters(AccessModeTemplate access_mode_template) {
    175   switch (access_mode_template) {
    176     case AccessModeTemplate::kGet:
    177       return 0;
    178     case AccessModeTemplate::kSet:
    179     case AccessModeTemplate::kGetAndUpdate:
    180       return 1;
    181     case AccessModeTemplate::kCompareAndSet:
    182     case AccessModeTemplate::kCompareAndExchange:
    183       return 2;
    184   }
    185   UNREACHABLE();
    186 }
    187 
    188 // Returns the number of parameters associated with an
    189 // AccessModeTemplate and the supplied coordinate types.
    190 int32_t GetNumberOfParameters(AccessModeTemplate access_mode_template,
    191                               ObjPtr<Class> coordinateType0,
    192                               ObjPtr<Class> coordinateType1) {
    193   int32_t count = 0;
    194   if (!coordinateType0.IsNull()) {
    195     count++;
    196     if (!coordinateType1.IsNull()) {
    197       count++;
    198     }
    199   }
    200   return count + GetNumberOfVarTypeParameters(access_mode_template);
    201 }
    202 
    203 void ThrowNullPointerExceptionForCoordinate() REQUIRES_SHARED(Locks::mutator_lock_) {
    204   ThrowNullPointerException("Attempt to access memory on a null object");
    205 }
    206 
    207 bool CheckElementIndex(Primitive::Type type,
    208                        int32_t relative_index,
    209                        int32_t start,
    210                        int32_t limit) REQUIRES_SHARED(Locks::mutator_lock_) {
    211   int64_t index = start + relative_index;
    212   int64_t max_index = limit - Primitive::ComponentSize(type);
    213   if (index < start || index > max_index) {
    214     ThrowIndexOutOfBoundsException(index, limit - start);
    215     return false;
    216   }
    217   return true;
    218 }
    219 
    220 bool CheckElementIndex(Primitive::Type type, int32_t index, int32_t range_limit)
    221     REQUIRES_SHARED(Locks::mutator_lock_) {
    222   return CheckElementIndex(type, index, 0, range_limit);
    223 }
    224 
    225 // Returns true if access_mode only entails a memory read. False if
    226 // access_mode may write to memory.
    227 bool IsReadOnlyAccessMode(VarHandle::AccessMode access_mode) {
    228   AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode);
    229   return access_mode_template == AccessModeTemplate::kGet;
    230 }
    231 
    232 // Writes the parameter types associated with the AccessModeTemplate
    233 // into an array. The parameter types are derived from the specified
    234 // variable type and coordinate types. Returns the number of
    235 // parameters written.
    236 int32_t BuildParameterArray(ObjPtr<Class> (&parameters)[VarHandle::kMaxAccessorParameters],
    237                             AccessModeTemplate access_mode_template,
    238                             ObjPtr<Class> varType,
    239                             ObjPtr<Class> coordinateType0,
    240                             ObjPtr<Class> coordinateType1)
    241     REQUIRES_SHARED(Locks::mutator_lock_) {
    242   DCHECK(varType != nullptr);
    243   int32_t index = 0;
    244   if (!coordinateType0.IsNull()) {
    245     parameters[index++] = coordinateType0;
    246     if (!coordinateType1.IsNull()) {
    247       parameters[index++] = coordinateType1;
    248     }
    249   } else {
    250     DCHECK(coordinateType1.IsNull());
    251   }
    252 
    253   switch (access_mode_template) {
    254     case AccessModeTemplate::kCompareAndExchange:
    255     case AccessModeTemplate::kCompareAndSet:
    256       parameters[index++] = varType;
    257       parameters[index++] = varType;
    258       return index;
    259     case AccessModeTemplate::kGet:
    260       return index;
    261     case AccessModeTemplate::kGetAndUpdate:
    262     case AccessModeTemplate::kSet:
    263       parameters[index++] = varType;
    264       return index;
    265   }
    266   return -1;
    267 }
    268 
    269 // Returns the return type associated with an AccessModeTemplate based
    270 // on the template and the variable type specified.
    271 static ObjPtr<Class> GetReturnType(AccessModeTemplate access_mode_template, ObjPtr<Class> varType)
    272     REQUIRES_SHARED(Locks::mutator_lock_) {
    273   DCHECK(varType != nullptr);
    274   switch (access_mode_template) {
    275     case AccessModeTemplate::kCompareAndSet:
    276       return GetClassRoot(ClassRoot::kPrimitiveBoolean);
    277     case AccessModeTemplate::kCompareAndExchange:
    278     case AccessModeTemplate::kGet:
    279     case AccessModeTemplate::kGetAndUpdate:
    280       return varType;
    281     case AccessModeTemplate::kSet:
    282       return GetClassRoot(ClassRoot::kPrimitiveVoid);
    283   }
    284   return nullptr;
    285 }
    286 
    287 // Method to insert a read barrier for accessors to reference fields.
    288 inline void ReadBarrierForVarHandleAccess(ObjPtr<Object> obj, MemberOffset field_offset)
    289     REQUIRES_SHARED(Locks::mutator_lock_) {
    290   if (kUseReadBarrier) {
    291     // We need to ensure that the reference stored in the field is a to-space one before attempting
    292     // the CompareAndSet/CompareAndExchange/Exchange operation otherwise it will fail incorrectly
    293     // if obj is in the process of being moved.
    294     uint8_t* raw_field_addr = reinterpret_cast<uint8_t*>(obj.Ptr()) + field_offset.SizeValue();
    295     auto field_addr = reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_field_addr);
    296     // Note that the read barrier load does NOT need to be volatile.
    297     static constexpr bool kIsVolatile = false;
    298     static constexpr bool kAlwaysUpdateField = true;
    299     ReadBarrier::Barrier<mirror::Object, kIsVolatile, kWithReadBarrier, kAlwaysUpdateField>(
    300         obj.Ptr(),
    301         MemberOffset(field_offset),
    302         field_addr);
    303   }
    304 }
    305 
    306 inline MemberOffset GetMemberOffset(jfieldID field_id) REQUIRES_SHARED(Locks::mutator_lock_) {
    307   ArtField* const field = jni::DecodeArtField(field_id);
    308   return field->GetOffset();
    309 }
    310 
    311 //
    312 // Helper methods for storing results from atomic operations into
    313 // JValue instances.
    314 //
    315 
    316 inline void StoreResult(uint8_t value, JValue* result) {
    317   result->SetZ(value);
    318 }
    319 
    320 inline void StoreResult(int8_t value, JValue* result) {
    321   result->SetB(value);
    322 }
    323 
    324 inline void StoreResult(uint16_t value, JValue* result) {
    325   result->SetC(value);
    326 }
    327 
    328 inline void StoreResult(int16_t value, JValue* result) {
    329   result->SetS(value);
    330 }
    331 
    332 inline void StoreResult(int32_t value, JValue* result) {
    333   result->SetI(value);
    334 }
    335 
    336 inline void StoreResult(int64_t value, JValue* result) {
    337   result->SetJ(value);
    338 }
    339 
    340 inline void StoreResult(float value, JValue* result) {
    341   result->SetF(value);
    342 }
    343 
    344 inline void StoreResult(double value, JValue* result) {
    345   result->SetD(value);
    346 }
    347 
    348 inline void StoreResult(ObjPtr<Object> value, JValue* result)
    349     REQUIRES_SHARED(Locks::mutator_lock_) {
    350   result->SetL(value);
    351 }
    352 
    353 //
    354 // Helper class for byte-swapping value that has been stored in a JValue.
    355 //
    356 
    357 template <typename T>
    358 class JValueByteSwapper final {
    359  public:
    360   static void ByteSwap(JValue* value);
    361   static void MaybeByteSwap(bool byte_swap, JValue* value) {
    362     if (byte_swap) {
    363       ByteSwap(value);
    364     }
    365   }
    366 };
    367 
    368 template <>
    369 void JValueByteSwapper<uint16_t>::ByteSwap(JValue* value) {
    370   value->SetC(BSWAP(value->GetC()));
    371 }
    372 
    373 template <>
    374 void JValueByteSwapper<int16_t>::ByteSwap(JValue* value) {
    375   value->SetS(BSWAP(value->GetS()));
    376 }
    377 
    378 template <>
    379 void JValueByteSwapper<int32_t>::ByteSwap(JValue* value) {
    380   value->SetI(BSWAP(value->GetI()));
    381 }
    382 
    383 template <>
    384 void JValueByteSwapper<int64_t>::ByteSwap(JValue* value) {
    385   value->SetJ(BSWAP(value->GetJ()));
    386 }
    387 
    388 //
    389 // Accessor implementations, shared across all VarHandle types.
    390 //
    391 
    392 template <typename T, std::memory_order MO>
    393 class AtomicGetAccessor : public Object::Accessor<T> {
    394  public:
    395   explicit AtomicGetAccessor(JValue* result) : result_(result) {}
    396 
    397   void Access(T* addr) override {
    398     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    399     StoreResult(atom->load(MO), result_);
    400   }
    401 
    402  private:
    403   JValue* result_;
    404 };
    405 
    406 template <typename T, std::memory_order MO>
    407 class AtomicSetAccessor : public Object::Accessor<T> {
    408  public:
    409   explicit AtomicSetAccessor(T new_value) : new_value_(new_value) {}
    410 
    411   void Access(T* addr) override {
    412     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    413     atom->store(new_value_, MO);
    414   }
    415 
    416  private:
    417   T new_value_;
    418 };
    419 
    420 template <typename T> using GetAccessor = AtomicGetAccessor<T, std::memory_order_relaxed>;
    421 
    422 template <typename T> using SetAccessor = AtomicSetAccessor<T, std::memory_order_relaxed>;
    423 
    424 template <typename T>
    425 using GetVolatileAccessor = AtomicGetAccessor<T, std::memory_order_seq_cst>;
    426 
    427 template <typename T>
    428 using SetVolatileAccessor = AtomicSetAccessor<T, std::memory_order_seq_cst>;
    429 
    430 template <typename T, std::memory_order MOS, std::memory_order MOF>
    431 class AtomicStrongCompareAndSetAccessor : public Object::Accessor<T> {
    432  public:
    433   AtomicStrongCompareAndSetAccessor(T expected_value, T desired_value, JValue* result)
    434       : expected_value_(expected_value), desired_value_(desired_value), result_(result) {}
    435 
    436   void Access(T* addr) override {
    437     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    438     bool success = atom->compare_exchange_strong(expected_value_, desired_value_, MOS, MOF);
    439     StoreResult(success ? JNI_TRUE : JNI_FALSE, result_);
    440   }
    441 
    442  private:
    443   T expected_value_;
    444   T desired_value_;
    445   JValue* result_;
    446 };
    447 
    448 template<typename T>
    449 using CompareAndSetAccessor =
    450     AtomicStrongCompareAndSetAccessor<T, std::memory_order_seq_cst, std::memory_order_seq_cst>;
    451 
    452 template <typename T, std::memory_order MOS, std::memory_order MOF>
    453 class AtomicStrongCompareAndExchangeAccessor : public Object::Accessor<T> {
    454  public:
    455   AtomicStrongCompareAndExchangeAccessor(T expected_value, T desired_value, JValue* result)
    456       : expected_value_(expected_value), desired_value_(desired_value), result_(result) {}
    457 
    458   void Access(T* addr) override {
    459     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    460     atom->compare_exchange_strong(expected_value_, desired_value_, MOS, MOF);
    461     StoreResult(expected_value_, result_);
    462   }
    463 
    464  private:
    465   T expected_value_;
    466   T desired_value_;
    467   JValue* result_;
    468 };
    469 
    470 template <typename T>
    471 using CompareAndExchangeAccessor =
    472     AtomicStrongCompareAndExchangeAccessor<T, std::memory_order_seq_cst, std::memory_order_seq_cst>;
    473 
    474 template <typename T, std::memory_order MOS, std::memory_order MOF>
    475 class AtomicWeakCompareAndSetAccessor : public Object::Accessor<T> {
    476  public:
    477   AtomicWeakCompareAndSetAccessor(T expected_value, T desired_value, JValue* result)
    478       : expected_value_(expected_value), desired_value_(desired_value), result_(result) {}
    479 
    480   void Access(T* addr) override {
    481     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    482     bool success = atom->compare_exchange_weak(expected_value_, desired_value_, MOS, MOF);
    483     StoreResult(success ? JNI_TRUE : JNI_FALSE, result_);
    484   }
    485 
    486  private:
    487   T expected_value_;
    488   T desired_value_;
    489   JValue* result_;
    490 };
    491 
    492 template <typename T>
    493 using WeakCompareAndSetAccessor =
    494     AtomicWeakCompareAndSetAccessor<T, std::memory_order_seq_cst, std::memory_order_seq_cst>;
    495 
    496 template <typename T, std::memory_order MO>
    497 class AtomicGetAndSetAccessor : public Object::Accessor<T> {
    498  public:
    499   AtomicGetAndSetAccessor(T new_value, JValue* result) : new_value_(new_value), result_(result) {}
    500 
    501   void Access(T* addr) override {
    502     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    503     T old_value = atom->exchange(new_value_, MO);
    504     StoreResult(old_value, result_);
    505   }
    506 
    507  private:
    508   T new_value_;
    509   JValue* result_;
    510 };
    511 
    512 template <typename T>
    513 using GetAndSetAccessor = AtomicGetAndSetAccessor<T, std::memory_order_seq_cst>;
    514 
    515 template <typename T, bool kIsFloat, std::memory_order MO>
    516 class AtomicGetAndAddOperator {
    517  public:
    518   static T Apply(T* addr, T addend) {
    519     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    520     return atom->fetch_add(addend, MO);
    521   }
    522 };
    523 
    524 template <typename T, std::memory_order MO>
    525 class AtomicGetAndAddOperator<T, /* kIsFloat */ true, MO> {
    526  public:
    527   static T Apply(T* addr, T addend) {
    528     // c++11 does not have std::atomic<T>::fetch_and_add for floating
    529     // point types, so we effect one with a compare and swap.
    530     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    531     T old_value = atom->load(std::memory_order_relaxed);
    532     T new_value;
    533     do {
    534       new_value = old_value + addend;
    535     } while (!atom->compare_exchange_weak(old_value, new_value, MO, std::memory_order_relaxed));
    536     return old_value;
    537   }
    538 };
    539 
    540 template <typename T, std::memory_order MO>
    541 class AtomicGetAndAddAccessor : public Object::Accessor<T> {
    542  public:
    543   AtomicGetAndAddAccessor(T addend, JValue* result) : addend_(addend), result_(result) {}
    544 
    545   void Access(T* addr) override {
    546     constexpr bool kIsFloatingPoint = std::is_floating_point<T>::value;
    547     T old_value = AtomicGetAndAddOperator<T, kIsFloatingPoint, MO>::Apply(addr, addend_);
    548     StoreResult(old_value, result_);
    549   }
    550 
    551  private:
    552   T addend_;
    553   JValue* result_;
    554 };
    555 
    556 template <typename T>
    557 using GetAndAddAccessor = AtomicGetAndAddAccessor<T, std::memory_order_seq_cst>;
    558 
    559 // Accessor specifically for memory views where the caller can specify
    560 // the byte-ordering. Addition only works outside of the byte-swapped
    561 // memory view because of the direction of carries.
    562 template <typename T, std::memory_order MO>
    563 class AtomicGetAndAddWithByteSwapAccessor : public Object::Accessor<T> {
    564  public:
    565   AtomicGetAndAddWithByteSwapAccessor(T value, JValue* result) : value_(value), result_(result) {}
    566 
    567   void Access(T* addr) override {
    568     std::atomic<T>* const atom = reinterpret_cast<std::atomic<T>*>(addr);
    569     T current_value = atom->load(std::memory_order_relaxed);
    570     T sum;
    571     do {
    572       sum = BSWAP(current_value) + value_;
    573       // NB current_value is a pass-by-reference argument in the call to
    574       // atomic<T>::compare_exchange_weak().
    575     } while (!atom->compare_exchange_weak(current_value,
    576                                           BSWAP(sum),
    577                                           MO,
    578                                           std::memory_order_relaxed));
    579     StoreResult(BSWAP(current_value), result_);
    580   }
    581 
    582  private:
    583   T value_;
    584   JValue* result_;
    585 };
    586 
    587 template <typename T>
    588 using GetAndAddWithByteSwapAccessor =
    589     AtomicGetAndAddWithByteSwapAccessor<T, std::memory_order_seq_cst>;
    590 
    591 template <typename T, std::memory_order MO>
    592 class AtomicGetAndBitwiseOrAccessor : public Object::Accessor<T> {
    593  public:
    594   AtomicGetAndBitwiseOrAccessor(T value, JValue* result) : value_(value), result_(result) {}
    595 
    596   void Access(T* addr) override {
    597     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    598     T old_value = atom->fetch_or(value_, MO);
    599     StoreResult(old_value, result_);
    600   }
    601 
    602  private:
    603   T value_;
    604   JValue* result_;
    605 };
    606 
    607 template <typename T>
    608 using GetAndBitwiseOrAccessor = AtomicGetAndBitwiseOrAccessor<T, std::memory_order_seq_cst>;
    609 
    610 template <typename T, std::memory_order MO>
    611 class AtomicGetAndBitwiseAndAccessor : public Object::Accessor<T> {
    612  public:
    613   AtomicGetAndBitwiseAndAccessor(T value, JValue* result) : value_(value), result_(result) {}
    614 
    615   void Access(T* addr) override {
    616     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    617     T old_value = atom->fetch_and(value_, MO);
    618     StoreResult(old_value, result_);
    619   }
    620 
    621  private:
    622   T value_;
    623   JValue* result_;
    624 };
    625 
    626 template <typename T>
    627 using GetAndBitwiseAndAccessor =
    628     AtomicGetAndBitwiseAndAccessor<T, std::memory_order_seq_cst>;
    629 
    630 template <typename T, std::memory_order MO>
    631 class AtomicGetAndBitwiseXorAccessor : public Object::Accessor<T> {
    632  public:
    633   AtomicGetAndBitwiseXorAccessor(T value, JValue* result) : value_(value), result_(result) {}
    634 
    635   void Access(T* addr) override {
    636     std::atomic<T>* atom = reinterpret_cast<std::atomic<T>*>(addr);
    637     T old_value = atom->fetch_xor(value_, MO);
    638     StoreResult(old_value, result_);
    639   }
    640 
    641  private:
    642   T value_;
    643   JValue* result_;
    644 };
    645 
    646 template <typename T>
    647 using GetAndBitwiseXorAccessor = AtomicGetAndBitwiseXorAccessor<T, std::memory_order_seq_cst>;
    648 
    649 //
    650 // Unreachable access modes.
    651 //
    652 
    653 NO_RETURN void UnreachableAccessMode(const char* access_mode, const char* type_name) {
    654   LOG(FATAL) << "Unreachable access mode :" << access_mode << " for type " << type_name;
    655   UNREACHABLE();
    656 }
    657 
    658 #define UNREACHABLE_ACCESS_MODE(ACCESS_MODE, TYPE)             \
    659 template<> void ACCESS_MODE ## Accessor<TYPE>::Access(TYPE*) { \
    660   UnreachableAccessMode(#ACCESS_MODE, #TYPE);                  \
    661 }
    662 
    663 // The boolean primitive type is not numeric (boolean == std::uint8_t).
    664 UNREACHABLE_ACCESS_MODE(GetAndAdd, uint8_t)
    665 
    666 // The floating point types do not support bitwise operations.
    667 UNREACHABLE_ACCESS_MODE(GetAndBitwiseOr, float)
    668 UNREACHABLE_ACCESS_MODE(GetAndBitwiseAnd, float)
    669 UNREACHABLE_ACCESS_MODE(GetAndBitwiseXor, float)
    670 UNREACHABLE_ACCESS_MODE(GetAndBitwiseOr, double)
    671 UNREACHABLE_ACCESS_MODE(GetAndBitwiseAnd, double)
    672 UNREACHABLE_ACCESS_MODE(GetAndBitwiseXor, double)
    673 
    674 // A helper class for object field accesses for floats and
    675 // doubles. The object interface deals with Field32 and Field64. The
    676 // former is used for both integers and floats, the latter for longs
    677 // and doubles. This class provides the necessary coercion.
    678 template <typename T, typename U>
    679 class TypeAdaptorAccessor : public Object::Accessor<T> {
    680  public:
    681   explicit TypeAdaptorAccessor(Object::Accessor<U>* inner_accessor)
    682       : inner_accessor_(inner_accessor) {}
    683 
    684   void Access(T* addr) override {
    685     static_assert(sizeof(T) == sizeof(U), "bad conversion");
    686     inner_accessor_->Access(reinterpret_cast<U*>(addr));
    687   }
    688 
    689  private:
    690   Object::Accessor<U>* inner_accessor_;
    691 };
    692 
    693 template <typename T>
    694 class FieldAccessViaAccessor {
    695  public:
    696   using Accessor = Object::Accessor<T>;
    697 
    698   // Apply an Accessor to get a field in an object.
    699   static void Get(ObjPtr<Object> obj,
    700                   MemberOffset field_offset,
    701                   Accessor* accessor)
    702       REQUIRES_SHARED(Locks::mutator_lock_) {
    703     obj->GetPrimitiveFieldViaAccessor(field_offset, accessor);
    704   }
    705 
    706   // Apply an Accessor to update a field in an object.
    707   static void Update(ObjPtr<Object> obj,
    708                      MemberOffset field_offset,
    709                      Accessor* accessor)
    710       REQUIRES_SHARED(Locks::mutator_lock_);
    711 };
    712 
    713 template <>
    714 inline void FieldAccessViaAccessor<float>::Get(ObjPtr<Object> obj,
    715                                                MemberOffset field_offset,
    716                                                Accessor* accessor)
    717     REQUIRES_SHARED(Locks::mutator_lock_) {
    718   TypeAdaptorAccessor<int32_t, float> float_to_int_accessor(accessor);
    719   obj->GetPrimitiveFieldViaAccessor(field_offset, &float_to_int_accessor);
    720 }
    721 
    722 template <>
    723 inline void FieldAccessViaAccessor<double>::Get(ObjPtr<Object> obj,
    724                                                 MemberOffset field_offset,
    725                                                 Accessor* accessor)
    726     REQUIRES_SHARED(Locks::mutator_lock_) {
    727   TypeAdaptorAccessor<int64_t, double> double_to_int_accessor(accessor);
    728   obj->GetPrimitiveFieldViaAccessor(field_offset, &double_to_int_accessor);
    729 }
    730 
    731 template <>
    732 void FieldAccessViaAccessor<uint8_t>::Update(ObjPtr<Object> obj,
    733                                              MemberOffset field_offset,
    734                                              Accessor* accessor)
    735     REQUIRES_SHARED(Locks::mutator_lock_) {
    736   if (Runtime::Current()->IsActiveTransaction()) {
    737     obj->UpdateFieldBooleanViaAccessor<kTransactionActive>(field_offset, accessor);
    738   } else {
    739     obj->UpdateFieldBooleanViaAccessor<kTransactionInactive>(field_offset, accessor);
    740   }
    741 }
    742 
    743 template <>
    744 void FieldAccessViaAccessor<int8_t>::Update(ObjPtr<Object> obj,
    745                                             MemberOffset field_offset,
    746                                             Accessor* accessor)
    747     REQUIRES_SHARED(Locks::mutator_lock_) {
    748   if (Runtime::Current()->IsActiveTransaction()) {
    749     obj->UpdateFieldByteViaAccessor<kTransactionActive>(field_offset, accessor);
    750   } else {
    751     obj->UpdateFieldByteViaAccessor<kTransactionInactive>(field_offset, accessor);
    752   }
    753 }
    754 
    755 template <>
    756 void FieldAccessViaAccessor<uint16_t>::Update(ObjPtr<Object> obj,
    757                                               MemberOffset field_offset,
    758                                               Accessor* accessor)
    759     REQUIRES_SHARED(Locks::mutator_lock_) {
    760   if (Runtime::Current()->IsActiveTransaction()) {
    761     obj->UpdateFieldCharViaAccessor<kTransactionActive>(field_offset, accessor);
    762   } else {
    763     obj->UpdateFieldCharViaAccessor<kTransactionInactive>(field_offset, accessor);
    764   }
    765 }
    766 
    767 template <>
    768 void FieldAccessViaAccessor<int16_t>::Update(ObjPtr<Object> obj,
    769                                               MemberOffset field_offset,
    770                                               Accessor* accessor)
    771     REQUIRES_SHARED(Locks::mutator_lock_) {
    772   if (Runtime::Current()->IsActiveTransaction()) {
    773     obj->UpdateFieldShortViaAccessor<kTransactionActive>(field_offset, accessor);
    774   } else {
    775     obj->UpdateFieldShortViaAccessor<kTransactionInactive>(field_offset, accessor);
    776   }
    777 }
    778 
    779 template <>
    780 void FieldAccessViaAccessor<int32_t>::Update(ObjPtr<Object> obj,
    781                                              MemberOffset field_offset,
    782                                              Accessor* accessor)
    783     REQUIRES_SHARED(Locks::mutator_lock_) {
    784   if (Runtime::Current()->IsActiveTransaction()) {
    785     obj->UpdateField32ViaAccessor<kTransactionActive>(field_offset, accessor);
    786   } else {
    787     obj->UpdateField32ViaAccessor<kTransactionInactive>(field_offset, accessor);
    788   }
    789 }
    790 
    791 template <>
    792 void FieldAccessViaAccessor<int64_t>::Update(ObjPtr<Object> obj,
    793                                              MemberOffset field_offset,
    794                                              Accessor* accessor)
    795     REQUIRES_SHARED(Locks::mutator_lock_) {
    796   if (Runtime::Current()->IsActiveTransaction()) {
    797     obj->UpdateField64ViaAccessor<kTransactionActive>(field_offset, accessor);
    798   } else {
    799     obj->UpdateField64ViaAccessor<kTransactionInactive>(field_offset, accessor);
    800   }
    801 }
    802 
    803 template <>
    804 void FieldAccessViaAccessor<float>::Update(ObjPtr<Object> obj,
    805                                            MemberOffset field_offset,
    806                                            Accessor* accessor)
    807     REQUIRES_SHARED(Locks::mutator_lock_) {
    808   TypeAdaptorAccessor<int32_t, float> float_to_int_accessor(accessor);
    809   if (Runtime::Current()->IsActiveTransaction()) {
    810     obj->UpdateField32ViaAccessor<kTransactionActive>(field_offset, &float_to_int_accessor);
    811   } else {
    812     obj->UpdateField32ViaAccessor<kTransactionInactive>(field_offset, &float_to_int_accessor);
    813   }
    814 }
    815 
    816 template <>
    817 void FieldAccessViaAccessor<double>::Update(ObjPtr<Object> obj,
    818                                             MemberOffset field_offset,
    819                                             Accessor* accessor)
    820     REQUIRES_SHARED(Locks::mutator_lock_) {
    821   TypeAdaptorAccessor<int64_t, double> double_to_int_accessor(accessor);
    822   if (Runtime::Current()->IsActiveTransaction()) {
    823     obj->UpdateField64ViaAccessor<kTransactionActive>(field_offset, &double_to_int_accessor);
    824   } else {
    825     obj->UpdateField64ViaAccessor<kTransactionInactive>(field_offset, &double_to_int_accessor);
    826   }
    827 }
    828 
    829 // Helper class that gets values from a shadow frame with appropriate type coercion.
    830 template <typename T>
    831 class ValueGetter {
    832  public:
    833   static T Get(ShadowFrameGetter* getter) REQUIRES_SHARED(Locks::mutator_lock_) {
    834     static_assert(sizeof(T) <= sizeof(uint32_t), "Bad size");
    835     uint32_t raw_value = getter->Get();
    836     return static_cast<T>(raw_value);
    837   }
    838 };
    839 
    840 template <>
    841 int64_t ValueGetter<int64_t>::Get(ShadowFrameGetter* getter) {
    842   return getter->GetLong();
    843 }
    844 
    845 template <>
    846 float ValueGetter<float>::Get(ShadowFrameGetter* getter) {
    847   uint32_t raw_value = getter->Get();
    848   return *reinterpret_cast<float*>(&raw_value);
    849 }
    850 
    851 template <>
    852 double ValueGetter<double>::Get(ShadowFrameGetter* getter) {
    853   int64_t raw_value = getter->GetLong();
    854   return *reinterpret_cast<double*>(&raw_value);
    855 }
    856 
    857 template <>
    858 ObjPtr<Object> ValueGetter<ObjPtr<Object>>::Get(ShadowFrameGetter* getter) {
    859   return getter->GetReference();
    860 }
    861 
    862 // Class for accessing fields of Object instances
    863 template <typename T>
    864 class FieldAccessor {
    865  public:
    866   static bool Dispatch(VarHandle::AccessMode access_mode,
    867                        ObjPtr<Object> obj,
    868                        MemberOffset field_offset,
    869                        ShadowFrameGetter* getter,
    870                        JValue* result)
    871       REQUIRES_SHARED(Locks::mutator_lock_);
    872 };
    873 
    874 // Dispatch implementation for primitive fields.
    875 template <typename T>
    876 bool FieldAccessor<T>::Dispatch(VarHandle::AccessMode access_mode,
    877                                 ObjPtr<Object> obj,
    878                                 MemberOffset field_offset,
    879                                 ShadowFrameGetter* getter,
    880                                 JValue* result) {
    881   switch (access_mode) {
    882     case VarHandle::AccessMode::kGet: {
    883       GetAccessor<T> accessor(result);
    884       FieldAccessViaAccessor<T>::Get(obj, field_offset, &accessor);
    885       break;
    886     }
    887     case VarHandle::AccessMode::kSet: {
    888       T new_value = ValueGetter<T>::Get(getter);
    889       SetAccessor<T> accessor(new_value);
    890       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    891       break;
    892     }
    893     case VarHandle::AccessMode::kGetAcquire:
    894     case VarHandle::AccessMode::kGetOpaque:
    895     case VarHandle::AccessMode::kGetVolatile: {
    896       GetVolatileAccessor<T> accessor(result);
    897       FieldAccessViaAccessor<T>::Get(obj, field_offset, &accessor);
    898       break;
    899     }
    900     case VarHandle::AccessMode::kSetOpaque:
    901     case VarHandle::AccessMode::kSetRelease:
    902     case VarHandle::AccessMode::kSetVolatile: {
    903       T new_value = ValueGetter<T>::Get(getter);
    904       SetVolatileAccessor<T> accessor(new_value);
    905       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    906       break;
    907     }
    908     case VarHandle::AccessMode::kCompareAndSet: {
    909       T expected_value = ValueGetter<T>::Get(getter);
    910       T desired_value = ValueGetter<T>::Get(getter);
    911       CompareAndSetAccessor<T> accessor(expected_value, desired_value, result);
    912       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    913       break;
    914     }
    915     case VarHandle::AccessMode::kCompareAndExchange:
    916     case VarHandle::AccessMode::kCompareAndExchangeAcquire:
    917     case VarHandle::AccessMode::kCompareAndExchangeRelease: {
    918       T expected_value = ValueGetter<T>::Get(getter);
    919       T desired_value = ValueGetter<T>::Get(getter);
    920       CompareAndExchangeAccessor<T> accessor(expected_value, desired_value, result);
    921       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    922       break;
    923     }
    924     case VarHandle::AccessMode::kWeakCompareAndSet:
    925     case VarHandle::AccessMode::kWeakCompareAndSetAcquire:
    926     case VarHandle::AccessMode::kWeakCompareAndSetPlain:
    927     case VarHandle::AccessMode::kWeakCompareAndSetRelease: {
    928       T expected_value = ValueGetter<T>::Get(getter);
    929       T desired_value = ValueGetter<T>::Get(getter);
    930       WeakCompareAndSetAccessor<T> accessor(expected_value, desired_value, result);
    931       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    932       break;
    933     }
    934     case VarHandle::AccessMode::kGetAndSet:
    935     case VarHandle::AccessMode::kGetAndSetAcquire:
    936     case VarHandle::AccessMode::kGetAndSetRelease: {
    937       T new_value = ValueGetter<T>::Get(getter);
    938       GetAndSetAccessor<T> accessor(new_value, result);
    939       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    940       break;
    941     }
    942     case VarHandle::AccessMode::kGetAndAdd:
    943     case VarHandle::AccessMode::kGetAndAddAcquire:
    944     case VarHandle::AccessMode::kGetAndAddRelease: {
    945       T value = ValueGetter<T>::Get(getter);
    946       GetAndAddAccessor<T> accessor(value, result);
    947       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    948       break;
    949     }
    950     case VarHandle::AccessMode::kGetAndBitwiseOr:
    951     case VarHandle::AccessMode::kGetAndBitwiseOrAcquire:
    952     case VarHandle::AccessMode::kGetAndBitwiseOrRelease: {
    953       T value = ValueGetter<T>::Get(getter);
    954       GetAndBitwiseOrAccessor<T> accessor(value, result);
    955       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    956       break;
    957     }
    958     case VarHandle::AccessMode::kGetAndBitwiseAnd:
    959     case VarHandle::AccessMode::kGetAndBitwiseAndAcquire:
    960     case VarHandle::AccessMode::kGetAndBitwiseAndRelease: {
    961       T value = ValueGetter<T>::Get(getter);
    962       GetAndBitwiseAndAccessor<T> accessor(value, result);
    963       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    964       break;
    965     }
    966     case VarHandle::AccessMode::kGetAndBitwiseXor:
    967     case VarHandle::AccessMode::kGetAndBitwiseXorAcquire:
    968     case VarHandle::AccessMode::kGetAndBitwiseXorRelease: {
    969       T value = ValueGetter<T>::Get(getter);
    970       GetAndBitwiseXorAccessor<T> accessor(value, result);
    971       FieldAccessViaAccessor<T>::Update(obj, field_offset, &accessor);
    972       break;
    973     }
    974   }
    975   return true;
    976 }
    977 
    978 // Dispatch implementation for reference fields.
    979 template <>
    980 bool FieldAccessor<ObjPtr<Object>>::Dispatch(VarHandle::AccessMode access_mode,
    981                                              ObjPtr<Object> obj,
    982                                              MemberOffset field_offset,
    983                                              ShadowFrameGetter* getter,
    984                                              JValue* result)
    985     REQUIRES_SHARED(Locks::mutator_lock_) {
    986   // To keep things simple, use the minimum strongest existing
    987   // field accessor for Object fields. This may be the most
    988   // straightforward strategy in general for the interpreter.
    989   switch (access_mode) {
    990     case VarHandle::AccessMode::kGet: {
    991       StoreResult(obj->GetFieldObject<Object>(field_offset), result);
    992       break;
    993     }
    994     case VarHandle::AccessMode::kSet: {
    995       ObjPtr<Object> new_value = ValueGetter<ObjPtr<Object>>::Get(getter);
    996       if (Runtime::Current()->IsActiveTransaction()) {
    997         obj->SetFieldObject<kTransactionActive>(field_offset, new_value);
    998       } else {
    999         obj->SetFieldObject<kTransactionInactive>(field_offset, new_value);
   1000       }
   1001       break;
   1002     }
   1003     case VarHandle::AccessMode::kGetAcquire:
   1004     case VarHandle::AccessMode::kGetOpaque:
   1005     case VarHandle::AccessMode::kGetVolatile: {
   1006       StoreResult(obj->GetFieldObjectVolatile<Object>(field_offset), result);
   1007       break;
   1008     }
   1009     case VarHandle::AccessMode::kSetOpaque:
   1010     case VarHandle::AccessMode::kSetRelease:
   1011     case VarHandle::AccessMode::kSetVolatile: {
   1012       ObjPtr<Object> new_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1013       if (Runtime::Current()->IsActiveTransaction()) {
   1014         obj->SetFieldObjectVolatile<kTransactionActive>(field_offset, new_value);
   1015       } else {
   1016         obj->SetFieldObjectVolatile<kTransactionInactive>(field_offset, new_value);
   1017       }
   1018       break;
   1019     }
   1020     case VarHandle::AccessMode::kCompareAndSet: {
   1021       ReadBarrierForVarHandleAccess(obj, field_offset);
   1022       ObjPtr<Object> expected_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1023       ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1024       bool cas_result;
   1025       if (Runtime::Current()->IsActiveTransaction()) {
   1026         cas_result = obj->CasFieldObject<kTransactionActive>(field_offset,
   1027                                                              expected_value,
   1028                                                              desired_value,
   1029                                                              CASMode::kStrong,
   1030                                                              std::memory_order_seq_cst);
   1031       } else {
   1032         cas_result = obj->CasFieldObject<kTransactionInactive>(field_offset,
   1033                                                                expected_value,
   1034                                                                desired_value,
   1035                                                                CASMode::kStrong,
   1036                                                                std::memory_order_seq_cst);
   1037       }
   1038       StoreResult(static_cast<uint8_t>(cas_result), result);
   1039       break;
   1040     }
   1041     case VarHandle::AccessMode::kWeakCompareAndSet:
   1042     case VarHandle::AccessMode::kWeakCompareAndSetAcquire:
   1043     case VarHandle::AccessMode::kWeakCompareAndSetPlain:
   1044     case VarHandle::AccessMode::kWeakCompareAndSetRelease: {
   1045       ReadBarrierForVarHandleAccess(obj, field_offset);
   1046       ObjPtr<Object> expected_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1047       ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1048       bool cas_result;
   1049       if (Runtime::Current()->IsActiveTransaction()) {
   1050         cas_result = obj->CasFieldObject<kTransactionActive>(field_offset,
   1051                                                              expected_value,
   1052                                                              desired_value,
   1053                                                              CASMode::kWeak,
   1054                                                              std::memory_order_seq_cst);
   1055       } else {
   1056         cas_result = obj->CasFieldObject<kTransactionInactive>(
   1057             field_offset,
   1058             expected_value,
   1059             desired_value,
   1060             CASMode::kWeak,
   1061             std::memory_order_seq_cst);
   1062       }
   1063       StoreResult(static_cast<uint8_t>(cas_result), result);
   1064       break;
   1065     }
   1066     case VarHandle::AccessMode::kCompareAndExchange:
   1067     case VarHandle::AccessMode::kCompareAndExchangeAcquire:
   1068     case VarHandle::AccessMode::kCompareAndExchangeRelease: {
   1069       ReadBarrierForVarHandleAccess(obj, field_offset);
   1070       ObjPtr<Object> expected_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1071       ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1072       ObjPtr<Object> witness_value;
   1073       if (Runtime::Current()->IsActiveTransaction()) {
   1074         witness_value = obj->CompareAndExchangeFieldObject<kTransactionActive>(field_offset,
   1075                                                                                expected_value,
   1076                                                                                desired_value);
   1077       } else {
   1078         witness_value = obj->CompareAndExchangeFieldObject<kTransactionInactive>(field_offset,
   1079                                                                                  expected_value,
   1080                                                                                  desired_value);
   1081       }
   1082       StoreResult(witness_value, result);
   1083       break;
   1084     }
   1085     case VarHandle::AccessMode::kGetAndSet:
   1086     case VarHandle::AccessMode::kGetAndSetAcquire:
   1087     case VarHandle::AccessMode::kGetAndSetRelease: {
   1088       ReadBarrierForVarHandleAccess(obj, field_offset);
   1089       ObjPtr<Object> new_value = ValueGetter<ObjPtr<Object>>::Get(getter);
   1090       ObjPtr<Object> old_value;
   1091       if (Runtime::Current()->IsActiveTransaction()) {
   1092         old_value = obj->ExchangeFieldObject<kTransactionActive>(field_offset, new_value);
   1093       } else {
   1094         old_value = obj->ExchangeFieldObject<kTransactionInactive>(field_offset, new_value);
   1095       }
   1096       StoreResult(old_value, result);
   1097       break;
   1098     }
   1099     case VarHandle::AccessMode::kGetAndAdd:
   1100     case VarHandle::AccessMode::kGetAndAddAcquire:
   1101     case VarHandle::AccessMode::kGetAndAddRelease:
   1102     case VarHandle::AccessMode::kGetAndBitwiseOr:
   1103     case VarHandle::AccessMode::kGetAndBitwiseOrAcquire:
   1104     case VarHandle::AccessMode::kGetAndBitwiseOrRelease:
   1105     case VarHandle::AccessMode::kGetAndBitwiseAnd:
   1106     case VarHandle::AccessMode::kGetAndBitwiseAndAcquire:
   1107     case VarHandle::AccessMode::kGetAndBitwiseAndRelease:
   1108     case VarHandle::AccessMode::kGetAndBitwiseXor:
   1109     case VarHandle::AccessMode::kGetAndBitwiseXorAcquire:
   1110     case VarHandle::AccessMode::kGetAndBitwiseXorRelease: {
   1111       size_t index = static_cast<size_t>(access_mode);
   1112       const char* access_mode_name = kAccessorToAccessMode[index].method_name;
   1113       UnreachableAccessMode(access_mode_name, "Object");
   1114     }
   1115   }
   1116   return true;
   1117 }
   1118 
   1119 // Class for accessing primitive array elements.
   1120 template <typename T>
   1121 class PrimitiveArrayElementAccessor {
   1122  public:
   1123   static T* GetElementAddress(ObjPtr<Array> target_array, int target_element)
   1124       REQUIRES_SHARED(Locks::mutator_lock_) {
   1125     auto primitive_array = ObjPtr<PrimitiveArray<T>>::DownCast(target_array);
   1126     DCHECK(primitive_array->CheckIsValidIndex(target_element));
   1127     return &primitive_array->GetData()[target_element];
   1128   }
   1129 
   1130   static bool Dispatch(VarHandle::AccessMode access_mode,
   1131                        ObjPtr<Array> target_array,
   1132                        int target_element,
   1133                        ShadowFrameGetter* getter,
   1134                        JValue* result)
   1135       REQUIRES_SHARED(Locks::mutator_lock_) {
   1136     T* element_address = GetElementAddress(target_array, target_element);
   1137     switch (access_mode) {
   1138       case VarHandle::AccessMode::kGet: {
   1139         GetAccessor<T> accessor(result);
   1140         accessor.Access(element_address);
   1141         break;
   1142       }
   1143       case VarHandle::AccessMode::kSet: {
   1144         T new_value = ValueGetter<T>::Get(getter);
   1145         SetAccessor<T> accessor(new_value);
   1146         accessor.Access(element_address);
   1147         break;
   1148       }
   1149       case VarHandle::AccessMode::kGetAcquire:
   1150       case VarHandle::AccessMode::kGetOpaque:
   1151       case VarHandle::AccessMode::kGetVolatile: {
   1152         GetVolatileAccessor<T> accessor(result);
   1153         accessor.Access(element_address);
   1154         break;
   1155       }
   1156       case VarHandle::AccessMode::kSetOpaque:
   1157       case VarHandle::AccessMode::kSetRelease:
   1158       case VarHandle::AccessMode::kSetVolatile: {
   1159         T new_value = ValueGetter<T>::Get(getter);
   1160         SetVolatileAccessor<T> accessor(new_value);
   1161         accessor.Access(element_address);
   1162         break;
   1163       }
   1164       case VarHandle::AccessMode::kCompareAndSet: {
   1165         T expected_value = ValueGetter<T>::Get(getter);
   1166         T desired_value = ValueGetter<T>::Get(getter);
   1167         CompareAndSetAccessor<T> accessor(expected_value, desired_value, result);
   1168         accessor.Access(element_address);
   1169         break;
   1170       }
   1171       case VarHandle::AccessMode::kCompareAndExchange:
   1172       case VarHandle::AccessMode::kCompareAndExchangeAcquire:
   1173       case VarHandle::AccessMode::kCompareAndExchangeRelease: {
   1174         T expected_value = ValueGetter<T>::Get(getter);
   1175         T desired_value = ValueGetter<T>::Get(getter);
   1176         CompareAndExchangeAccessor<T> accessor(expected_value, desired_value, result);
   1177         accessor.Access(element_address);
   1178         break;
   1179       }
   1180       case VarHandle::AccessMode::kWeakCompareAndSet:
   1181       case VarHandle::AccessMode::kWeakCompareAndSetAcquire:
   1182       case VarHandle::AccessMode::kWeakCompareAndSetPlain:
   1183       case VarHandle::AccessMode::kWeakCompareAndSetRelease: {
   1184         T expected_value = ValueGetter<T>::Get(getter);
   1185         T desired_value = ValueGetter<T>::Get(getter);
   1186         WeakCompareAndSetAccessor<T> accessor(expected_value, desired_value, result);
   1187         accessor.Access(element_address);
   1188         break;
   1189       }
   1190       case VarHandle::AccessMode::kGetAndSet:
   1191       case VarHandle::AccessMode::kGetAndSetAcquire:
   1192       case VarHandle::AccessMode::kGetAndSetRelease: {
   1193         T new_value = ValueGetter<T>::Get(getter);
   1194         GetAndSetAccessor<T> accessor(new_value, result);
   1195         accessor.Access(element_address);
   1196         break;
   1197       }
   1198       case VarHandle::AccessMode::kGetAndAdd:
   1199       case VarHandle::AccessMode::kGetAndAddAcquire:
   1200       case VarHandle::AccessMode::kGetAndAddRelease: {
   1201         T value = ValueGetter<T>::Get(getter);
   1202         GetAndAddAccessor<T> accessor(value, result);
   1203         accessor.Access(element_address);
   1204         break;
   1205       }
   1206       case VarHandle::AccessMode::kGetAndBitwiseOr:
   1207       case VarHandle::AccessMode::kGetAndBitwiseOrAcquire:
   1208       case VarHandle::AccessMode::kGetAndBitwiseOrRelease: {
   1209         T value = ValueGetter<T>::Get(getter);
   1210         GetAndBitwiseOrAccessor<T> accessor(value, result);
   1211         accessor.Access(element_address);
   1212         break;
   1213       }
   1214       case VarHandle::AccessMode::kGetAndBitwiseAnd:
   1215       case VarHandle::AccessMode::kGetAndBitwiseAndAcquire:
   1216       case VarHandle::AccessMode::kGetAndBitwiseAndRelease: {
   1217         T value = ValueGetter<T>::Get(getter);
   1218         GetAndBitwiseAndAccessor<T> accessor(value, result);
   1219         accessor.Access(element_address);
   1220         break;
   1221       }
   1222       case VarHandle::AccessMode::kGetAndBitwiseXor:
   1223       case VarHandle::AccessMode::kGetAndBitwiseXorAcquire:
   1224       case VarHandle::AccessMode::kGetAndBitwiseXorRelease: {
   1225         T value = ValueGetter<T>::Get(getter);
   1226         GetAndBitwiseXorAccessor<T> accessor(value, result);
   1227         accessor.Access(element_address);
   1228         break;
   1229       }
   1230     }
   1231     return true;
   1232   }
   1233 };
   1234 
   1235 // Class for accessing primitive array elements.
   1236 template <typename T>
   1237 class ByteArrayViewAccessor {
   1238  public:
   1239   static inline bool IsAccessAligned(int8_t* data, int data_index) {
   1240     static_assert(IsPowerOfTwo(sizeof(T)), "unexpected size");
   1241     static_assert(std::is_arithmetic<T>::value, "unexpected type");
   1242     uintptr_t alignment_mask = sizeof(T) - 1;
   1243     uintptr_t address = reinterpret_cast<uintptr_t>(data + data_index);
   1244     return (address & alignment_mask) == 0;
   1245   }
   1246 
   1247   static inline void MaybeByteSwap(bool byte_swap, T* const value) {
   1248     if (byte_swap) {
   1249       *value = BSWAP(*value);
   1250     }
   1251   }
   1252 
   1253   static bool Dispatch(const VarHandle::AccessMode access_mode,
   1254                        int8_t* const data,
   1255                        const int data_index,
   1256                        const bool byte_swap,
   1257                        ShadowFrameGetter* const getter,
   1258                        JValue* const result)
   1259       REQUIRES_SHARED(Locks::mutator_lock_) {
   1260     const bool is_aligned = IsAccessAligned(data, data_index);
   1261     if (!is_aligned) {
   1262       switch (access_mode) {
   1263         case VarHandle::AccessMode::kGet: {
   1264           T value;
   1265           memcpy(&value, data + data_index, sizeof(T));
   1266           MaybeByteSwap(byte_swap, &value);
   1267           StoreResult(value, result);
   1268           return true;
   1269         }
   1270         case VarHandle::AccessMode::kSet: {
   1271           T new_value = ValueGetter<T>::Get(getter);
   1272           MaybeByteSwap(byte_swap, &new_value);
   1273           memcpy(data + data_index, &new_value, sizeof(T));
   1274           return true;
   1275         }
   1276         default:
   1277           // No other access modes support unaligned access.
   1278           ThrowIllegalStateException("Unaligned access not supported");
   1279           return false;
   1280       }
   1281     }
   1282 
   1283     T* const element_address = reinterpret_cast<T*>(data + data_index);
   1284     CHECK(IsAccessAligned(reinterpret_cast<int8_t*>(element_address), 0));
   1285     switch (access_mode) {
   1286       case VarHandle::AccessMode::kGet: {
   1287         GetAccessor<T> accessor(result);
   1288         accessor.Access(element_address);
   1289         JValueByteSwapper<T>::MaybeByteSwap(byte_swap, result);
   1290         break;
   1291       }
   1292       case VarHandle::AccessMode::kSet: {
   1293         T new_value = ValueGetter<T>::Get(getter);
   1294         MaybeByteSwap(byte_swap, &new_value);
   1295         SetAccessor<T> accessor(new_value);
   1296         accessor.Access(element_address);
   1297         break;
   1298       }
   1299       case VarHandle::AccessMode::kGetAcquire:
   1300       case VarHandle::AccessMode::kGetOpaque:
   1301       case VarHandle::AccessMode::kGetVolatile: {
   1302         GetVolatileAccessor<T> accessor(result);
   1303         accessor.Access(element_address);
   1304         JValueByteSwapper<T>::MaybeByteSwap(byte_swap, result);
   1305         break;
   1306       }
   1307       case VarHandle::AccessMode::kSetOpaque:
   1308       case VarHandle::AccessMode::kSetRelease:
   1309       case VarHandle::AccessMode::kSetVolatile: {
   1310         T new_value = ValueGetter<T>::Get(getter);
   1311         MaybeByteSwap(byte_swap, &new_value);
   1312         SetVolatileAccessor<T> accessor(new_value);
   1313         accessor.Access(element_address);
   1314         break;
   1315       }
   1316       case VarHandle::AccessMode::kCompareAndSet: {
   1317         T expected_value = ValueGetter<T>::Get(getter);
   1318         T desired_value = ValueGetter<T>::Get(getter);
   1319         MaybeByteSwap(byte_swap, &expected_value);
   1320         MaybeByteSwap(byte_swap, &desired_value);
   1321         CompareAndSetAccessor<T> accessor(expected_value, desired_value, result);
   1322         accessor.Access(element_address);
   1323         break;
   1324       }
   1325       case VarHandle::AccessMode::kCompareAndExchange:
   1326       case VarHandle::AccessMode::kCompareAndExchangeAcquire:
   1327       case VarHandle::AccessMode::kCompareAndExchangeRelease: {
   1328         T expected_value = ValueGetter<T>::Get(getter);
   1329         T desired_value = ValueGetter<T>::Get(getter);
   1330         MaybeByteSwap(byte_swap, &expected_value);
   1331         MaybeByteSwap(byte_swap, &desired_value);
   1332         CompareAndExchangeAccessor<T> accessor(expected_value, desired_value, result);
   1333         accessor.Access(element_address);
   1334         JValueByteSwapper<T>::MaybeByteSwap(byte_swap, result);
   1335         break;
   1336       }
   1337       case VarHandle::AccessMode::kWeakCompareAndSet:
   1338       case VarHandle::AccessMode::kWeakCompareAndSetAcquire:
   1339       case VarHandle::AccessMode::kWeakCompareAndSetPlain:
   1340       case VarHandle::AccessMode::kWeakCompareAndSetRelease: {
   1341         T expected_value = ValueGetter<T>::Get(getter);
   1342         T desired_value = ValueGetter<T>::Get(getter);
   1343         MaybeByteSwap(byte_swap, &expected_value);
   1344         MaybeByteSwap(byte_swap, &desired_value);
   1345         WeakCompareAndSetAccessor<T> accessor(expected_value, desired_value, result);
   1346         accessor.Access(element_address);
   1347         break;
   1348       }
   1349       case VarHandle::AccessMode::kGetAndSet:
   1350       case VarHandle::AccessMode::kGetAndSetAcquire:
   1351       case VarHandle::AccessMode::kGetAndSetRelease: {
   1352         T new_value = ValueGetter<T>::Get(getter);
   1353         MaybeByteSwap(byte_swap, &new_value);
   1354         GetAndSetAccessor<T> accessor(new_value, result);
   1355         accessor.Access(element_address);
   1356         JValueByteSwapper<T>::MaybeByteSwap(byte_swap, result);
   1357         break;
   1358       }
   1359       case VarHandle::AccessMode::kGetAndAdd:
   1360       case VarHandle::AccessMode::kGetAndAddAcquire:
   1361       case VarHandle::AccessMode::kGetAndAddRelease: {
   1362         T value = ValueGetter<T>::Get(getter);
   1363         if (byte_swap) {
   1364           GetAndAddWithByteSwapAccessor<T> accessor(value, result);
   1365           accessor.Access(element_address);
   1366         } else {
   1367           GetAndAddAccessor<T> accessor(value, result);
   1368           accessor.Access(element_address);
   1369         }
   1370         break;
   1371       }
   1372       case VarHandle::AccessMode::kGetAndBitwiseOr:
   1373       case VarHandle::AccessMode::kGetAndBitwiseOrAcquire:
   1374       case VarHandle::AccessMode::kGetAndBitwiseOrRelease: {
   1375         T value = ValueGetter<T>::Get(getter);
   1376         MaybeByteSwap(byte_swap, &value);
   1377         GetAndBitwiseOrAccessor<T> accessor(value, result);
   1378         accessor.Access(element_address);
   1379         JValueByteSwapper<T>::MaybeByteSwap(byte_swap, result);
   1380         break;
   1381       }
   1382       case VarHandle::AccessMode::kGetAndBitwiseAnd:
   1383       case VarHandle::AccessMode::kGetAndBitwiseAndAcquire:
   1384       case VarHandle::AccessMode::kGetAndBitwiseAndRelease: {
   1385         T value = ValueGetter<T>::Get(getter);
   1386         MaybeByteSwap(byte_swap, &value);
   1387         GetAndBitwiseAndAccessor<T> accessor(value, result);
   1388         accessor.Access(element_address);
   1389         JValueByteSwapper<T>::MaybeByteSwap(byte_swap, result);
   1390         break;
   1391       }
   1392       case VarHandle::AccessMode::kGetAndBitwiseXor:
   1393       case VarHandle::AccessMode::kGetAndBitwiseXorAcquire:
   1394       case VarHandle::AccessMode::kGetAndBitwiseXorRelease: {
   1395         T value = ValueGetter<T>::Get(getter);
   1396         MaybeByteSwap(byte_swap, &value);
   1397         GetAndBitwiseXorAccessor<T> accessor(value, result);
   1398         accessor.Access(element_address);
   1399         JValueByteSwapper<T>::MaybeByteSwap(byte_swap, result);
   1400         break;
   1401       }
   1402     }
   1403     return true;
   1404   }
   1405 };
   1406 
   1407 }  // namespace
   1408 
   1409 ObjPtr<Class> VarHandle::GetVarType() {
   1410   return GetFieldObject<Class>(VarTypeOffset());
   1411 }
   1412 
   1413 ObjPtr<Class> VarHandle::GetCoordinateType0() {
   1414   return GetFieldObject<Class>(CoordinateType0Offset());
   1415 }
   1416 
   1417 ObjPtr<Class> VarHandle::GetCoordinateType1() {
   1418   return GetFieldObject<Class>(CoordinateType1Offset());
   1419 }
   1420 
   1421 int32_t VarHandle::GetAccessModesBitMask() {
   1422   return GetField32(AccessModesBitMaskOffset());
   1423 }
   1424 
   1425 VarHandle::MatchKind VarHandle::GetMethodTypeMatchForAccessMode(AccessMode access_mode,
   1426                                                                 ObjPtr<MethodType> method_type) {
   1427   MatchKind match = MatchKind::kExact;
   1428 
   1429   ObjPtr<VarHandle> vh = this;
   1430   ObjPtr<Class> var_type = vh->GetVarType();
   1431   ObjPtr<Class> mt_rtype = method_type->GetRType();
   1432   AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode);
   1433 
   1434   // Check return type first. If the return type of the method
   1435   // of the VarHandle is immaterial.
   1436   if (mt_rtype->GetPrimitiveType() != Primitive::Type::kPrimVoid) {
   1437     ObjPtr<Class> vh_rtype = GetReturnType(access_mode_template, var_type);
   1438     if (vh_rtype != mt_rtype) {
   1439       if (!IsReturnTypeConvertible(vh_rtype, mt_rtype)) {
   1440         return MatchKind::kNone;
   1441       }
   1442       match = MatchKind::kWithConversions;
   1443     }
   1444   }
   1445 
   1446   // Check the number of parameters matches.
   1447   ObjPtr<Class> vh_ptypes[VarHandle::kMaxAccessorParameters];
   1448   const int32_t vh_ptypes_count = BuildParameterArray(vh_ptypes,
   1449                                                       access_mode_template,
   1450                                                       var_type,
   1451                                                       GetCoordinateType0(),
   1452                                                       GetCoordinateType1());
   1453   if (vh_ptypes_count != method_type->GetPTypes()->GetLength()) {
   1454     return MatchKind::kNone;
   1455   }
   1456 
   1457   // Check the parameter types are compatible.
   1458   ObjPtr<ObjectArray<Class>> mt_ptypes = method_type->GetPTypes();
   1459   for (int32_t i = 0; i < vh_ptypes_count; ++i) {
   1460     if (mt_ptypes->Get(i) == vh_ptypes[i]) {
   1461       continue;
   1462     }
   1463     if (!IsParameterTypeConvertible(mt_ptypes->Get(i), vh_ptypes[i])) {
   1464       return MatchKind::kNone;
   1465     }
   1466     match = MatchKind::kWithConversions;
   1467   }
   1468   return match;
   1469 }
   1470 
   1471 bool VarHandle::IsInvokerMethodTypeCompatible(AccessMode access_mode,
   1472                                               ObjPtr<MethodType> method_type) {
   1473   StackHandleScope<3> hs(Thread::Current());
   1474   Handle<Class> mt_rtype(hs.NewHandle(method_type->GetRType()));
   1475   Handle<VarHandle> vh(hs.NewHandle(this));
   1476   Handle<Class> var_type(hs.NewHandle(vh->GetVarType()));
   1477   AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode);
   1478 
   1479   // Check return type first.
   1480   if (mt_rtype->GetPrimitiveType() == Primitive::Type::kPrimVoid) {
   1481     // The result of the operation will be discarded. The return type
   1482     // of the VarHandle is immaterial.
   1483   } else {
   1484     ObjPtr<Class> vh_rtype(GetReturnType(access_mode_template, var_type.Get()));
   1485     if (!IsReturnTypeConvertible(vh_rtype, mt_rtype.Get())) {
   1486       return false;
   1487     }
   1488   }
   1489 
   1490   // Check the number of parameters matches (ignoring the VarHandle parameter).
   1491   static const int32_t kVarHandleParameters = 1;
   1492   ObjPtr<Class> vh_ptypes[VarHandle::kMaxAccessorParameters];
   1493   const int32_t vh_ptypes_count = BuildParameterArray(vh_ptypes,
   1494                                                       access_mode_template,
   1495                                                       var_type.Get(),
   1496                                                       GetCoordinateType0(),
   1497                                                       GetCoordinateType1());
   1498   if (vh_ptypes_count != method_type->GetPTypes()->GetLength() - kVarHandleParameters) {
   1499     return false;
   1500   }
   1501 
   1502   // Check the parameter types are compatible (ignoring the VarHandle parameter).
   1503   ObjPtr<ObjectArray<Class>> mt_ptypes = method_type->GetPTypes();
   1504   for (int32_t i = 0; i < vh_ptypes_count; ++i) {
   1505     if (!IsParameterTypeConvertible(mt_ptypes->Get(i + kVarHandleParameters), vh_ptypes[i])) {
   1506       return false;
   1507     }
   1508   }
   1509   return true;
   1510 }
   1511 
   1512 ObjPtr<MethodType> VarHandle::GetMethodTypeForAccessMode(Thread* self,
   1513                                                          ObjPtr<VarHandle> var_handle,
   1514                                                          AccessMode access_mode) {
   1515   // This is a static method as the var_handle might be moved by the GC during it's execution.
   1516   AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode);
   1517 
   1518   StackHandleScope<3> hs(self);
   1519   Handle<VarHandle> vh = hs.NewHandle(var_handle);
   1520   Handle<Class> rtype = hs.NewHandle(GetReturnType(access_mode_template, vh->GetVarType()));
   1521   const int32_t ptypes_count = GetNumberOfParameters(access_mode_template,
   1522                                                      vh->GetCoordinateType0(),
   1523                                                      vh->GetCoordinateType1());
   1524   ObjPtr<Class> array_of_class = GetClassRoot<ObjectArray<Class>>();
   1525   Handle<ObjectArray<Class>> ptypes =
   1526       hs.NewHandle(ObjectArray<Class>::Alloc(Thread::Current(), array_of_class, ptypes_count));
   1527   if (ptypes == nullptr) {
   1528     return nullptr;
   1529   }
   1530 
   1531   ObjPtr<Class> ptypes_array[VarHandle::kMaxAccessorParameters];
   1532   BuildParameterArray(ptypes_array,
   1533                       access_mode_template,
   1534                       vh->GetVarType(),
   1535                       vh->GetCoordinateType0(),
   1536                       vh->GetCoordinateType1());
   1537   for (int32_t i = 0; i < ptypes_count; ++i) {
   1538     ptypes->Set(i, ptypes_array[i]);
   1539   }
   1540   return MethodType::Create(self, rtype, ptypes);
   1541 }
   1542 
   1543 ObjPtr<MethodType> VarHandle::GetMethodTypeForAccessMode(Thread* self, AccessMode access_mode) {
   1544   return GetMethodTypeForAccessMode(self, this, access_mode);
   1545 }
   1546 
   1547 std::string VarHandle::PrettyDescriptorForAccessMode(AccessMode access_mode) {
   1548   // Effect MethodType::PrettyDescriptor() without first creating a method type first.
   1549   std::ostringstream oss;
   1550   oss << '(';
   1551 
   1552   AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode);
   1553   ObjPtr<Class> var_type = GetVarType();
   1554   ObjPtr<Class> ctypes[2] = { GetCoordinateType0(), GetCoordinateType1() };
   1555   const int32_t ptypes_count = GetNumberOfParameters(access_mode_template, ctypes[0], ctypes[1]);
   1556   int32_t ptypes_done = 0;
   1557   for (ObjPtr<Class> ctype : ctypes) {
   1558     if (!ctype.IsNull()) {
   1559       if (ptypes_done != 0) {
   1560         oss << ", ";
   1561       }
   1562       oss << ctype->PrettyDescriptor();;
   1563       ptypes_done++;
   1564     }
   1565   }
   1566   while (ptypes_done != ptypes_count) {
   1567     if (ptypes_done != 0) {
   1568       oss << ", ";
   1569     }
   1570     oss << var_type->PrettyDescriptor();
   1571     ptypes_done++;
   1572   }
   1573   ObjPtr<Class> rtype = GetReturnType(access_mode_template, var_type);
   1574   oss << ')' << rtype->PrettyDescriptor();
   1575   return oss.str();
   1576 }
   1577 
   1578 bool VarHandle::Access(AccessMode access_mode,
   1579                        ShadowFrame* shadow_frame,
   1580                        const InstructionOperands* const operands,
   1581                        JValue* result) {
   1582   ObjPtr<ObjectArray<Class>> class_roots = Runtime::Current()->GetClassLinker()->GetClassRoots();
   1583   ObjPtr<Class> klass = GetClass();
   1584   if (klass == GetClassRoot<FieldVarHandle>(class_roots)) {
   1585     auto vh = reinterpret_cast<FieldVarHandle*>(this);
   1586     return vh->Access(access_mode, shadow_frame, operands, result);
   1587   } else if (klass == GetClassRoot<ArrayElementVarHandle>(class_roots)) {
   1588     auto vh = reinterpret_cast<ArrayElementVarHandle*>(this);
   1589     return vh->Access(access_mode, shadow_frame, operands, result);
   1590   } else if (klass == GetClassRoot<ByteArrayViewVarHandle>(class_roots)) {
   1591     auto vh = reinterpret_cast<ByteArrayViewVarHandle*>(this);
   1592     return vh->Access(access_mode, shadow_frame, operands, result);
   1593   } else if (klass == GetClassRoot<ByteBufferViewVarHandle>(class_roots)) {
   1594     auto vh = reinterpret_cast<ByteBufferViewVarHandle*>(this);
   1595     return vh->Access(access_mode, shadow_frame, operands, result);
   1596   } else {
   1597     LOG(FATAL) << "Unknown varhandle kind";
   1598     UNREACHABLE();
   1599   }
   1600 }
   1601 
   1602 const char* VarHandle::GetReturnTypeDescriptor(const char* accessor_name) {
   1603   AccessMode access_mode;
   1604   if (!GetAccessModeByMethodName(accessor_name, &access_mode)) {
   1605     return nullptr;
   1606   }
   1607   AccessModeTemplate access_mode_template = GetAccessModeTemplate(access_mode);
   1608   switch (access_mode_template) {
   1609     case AccessModeTemplate::kGet:
   1610     case AccessModeTemplate::kCompareAndExchange:
   1611     case AccessModeTemplate::kGetAndUpdate:
   1612       return "Ljava/lang/Object;";
   1613     case AccessModeTemplate::kCompareAndSet:
   1614       return "Z";
   1615     case AccessModeTemplate::kSet:
   1616       return "V";
   1617   }
   1618 }
   1619 
   1620 VarHandle::AccessMode VarHandle::GetAccessModeByIntrinsic(Intrinsics intrinsic) {
   1621 #define VAR_HANDLE_ACCESS_MODE(V)               \
   1622     V(CompareAndExchange)                       \
   1623     V(CompareAndExchangeAcquire)                \
   1624     V(CompareAndExchangeRelease)                \
   1625     V(CompareAndSet)                            \
   1626     V(Get)                                      \
   1627     V(GetAcquire)                               \
   1628     V(GetAndAdd)                                \
   1629     V(GetAndAddAcquire)                         \
   1630     V(GetAndAddRelease)                         \
   1631     V(GetAndBitwiseAnd)                         \
   1632     V(GetAndBitwiseAndAcquire)                  \
   1633     V(GetAndBitwiseAndRelease)                  \
   1634     V(GetAndBitwiseOr)                          \
   1635     V(GetAndBitwiseOrAcquire)                   \
   1636     V(GetAndBitwiseOrRelease)                   \
   1637     V(GetAndBitwiseXor)                         \
   1638     V(GetAndBitwiseXorAcquire)                  \
   1639     V(GetAndBitwiseXorRelease)                  \
   1640     V(GetAndSet)                                \
   1641     V(GetAndSetAcquire)                         \
   1642     V(GetAndSetRelease)                         \
   1643     V(GetOpaque)                                \
   1644     V(GetVolatile)                              \
   1645     V(Set)                                      \
   1646     V(SetOpaque)                                \
   1647     V(SetRelease)                               \
   1648     V(SetVolatile)                              \
   1649     V(WeakCompareAndSet)                        \
   1650     V(WeakCompareAndSetAcquire)                 \
   1651     V(WeakCompareAndSetPlain)                   \
   1652     V(WeakCompareAndSetRelease)
   1653   switch (intrinsic) {
   1654 #define INTRINSIC_CASE(Name)                    \
   1655     case Intrinsics::kVarHandle ## Name:        \
   1656       return VarHandle::AccessMode::k ## Name;
   1657     VAR_HANDLE_ACCESS_MODE(INTRINSIC_CASE)
   1658 #undef INTRINSIC_CASE
   1659 #undef VAR_HANDLE_ACCESS_MODE
   1660     default:
   1661       break;
   1662   }
   1663   LOG(FATAL) << "Unknown VarHandle instrinsic: " << static_cast<int>(intrinsic);
   1664   UNREACHABLE();
   1665 }
   1666 
   1667 bool VarHandle::GetAccessModeByMethodName(const char* method_name, AccessMode* access_mode) {
   1668   if (method_name == nullptr) {
   1669     return false;
   1670   }
   1671   VarHandleAccessorToAccessModeEntry target = { method_name, /*dummy*/VarHandle::AccessMode::kGet };
   1672   auto last = std::cend(kAccessorToAccessMode);
   1673   auto it = std::lower_bound(std::cbegin(kAccessorToAccessMode),
   1674                              last,
   1675                              target,
   1676                              VarHandleAccessorToAccessModeEntry::CompareName);
   1677   if (it == last || strcmp(it->method_name, method_name) != 0) {
   1678     return false;
   1679   }
   1680   *access_mode = it->access_mode;
   1681   return true;
   1682 }
   1683 
   1684 ArtField* FieldVarHandle::GetField() {
   1685   return reinterpret_cast64<ArtField*>(GetField64(ArtFieldOffset()));
   1686 }
   1687 
   1688 bool FieldVarHandle::Access(AccessMode access_mode,
   1689                             ShadowFrame* shadow_frame,
   1690                             const InstructionOperands* const operands,
   1691                             JValue* result) {
   1692   ShadowFrameGetter getter(*shadow_frame, operands);
   1693   ArtField* field = GetField();
   1694   ObjPtr<Object> obj;
   1695   if (field->IsStatic()) {
   1696     DCHECK_LE(operands->GetNumberOfOperands(),
   1697               2u * (Primitive::Is64BitType(GetVarType()->GetPrimitiveType()) ? 2u : 1u));
   1698     obj = field->GetDeclaringClass();
   1699   } else {
   1700     DCHECK_GE(operands->GetNumberOfOperands(), 1u);
   1701     DCHECK_LE(operands->GetNumberOfOperands(),
   1702               1u + 2u * (Primitive::Is64BitType(GetVarType()->GetPrimitiveType()) ? 2u : 1u));
   1703     obj = getter.GetReference();
   1704     if (obj.IsNull()) {
   1705       ThrowNullPointerExceptionForCoordinate();
   1706       return false;
   1707     }
   1708   }
   1709   DCHECK(!obj.IsNull());
   1710 
   1711   const MemberOffset offset = field->GetOffset();
   1712   const Primitive::Type primitive_type = GetVarType()->GetPrimitiveType();
   1713   switch (primitive_type) {
   1714     case Primitive::Type::kPrimNot:
   1715       return FieldAccessor<ObjPtr<Object>>::Dispatch(access_mode, obj, offset, &getter, result);
   1716     case Primitive::kPrimBoolean:
   1717       return FieldAccessor<uint8_t>::Dispatch(access_mode, obj, offset, &getter, result);
   1718     case Primitive::kPrimByte:
   1719       return FieldAccessor<int8_t>::Dispatch(access_mode, obj, offset, &getter, result);
   1720     case Primitive::kPrimChar:
   1721       return FieldAccessor<uint16_t>::Dispatch(access_mode, obj, offset, &getter, result);
   1722     case Primitive::kPrimShort:
   1723       return FieldAccessor<int16_t>::Dispatch(access_mode, obj, offset, &getter, result);
   1724     case Primitive::kPrimInt:
   1725       return FieldAccessor<int32_t>::Dispatch(access_mode, obj, offset, &getter, result);
   1726     case Primitive::kPrimFloat:
   1727       return FieldAccessor<float>::Dispatch(access_mode,  obj, offset, &getter, result);
   1728     case Primitive::kPrimLong:
   1729       return FieldAccessor<int64_t>::Dispatch(access_mode, obj, offset, &getter, result);
   1730     case Primitive::kPrimDouble:
   1731       return FieldAccessor<double>::Dispatch(access_mode, obj, offset, &getter, result);
   1732     case Primitive::kPrimVoid:
   1733       break;
   1734   }
   1735   LOG(FATAL) << "Unreachable: Unexpected primitive " << primitive_type;
   1736   UNREACHABLE();
   1737 }
   1738 
   1739 bool ArrayElementVarHandle::Access(AccessMode access_mode,
   1740                                    ShadowFrame* shadow_frame,
   1741                                    const InstructionOperands* const operands,
   1742                                    JValue* result) {
   1743   ShadowFrameGetter getter(*shadow_frame, operands);
   1744 
   1745   // The target array is the first co-ordinate type preceeding var type arguments.
   1746   ObjPtr<Object> raw_array(getter.GetReference());
   1747   if (raw_array == nullptr) {
   1748     ThrowNullPointerExceptionForCoordinate();
   1749     return false;
   1750   }
   1751 
   1752   ObjPtr<Array> target_array(raw_array->AsArray());
   1753 
   1754   // The target array element is the second co-ordinate type preceeding var type arguments.
   1755   const int target_element = getter.Get();
   1756   if (!target_array->CheckIsValidIndex(target_element)) {
   1757     DCHECK(Thread::Current()->IsExceptionPending());
   1758     return false;
   1759   }
   1760 
   1761   const Primitive::Type primitive_type = GetVarType()->GetPrimitiveType();
   1762   switch (primitive_type) {
   1763     case Primitive::Type::kPrimNot: {
   1764       MemberOffset target_element_offset =
   1765           target_array->AsObjectArray<Object>()->OffsetOfElement(target_element);
   1766       return FieldAccessor<ObjPtr<Object>>::Dispatch(access_mode,
   1767                                                      target_array,
   1768                                                      target_element_offset,
   1769                                                      &getter,
   1770                                                      result);
   1771     }
   1772     case Primitive::Type::kPrimBoolean:
   1773       return PrimitiveArrayElementAccessor<uint8_t>::Dispatch(access_mode,
   1774                                                               target_array,
   1775                                                               target_element,
   1776                                                               &getter,
   1777                                                               result);
   1778     case Primitive::Type::kPrimByte:
   1779       return PrimitiveArrayElementAccessor<int8_t>::Dispatch(access_mode,
   1780                                                              target_array,
   1781                                                              target_element,
   1782                                                              &getter,
   1783                                                              result);
   1784     case Primitive::Type::kPrimChar:
   1785       return PrimitiveArrayElementAccessor<uint16_t>::Dispatch(access_mode,
   1786                                                                target_array,
   1787                                                                target_element,
   1788                                                                &getter,
   1789                                                                result);
   1790     case Primitive::Type::kPrimShort:
   1791       return PrimitiveArrayElementAccessor<int16_t>::Dispatch(access_mode,
   1792                                                               target_array,
   1793                                                               target_element,
   1794                                                               &getter,
   1795                                                               result);
   1796     case Primitive::Type::kPrimInt:
   1797       return PrimitiveArrayElementAccessor<int32_t>::Dispatch(access_mode,
   1798                                                               target_array,
   1799                                                               target_element,
   1800                                                               &getter,
   1801                                                               result);
   1802     case Primitive::Type::kPrimLong:
   1803       return PrimitiveArrayElementAccessor<int64_t>::Dispatch(access_mode,
   1804                                                               target_array,
   1805                                                               target_element,
   1806                                                               &getter,
   1807                                                               result);
   1808     case Primitive::Type::kPrimFloat:
   1809       return PrimitiveArrayElementAccessor<float>::Dispatch(access_mode,
   1810                                                             target_array,
   1811                                                             target_element,
   1812                                                             &getter,
   1813                                                             result);
   1814     case Primitive::Type::kPrimDouble:
   1815       return PrimitiveArrayElementAccessor<double>::Dispatch(access_mode,
   1816                                                              target_array,
   1817                                                              target_element,
   1818                                                              &getter,
   1819                                                              result);
   1820     case Primitive::Type::kPrimVoid:
   1821       break;
   1822   }
   1823   LOG(FATAL) << "Unreachable: Unexpected primitive " << primitive_type;
   1824   UNREACHABLE();
   1825 }
   1826 
   1827 bool ByteArrayViewVarHandle::GetNativeByteOrder() {
   1828   return GetFieldBoolean(NativeByteOrderOffset());
   1829 }
   1830 
   1831 bool ByteArrayViewVarHandle::Access(AccessMode access_mode,
   1832                                     ShadowFrame* shadow_frame,
   1833                                     const InstructionOperands* const operands,
   1834                                     JValue* result) {
   1835   ShadowFrameGetter getter(*shadow_frame, operands);
   1836 
   1837   // The byte array is the first co-ordinate type preceeding var type arguments.
   1838   ObjPtr<Object> raw_byte_array(getter.GetReference());
   1839   if (raw_byte_array == nullptr) {
   1840     ThrowNullPointerExceptionForCoordinate();
   1841     return false;
   1842   }
   1843 
   1844   ObjPtr<ByteArray> byte_array(raw_byte_array->AsByteArray());
   1845 
   1846   // The offset in the byte array element is the second co-ordinate type.
   1847   const int32_t data_offset = getter.Get();
   1848 
   1849   // Bounds check requested access.
   1850   const Primitive::Type primitive_type = GetVarType()->GetPrimitiveType();
   1851   if (!CheckElementIndex(primitive_type, data_offset, byte_array->GetLength())) {
   1852     return false;
   1853   }
   1854 
   1855   int8_t* const data = byte_array->GetData();
   1856   bool byte_swap = !GetNativeByteOrder();
   1857   switch (primitive_type) {
   1858     case Primitive::Type::kPrimNot:
   1859     case Primitive::kPrimBoolean:
   1860     case Primitive::kPrimByte:
   1861     case Primitive::kPrimVoid:
   1862       // These are not supported for byte array views and not instantiable.
   1863       break;
   1864     case Primitive::kPrimChar:
   1865       return ByteArrayViewAccessor<uint16_t>::Dispatch(access_mode,
   1866                                                        data,
   1867                                                        data_offset,
   1868                                                        byte_swap,
   1869                                                        &getter,
   1870                                                        result);
   1871     case Primitive::kPrimShort:
   1872       return ByteArrayViewAccessor<int16_t>::Dispatch(access_mode,
   1873                                                       data,
   1874                                                       data_offset,
   1875                                                       byte_swap,
   1876                                                       &getter,
   1877                                                       result);
   1878     case Primitive::kPrimInt:
   1879       return ByteArrayViewAccessor<int32_t>::Dispatch(access_mode,
   1880                                                       data,
   1881                                                       data_offset,
   1882                                                       byte_swap,
   1883                                                       &getter,
   1884                                                       result);
   1885     case Primitive::kPrimFloat:
   1886       // Treated as a bitwise representation. See javadoc comments for
   1887       // java.lang.invoke.MethodHandles.byteArrayViewVarHandle().
   1888       return ByteArrayViewAccessor<int32_t>::Dispatch(access_mode,
   1889                                                       data,
   1890                                                       data_offset,
   1891                                                       byte_swap,
   1892                                                       &getter,
   1893                                                       result);
   1894     case Primitive::kPrimLong:
   1895       return ByteArrayViewAccessor<int64_t>::Dispatch(access_mode,
   1896                                                       data,
   1897                                                       data_offset,
   1898                                                       byte_swap,
   1899                                                       &getter,
   1900                                                       result);
   1901     case Primitive::kPrimDouble:
   1902       // Treated as a bitwise representation. See javadoc comments for
   1903       // java.lang.invoke.MethodHandles.byteArrayViewVarHandle().
   1904       return ByteArrayViewAccessor<int64_t>::Dispatch(access_mode,
   1905                                                       data,
   1906                                                       data_offset,
   1907                                                       byte_swap,
   1908                                                       &getter,
   1909                                                       result);
   1910   }
   1911   LOG(FATAL) << "Unreachable: Unexpected primitive " << primitive_type;
   1912   UNREACHABLE();
   1913 }
   1914 
   1915 bool ByteBufferViewVarHandle::GetNativeByteOrder() {
   1916   return GetFieldBoolean(NativeByteOrderOffset());
   1917 }
   1918 
   1919 bool ByteBufferViewVarHandle::Access(AccessMode access_mode,
   1920                                      ShadowFrame* shadow_frame,
   1921                                      const InstructionOperands* const operands,
   1922                                      JValue* result) {
   1923   ShadowFrameGetter getter(*shadow_frame, operands);
   1924 
   1925   // The byte buffer is the first co-ordinate argument preceeding var type arguments.
   1926   ObjPtr<Object> byte_buffer(getter.GetReference());
   1927   if (byte_buffer == nullptr) {
   1928     ThrowNullPointerExceptionForCoordinate();
   1929     return false;
   1930   }
   1931 
   1932   // The byte index for access is the second co-ordinate
   1933   // argument. This is relative to the offset field of the ByteBuffer.
   1934   const int32_t byte_index = getter.Get();
   1935 
   1936   // Check access_mode is compatible with ByteBuffer's read-only property.
   1937   bool is_read_only = byte_buffer->GetFieldBoolean(
   1938       GetMemberOffset(WellKnownClasses::java_nio_ByteBuffer_isReadOnly));
   1939   if (is_read_only && !IsReadOnlyAccessMode(access_mode)) {
   1940     ThrowReadOnlyBufferException();
   1941     return false;
   1942   }
   1943 
   1944   // The native_address is only set for ByteBuffer instances backed by native memory.
   1945   const int64_t native_address =
   1946       byte_buffer->GetField64(GetMemberOffset(WellKnownClasses::java_nio_ByteBuffer_address));
   1947 
   1948   // Determine offset and limit for accesses.
   1949   int32_t byte_buffer_offset;
   1950   if (native_address == 0L) {
   1951     // Accessing a heap allocated byte buffer.
   1952     byte_buffer_offset = byte_buffer->GetField32(
   1953         GetMemberOffset(WellKnownClasses::java_nio_ByteBuffer_offset));
   1954   } else {
   1955     // Accessing direct memory.
   1956     byte_buffer_offset = 0;
   1957   }
   1958   const int32_t byte_buffer_limit = byte_buffer->GetField32(
   1959       GetMemberOffset(WellKnownClasses::java_nio_ByteBuffer_limit));
   1960 
   1961   const Primitive::Type primitive_type = GetVarType()->GetPrimitiveType();
   1962   if (!CheckElementIndex(primitive_type, byte_index, byte_buffer_offset, byte_buffer_limit)) {
   1963     return false;
   1964   }
   1965   const int32_t checked_offset32 = byte_buffer_offset + byte_index;
   1966 
   1967   int8_t* data;
   1968   if (native_address == 0) {
   1969     ObjPtr<ByteArray> heap_byte_array = byte_buffer->GetFieldObject<ByteArray>(
   1970         GetMemberOffset(WellKnownClasses::java_nio_ByteBuffer_hb));
   1971     data = heap_byte_array->GetData();
   1972   } else {
   1973     data = reinterpret_cast<int8_t*>(static_cast<uint32_t>(native_address));
   1974   }
   1975 
   1976   bool byte_swap = !GetNativeByteOrder();
   1977   switch (primitive_type) {
   1978     case Primitive::kPrimChar:
   1979       return ByteArrayViewAccessor<uint16_t>::Dispatch(access_mode,
   1980                                                        data,
   1981                                                        checked_offset32,
   1982                                                        byte_swap,
   1983                                                        &getter,
   1984                                                        result);
   1985     case Primitive::kPrimShort:
   1986       return ByteArrayViewAccessor<int16_t>::Dispatch(access_mode,
   1987                                                       data,
   1988                                                       checked_offset32,
   1989                                                       byte_swap,
   1990                                                       &getter,
   1991                                                       result);
   1992     case Primitive::kPrimInt:
   1993       return ByteArrayViewAccessor<int32_t>::Dispatch(access_mode,
   1994                                                       data,
   1995                                                       checked_offset32,
   1996                                                       byte_swap,
   1997                                                       &getter,
   1998                                                       result);
   1999     case Primitive::kPrimFloat:
   2000       // Treated as a bitwise representation. See javadoc comments for
   2001       // java.lang.invoke.MethodHandles.byteArrayViewVarHandle().
   2002       return ByteArrayViewAccessor<int32_t>::Dispatch(access_mode,
   2003                                                       data,
   2004                                                       checked_offset32,
   2005                                                       byte_swap,
   2006                                                       &getter,
   2007                                                       result);
   2008     case Primitive::kPrimLong:
   2009       return ByteArrayViewAccessor<int64_t>::Dispatch(access_mode,
   2010                                                       data,
   2011                                                       checked_offset32,
   2012                                                       byte_swap,
   2013                                                       &getter,
   2014                                                       result);
   2015     case Primitive::kPrimDouble:
   2016       // Treated as a bitwise representation. See javadoc comments for
   2017       // java.lang.invoke.MethodHandles.byteArrayViewVarHandle().
   2018       return ByteArrayViewAccessor<int64_t>::Dispatch(access_mode,
   2019                                                       data,
   2020                                                       checked_offset32,
   2021                                                       byte_swap,
   2022                                                       &getter,
   2023                                                       result);
   2024     case Primitive::Type::kPrimNot:
   2025     case Primitive::kPrimBoolean:
   2026     case Primitive::kPrimByte:
   2027     case Primitive::kPrimVoid:
   2028       // These are not supported for byte array views and not instantiable.
   2029       break;
   2030   }
   2031   LOG(FATAL) << "Unreachable: Unexpected primitive " << primitive_type;
   2032   UNREACHABLE();
   2033 }
   2034 
   2035 }  // namespace mirror
   2036 }  // namespace art
   2037