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