Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2014 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 "transaction.h"
     18 
     19 #include "art_field-inl.h"
     20 #include "art_method-inl.h"
     21 #include "class_linker-inl.h"
     22 #include "common_runtime_test.h"
     23 #include "dex/dex_file.h"
     24 #include "mirror/array-inl.h"
     25 #include "scoped_thread_state_change-inl.h"
     26 
     27 namespace art {
     28 
     29 class TransactionTest : public CommonRuntimeTest {
     30  public:
     31   // Tests failing class initialization due to native call with transaction rollback.
     32   void testTransactionAbort(const char* tested_class_signature) {
     33     ScopedObjectAccess soa(Thread::Current());
     34     jobject jclass_loader = LoadDex("Transaction");
     35     StackHandleScope<2> hs(soa.Self());
     36     Handle<mirror::ClassLoader> class_loader(
     37         hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
     38     ASSERT_TRUE(class_loader != nullptr);
     39 
     40     // Load and initialize java.lang.ExceptionInInitializerError and the exception class used
     41     // to abort transaction so they can be thrown during class initialization if the transaction
     42     // aborts.
     43     MutableHandle<mirror::Class> h_klass(
     44         hs.NewHandle(class_linker_->FindSystemClass(soa.Self(),
     45                                                     "Ljava/lang/ExceptionInInitializerError;")));
     46     ASSERT_TRUE(h_klass != nullptr);
     47     class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
     48     ASSERT_TRUE(h_klass->IsInitialized());
     49 
     50     h_klass.Assign(class_linker_->FindSystemClass(soa.Self(),
     51                                                   Transaction::kAbortExceptionSignature));
     52     ASSERT_TRUE(h_klass != nullptr);
     53     class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
     54     ASSERT_TRUE(h_klass->IsInitialized());
     55 
     56     // Load and verify utility class.
     57     h_klass.Assign(class_linker_->FindClass(soa.Self(), "LTransaction$AbortHelperClass;",
     58                                             class_loader));
     59     ASSERT_TRUE(h_klass != nullptr);
     60     class_linker_->VerifyClass(soa.Self(), h_klass);
     61     ASSERT_TRUE(h_klass->IsVerified());
     62 
     63     // Load and verify tested class.
     64     h_klass.Assign(class_linker_->FindClass(soa.Self(), tested_class_signature, class_loader));
     65     ASSERT_TRUE(h_klass != nullptr);
     66     class_linker_->VerifyClass(soa.Self(), h_klass);
     67     ASSERT_TRUE(h_klass->IsVerified());
     68 
     69     ClassStatus old_status = h_klass->GetStatus();
     70     LockWord old_lock_word = h_klass->GetLockWord(false);
     71 
     72     Runtime::Current()->EnterTransactionMode();
     73     bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
     74     ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
     75     ASSERT_FALSE(success);
     76     ASSERT_TRUE(h_klass->IsErroneous());
     77     ASSERT_TRUE(soa.Self()->IsExceptionPending());
     78 
     79     // Check class's monitor get back to its original state without rolling back changes.
     80     LockWord new_lock_word = h_klass->GetLockWord(false);
     81     EXPECT_TRUE(LockWord::Equal<false>(old_lock_word, new_lock_word));
     82 
     83     // Check class status is rolled back properly.
     84     soa.Self()->ClearException();
     85     Runtime::Current()->RollbackAndExitTransactionMode();
     86     ASSERT_EQ(old_status, h_klass->GetStatus());
     87   }
     88 };
     89 
     90 // Tests object's class is preserved after transaction rollback.
     91 TEST_F(TransactionTest, Object_class) {
     92   ScopedObjectAccess soa(Thread::Current());
     93   StackHandleScope<2> hs(soa.Self());
     94   Handle<mirror::Class> h_klass(
     95       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
     96   ASSERT_TRUE(h_klass != nullptr);
     97 
     98   Runtime::Current()->EnterTransactionMode();
     99   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    100   ASSERT_TRUE(h_obj != nullptr);
    101   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    102   // Rolling back transaction's changes must not clear the Object::class field.
    103   Runtime::Current()->RollbackAndExitTransactionMode();
    104   EXPECT_EQ(h_obj->GetClass(), h_klass.Get());
    105 }
    106 
    107 // Tests object's monitor state is preserved after transaction rollback.
    108 TEST_F(TransactionTest, Object_monitor) {
    109   ScopedObjectAccess soa(Thread::Current());
    110   StackHandleScope<2> hs(soa.Self());
    111   Handle<mirror::Class> h_klass(
    112       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
    113   ASSERT_TRUE(h_klass != nullptr);
    114   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    115   ASSERT_TRUE(h_obj != nullptr);
    116   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    117 
    118   // Lock object's monitor outside the transaction.
    119   h_obj->MonitorEnter(soa.Self());
    120   LockWord old_lock_word = h_obj->GetLockWord(false);
    121 
    122   Runtime::Current()->EnterTransactionMode();
    123   // Unlock object's monitor inside the transaction.
    124   h_obj->MonitorExit(soa.Self());
    125   LockWord new_lock_word = h_obj->GetLockWord(false);
    126   // Rolling back transaction's changes must not change monitor's state.
    127   Runtime::Current()->RollbackAndExitTransactionMode();
    128 
    129   LockWord aborted_lock_word = h_obj->GetLockWord(false);
    130   EXPECT_FALSE(LockWord::Equal<false>(old_lock_word, new_lock_word));
    131   EXPECT_TRUE(LockWord::Equal<false>(aborted_lock_word, new_lock_word));
    132 }
    133 
    134 // Tests array's length is preserved after transaction rollback.
    135 TEST_F(TransactionTest, Array_length) {
    136   ScopedObjectAccess soa(Thread::Current());
    137   StackHandleScope<2> hs(soa.Self());
    138   Handle<mirror::Class> h_klass(
    139       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
    140   ASSERT_TRUE(h_klass != nullptr);
    141 
    142   constexpr int32_t kArraySize = 2;
    143 
    144   Runtime::Current()->EnterTransactionMode();
    145 
    146   // Allocate an array during transaction.
    147   Handle<mirror::Array> h_obj(
    148       hs.NewHandle(
    149           mirror::Array::Alloc<true>(soa.Self(), h_klass.Get(), kArraySize,
    150                                      h_klass->GetComponentSizeShift(),
    151                                      Runtime::Current()->GetHeap()->GetCurrentAllocator())));
    152   ASSERT_TRUE(h_obj != nullptr);
    153   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    154   Runtime::Current()->RollbackAndExitTransactionMode();
    155 
    156   // Rolling back transaction's changes must not reset array's length.
    157   EXPECT_EQ(h_obj->GetLength(), kArraySize);
    158 }
    159 
    160 // Tests static fields are reset to their default value after transaction rollback.
    161 TEST_F(TransactionTest, StaticFieldsTest) {
    162   ScopedObjectAccess soa(Thread::Current());
    163   StackHandleScope<4> hs(soa.Self());
    164   Handle<mirror::ClassLoader> class_loader(
    165       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
    166   ASSERT_TRUE(class_loader != nullptr);
    167 
    168   Handle<mirror::Class> h_klass(
    169       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticFieldsTest;", class_loader)));
    170   ASSERT_TRUE(h_klass != nullptr);
    171   bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
    172   ASSERT_TRUE(success);
    173   ASSERT_TRUE(h_klass->IsInitialized());
    174   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    175 
    176   // Lookup fields.
    177   ArtField* booleanField = h_klass->FindDeclaredStaticField("booleanField", "Z");
    178   ASSERT_TRUE(booleanField != nullptr);
    179   ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
    180   ASSERT_EQ(booleanField->GetBoolean(h_klass.Get()), false);
    181 
    182   ArtField* byteField = h_klass->FindDeclaredStaticField("byteField", "B");
    183   ASSERT_TRUE(byteField != nullptr);
    184   ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
    185   ASSERT_EQ(byteField->GetByte(h_klass.Get()), 0);
    186 
    187   ArtField* charField = h_klass->FindDeclaredStaticField("charField", "C");
    188   ASSERT_TRUE(charField != nullptr);
    189   ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
    190   ASSERT_EQ(charField->GetChar(h_klass.Get()), 0u);
    191 
    192   ArtField* shortField = h_klass->FindDeclaredStaticField("shortField", "S");
    193   ASSERT_TRUE(shortField != nullptr);
    194   ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
    195   ASSERT_EQ(shortField->GetShort(h_klass.Get()), 0);
    196 
    197   ArtField* intField = h_klass->FindDeclaredStaticField("intField", "I");
    198   ASSERT_TRUE(intField != nullptr);
    199   ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
    200   ASSERT_EQ(intField->GetInt(h_klass.Get()), 0);
    201 
    202   ArtField* longField = h_klass->FindDeclaredStaticField("longField", "J");
    203   ASSERT_TRUE(longField != nullptr);
    204   ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
    205   ASSERT_EQ(longField->GetLong(h_klass.Get()), static_cast<int64_t>(0));
    206 
    207   ArtField* floatField = h_klass->FindDeclaredStaticField("floatField", "F");
    208   ASSERT_TRUE(floatField != nullptr);
    209   ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
    210   ASSERT_FLOAT_EQ(floatField->GetFloat(h_klass.Get()), static_cast<float>(0.0f));
    211 
    212   ArtField* doubleField = h_klass->FindDeclaredStaticField("doubleField", "D");
    213   ASSERT_TRUE(doubleField != nullptr);
    214   ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
    215   ASSERT_DOUBLE_EQ(doubleField->GetDouble(h_klass.Get()), static_cast<double>(0.0));
    216 
    217   ArtField* objectField = h_klass->FindDeclaredStaticField("objectField",
    218                                                                    "Ljava/lang/Object;");
    219   ASSERT_TRUE(objectField != nullptr);
    220   ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
    221   ASSERT_EQ(objectField->GetObject(h_klass.Get()), nullptr);
    222 
    223   // Create a java.lang.Object instance to set objectField.
    224   Handle<mirror::Class> object_klass(
    225       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
    226   ASSERT_TRUE(object_klass != nullptr);
    227   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    228   ASSERT_TRUE(h_obj != nullptr);
    229   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    230 
    231   // Modify fields inside transaction then rollback changes.
    232   Runtime::Current()->EnterTransactionMode();
    233   booleanField->SetBoolean<true>(h_klass.Get(), true);
    234   byteField->SetByte<true>(h_klass.Get(), 1);
    235   charField->SetChar<true>(h_klass.Get(), 1u);
    236   shortField->SetShort<true>(h_klass.Get(), 1);
    237   intField->SetInt<true>(h_klass.Get(), 1);
    238   longField->SetLong<true>(h_klass.Get(), 1);
    239   floatField->SetFloat<true>(h_klass.Get(), 1.0);
    240   doubleField->SetDouble<true>(h_klass.Get(), 1.0);
    241   objectField->SetObject<true>(h_klass.Get(), h_obj.Get());
    242   Runtime::Current()->RollbackAndExitTransactionMode();
    243 
    244   // Check values have properly been restored to their original (default) value.
    245   EXPECT_EQ(booleanField->GetBoolean(h_klass.Get()), false);
    246   EXPECT_EQ(byteField->GetByte(h_klass.Get()), 0);
    247   EXPECT_EQ(charField->GetChar(h_klass.Get()), 0u);
    248   EXPECT_EQ(shortField->GetShort(h_klass.Get()), 0);
    249   EXPECT_EQ(intField->GetInt(h_klass.Get()), 0);
    250   EXPECT_EQ(longField->GetLong(h_klass.Get()), static_cast<int64_t>(0));
    251   EXPECT_FLOAT_EQ(floatField->GetFloat(h_klass.Get()), static_cast<float>(0.0f));
    252   EXPECT_DOUBLE_EQ(doubleField->GetDouble(h_klass.Get()), static_cast<double>(0.0));
    253   EXPECT_EQ(objectField->GetObject(h_klass.Get()), nullptr);
    254 }
    255 
    256 // Tests instance fields are reset to their default value after transaction rollback.
    257 TEST_F(TransactionTest, InstanceFieldsTest) {
    258   ScopedObjectAccess soa(Thread::Current());
    259   StackHandleScope<5> hs(soa.Self());
    260   Handle<mirror::ClassLoader> class_loader(
    261       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
    262   ASSERT_TRUE(class_loader != nullptr);
    263 
    264   Handle<mirror::Class> h_klass(
    265       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInstanceFieldsTest;", class_loader)));
    266   ASSERT_TRUE(h_klass != nullptr);
    267   bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
    268   ASSERT_TRUE(success);
    269   ASSERT_TRUE(h_klass->IsInitialized());
    270   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    271 
    272   // Allocate an InstanceFieldTest object.
    273   Handle<mirror::Object> h_instance(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    274   ASSERT_TRUE(h_instance != nullptr);
    275 
    276   // Lookup fields.
    277   ArtField* booleanField = h_klass->FindDeclaredInstanceField("booleanField", "Z");
    278   ASSERT_TRUE(booleanField != nullptr);
    279   ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
    280   ASSERT_EQ(booleanField->GetBoolean(h_instance.Get()), false);
    281 
    282   ArtField* byteField = h_klass->FindDeclaredInstanceField("byteField", "B");
    283   ASSERT_TRUE(byteField != nullptr);
    284   ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
    285   ASSERT_EQ(byteField->GetByte(h_instance.Get()), 0);
    286 
    287   ArtField* charField = h_klass->FindDeclaredInstanceField("charField", "C");
    288   ASSERT_TRUE(charField != nullptr);
    289   ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
    290   ASSERT_EQ(charField->GetChar(h_instance.Get()), 0u);
    291 
    292   ArtField* shortField = h_klass->FindDeclaredInstanceField("shortField", "S");
    293   ASSERT_TRUE(shortField != nullptr);
    294   ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
    295   ASSERT_EQ(shortField->GetShort(h_instance.Get()), 0);
    296 
    297   ArtField* intField = h_klass->FindDeclaredInstanceField("intField", "I");
    298   ASSERT_TRUE(intField != nullptr);
    299   ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
    300   ASSERT_EQ(intField->GetInt(h_instance.Get()), 0);
    301 
    302   ArtField* longField = h_klass->FindDeclaredInstanceField("longField", "J");
    303   ASSERT_TRUE(longField != nullptr);
    304   ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
    305   ASSERT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0));
    306 
    307   ArtField* floatField = h_klass->FindDeclaredInstanceField("floatField", "F");
    308   ASSERT_TRUE(floatField != nullptr);
    309   ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
    310   ASSERT_FLOAT_EQ(floatField->GetFloat(h_instance.Get()), static_cast<float>(0.0f));
    311 
    312   ArtField* doubleField = h_klass->FindDeclaredInstanceField("doubleField", "D");
    313   ASSERT_TRUE(doubleField != nullptr);
    314   ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
    315   ASSERT_DOUBLE_EQ(doubleField->GetDouble(h_instance.Get()), static_cast<double>(0.0));
    316 
    317   ArtField* objectField = h_klass->FindDeclaredInstanceField("objectField",
    318                                                                         "Ljava/lang/Object;");
    319   ASSERT_TRUE(objectField != nullptr);
    320   ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
    321   ASSERT_EQ(objectField->GetObject(h_instance.Get()), nullptr);
    322 
    323   // Create a java.lang.Object instance to set objectField.
    324   Handle<mirror::Class> object_klass(
    325       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
    326   ASSERT_TRUE(object_klass != nullptr);
    327   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    328   ASSERT_TRUE(h_obj != nullptr);
    329   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    330 
    331   // Modify fields inside transaction then rollback changes.
    332   Runtime::Current()->EnterTransactionMode();
    333   booleanField->SetBoolean<true>(h_instance.Get(), true);
    334   byteField->SetByte<true>(h_instance.Get(), 1);
    335   charField->SetChar<true>(h_instance.Get(), 1u);
    336   shortField->SetShort<true>(h_instance.Get(), 1);
    337   intField->SetInt<true>(h_instance.Get(), 1);
    338   longField->SetLong<true>(h_instance.Get(), 1);
    339   floatField->SetFloat<true>(h_instance.Get(), 1.0);
    340   doubleField->SetDouble<true>(h_instance.Get(), 1.0);
    341   objectField->SetObject<true>(h_instance.Get(), h_obj.Get());
    342   Runtime::Current()->RollbackAndExitTransactionMode();
    343 
    344   // Check values have properly been restored to their original (default) value.
    345   EXPECT_EQ(booleanField->GetBoolean(h_instance.Get()), false);
    346   EXPECT_EQ(byteField->GetByte(h_instance.Get()), 0);
    347   EXPECT_EQ(charField->GetChar(h_instance.Get()), 0u);
    348   EXPECT_EQ(shortField->GetShort(h_instance.Get()), 0);
    349   EXPECT_EQ(intField->GetInt(h_instance.Get()), 0);
    350   EXPECT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0));
    351   EXPECT_FLOAT_EQ(floatField->GetFloat(h_instance.Get()), static_cast<float>(0.0f));
    352   EXPECT_DOUBLE_EQ(doubleField->GetDouble(h_instance.Get()), static_cast<double>(0.0));
    353   EXPECT_EQ(objectField->GetObject(h_instance.Get()), nullptr);
    354 }
    355 
    356 // Tests static array fields are reset to their default value after transaction rollback.
    357 TEST_F(TransactionTest, StaticArrayFieldsTest) {
    358   ScopedObjectAccess soa(Thread::Current());
    359   StackHandleScope<4> hs(soa.Self());
    360   Handle<mirror::ClassLoader> class_loader(
    361       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
    362   ASSERT_TRUE(class_loader != nullptr);
    363 
    364   Handle<mirror::Class> h_klass(
    365       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticArrayFieldsTest;", class_loader)));
    366   ASSERT_TRUE(h_klass != nullptr);
    367   bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
    368   ASSERT_TRUE(success);
    369   ASSERT_TRUE(h_klass->IsInitialized());
    370   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    371 
    372   // Lookup fields.
    373   ArtField* booleanArrayField = h_klass->FindDeclaredStaticField("booleanArrayField", "[Z");
    374   ASSERT_TRUE(booleanArrayField != nullptr);
    375   mirror::BooleanArray* booleanArray = booleanArrayField->GetObject(h_klass.Get())->AsBooleanArray();
    376   ASSERT_TRUE(booleanArray != nullptr);
    377   ASSERT_EQ(booleanArray->GetLength(), 1);
    378   ASSERT_EQ(booleanArray->GetWithoutChecks(0), false);
    379 
    380   ArtField* byteArrayField = h_klass->FindDeclaredStaticField("byteArrayField", "[B");
    381   ASSERT_TRUE(byteArrayField != nullptr);
    382   mirror::ByteArray* byteArray = byteArrayField->GetObject(h_klass.Get())->AsByteArray();
    383   ASSERT_TRUE(byteArray != nullptr);
    384   ASSERT_EQ(byteArray->GetLength(), 1);
    385   ASSERT_EQ(byteArray->GetWithoutChecks(0), 0);
    386 
    387   ArtField* charArrayField = h_klass->FindDeclaredStaticField("charArrayField", "[C");
    388   ASSERT_TRUE(charArrayField != nullptr);
    389   mirror::CharArray* charArray = charArrayField->GetObject(h_klass.Get())->AsCharArray();
    390   ASSERT_TRUE(charArray != nullptr);
    391   ASSERT_EQ(charArray->GetLength(), 1);
    392   ASSERT_EQ(charArray->GetWithoutChecks(0), 0u);
    393 
    394   ArtField* shortArrayField = h_klass->FindDeclaredStaticField("shortArrayField", "[S");
    395   ASSERT_TRUE(shortArrayField != nullptr);
    396   mirror::ShortArray* shortArray = shortArrayField->GetObject(h_klass.Get())->AsShortArray();
    397   ASSERT_TRUE(shortArray != nullptr);
    398   ASSERT_EQ(shortArray->GetLength(), 1);
    399   ASSERT_EQ(shortArray->GetWithoutChecks(0), 0);
    400 
    401   ArtField* intArrayField = h_klass->FindDeclaredStaticField("intArrayField", "[I");
    402   ASSERT_TRUE(intArrayField != nullptr);
    403   mirror::IntArray* intArray = intArrayField->GetObject(h_klass.Get())->AsIntArray();
    404   ASSERT_TRUE(intArray != nullptr);
    405   ASSERT_EQ(intArray->GetLength(), 1);
    406   ASSERT_EQ(intArray->GetWithoutChecks(0), 0);
    407 
    408   ArtField* longArrayField = h_klass->FindDeclaredStaticField("longArrayField", "[J");
    409   ASSERT_TRUE(longArrayField != nullptr);
    410   mirror::LongArray* longArray = longArrayField->GetObject(h_klass.Get())->AsLongArray();
    411   ASSERT_TRUE(longArray != nullptr);
    412   ASSERT_EQ(longArray->GetLength(), 1);
    413   ASSERT_EQ(longArray->GetWithoutChecks(0), static_cast<int64_t>(0));
    414 
    415   ArtField* floatArrayField = h_klass->FindDeclaredStaticField("floatArrayField", "[F");
    416   ASSERT_TRUE(floatArrayField != nullptr);
    417   mirror::FloatArray* floatArray = floatArrayField->GetObject(h_klass.Get())->AsFloatArray();
    418   ASSERT_TRUE(floatArray != nullptr);
    419   ASSERT_EQ(floatArray->GetLength(), 1);
    420   ASSERT_FLOAT_EQ(floatArray->GetWithoutChecks(0), static_cast<float>(0.0f));
    421 
    422   ArtField* doubleArrayField = h_klass->FindDeclaredStaticField("doubleArrayField", "[D");
    423   ASSERT_TRUE(doubleArrayField != nullptr);
    424   mirror::DoubleArray* doubleArray = doubleArrayField->GetObject(h_klass.Get())->AsDoubleArray();
    425   ASSERT_TRUE(doubleArray != nullptr);
    426   ASSERT_EQ(doubleArray->GetLength(), 1);
    427   ASSERT_DOUBLE_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
    428 
    429   ArtField* objectArrayField = h_klass->FindDeclaredStaticField("objectArrayField",
    430                                                                            "[Ljava/lang/Object;");
    431   ASSERT_TRUE(objectArrayField != nullptr);
    432   mirror::ObjectArray<mirror::Object>* objectArray =
    433       objectArrayField->GetObject(h_klass.Get())->AsObjectArray<mirror::Object>();
    434   ASSERT_TRUE(objectArray != nullptr);
    435   ASSERT_EQ(objectArray->GetLength(), 1);
    436   ASSERT_EQ(objectArray->GetWithoutChecks(0), nullptr);
    437 
    438   // Create a java.lang.Object instance to set objectField.
    439   Handle<mirror::Class> object_klass(
    440       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
    441   ASSERT_TRUE(object_klass != nullptr);
    442   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    443   ASSERT_TRUE(h_obj != nullptr);
    444   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    445 
    446   // Modify fields inside transaction then rollback changes.
    447   Runtime::Current()->EnterTransactionMode();
    448   booleanArray->SetWithoutChecks<true>(0, true);
    449   byteArray->SetWithoutChecks<true>(0, 1);
    450   charArray->SetWithoutChecks<true>(0, 1u);
    451   shortArray->SetWithoutChecks<true>(0, 1);
    452   intArray->SetWithoutChecks<true>(0, 1);
    453   longArray->SetWithoutChecks<true>(0, 1);
    454   floatArray->SetWithoutChecks<true>(0, 1.0);
    455   doubleArray->SetWithoutChecks<true>(0, 1.0);
    456   objectArray->SetWithoutChecks<true>(0, h_obj.Get());
    457   Runtime::Current()->RollbackAndExitTransactionMode();
    458 
    459   // Check values have properly been restored to their original (default) value.
    460   EXPECT_EQ(booleanArray->GetWithoutChecks(0), false);
    461   EXPECT_EQ(byteArray->GetWithoutChecks(0), 0);
    462   EXPECT_EQ(charArray->GetWithoutChecks(0), 0u);
    463   EXPECT_EQ(shortArray->GetWithoutChecks(0), 0);
    464   EXPECT_EQ(intArray->GetWithoutChecks(0), 0);
    465   EXPECT_EQ(longArray->GetWithoutChecks(0), static_cast<int64_t>(0));
    466   EXPECT_FLOAT_EQ(floatArray->GetWithoutChecks(0), static_cast<float>(0.0f));
    467   EXPECT_DOUBLE_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
    468   EXPECT_EQ(objectArray->GetWithoutChecks(0), nullptr);
    469 }
    470 
    471 // Tests rolling back interned strings and resolved strings.
    472 TEST_F(TransactionTest, ResolveString) {
    473   ScopedObjectAccess soa(Thread::Current());
    474   StackHandleScope<3> hs(soa.Self());
    475   Handle<mirror::ClassLoader> class_loader(
    476       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
    477   ASSERT_TRUE(class_loader != nullptr);
    478 
    479   Handle<mirror::Class> h_klass(
    480       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$ResolveString;",
    481                                             class_loader)));
    482   ASSERT_TRUE(h_klass != nullptr);
    483 
    484   Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(h_klass->GetDexCache()));
    485   ASSERT_TRUE(h_dex_cache != nullptr);
    486   const DexFile* const dex_file = h_dex_cache->GetDexFile();
    487   ASSERT_TRUE(dex_file != nullptr);
    488 
    489   // Go search the dex file to find the string id of our string.
    490   static const char* kResolvedString = "ResolvedString";
    491   const DexFile::StringId* string_id = dex_file->FindStringId(kResolvedString);
    492   ASSERT_TRUE(string_id != nullptr);
    493   dex::StringIndex string_idx = dex_file->GetIndexForStringId(*string_id);
    494   ASSERT_TRUE(string_idx.IsValid());
    495   // String should only get resolved by the initializer.
    496   EXPECT_TRUE(class_linker_->LookupString(string_idx, h_dex_cache.Get()) == nullptr);
    497   EXPECT_TRUE(h_dex_cache->GetResolvedString(string_idx) == nullptr);
    498   // Do the transaction, then roll back.
    499   Runtime::Current()->EnterTransactionMode();
    500   bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
    501   ASSERT_TRUE(success);
    502   ASSERT_TRUE(h_klass->IsInitialized());
    503   // Make sure the string got resolved by the transaction.
    504   {
    505     ObjPtr<mirror::String> s =
    506         class_linker_->LookupString(string_idx, h_dex_cache.Get());
    507     ASSERT_TRUE(s != nullptr);
    508     EXPECT_STREQ(s->ToModifiedUtf8().c_str(), kResolvedString);
    509     EXPECT_EQ(s.Ptr(), h_dex_cache->GetResolvedString(string_idx));
    510   }
    511   Runtime::Current()->RollbackAndExitTransactionMode();
    512   // Check that the string did not stay resolved.
    513   EXPECT_TRUE(class_linker_->LookupString(string_idx, h_dex_cache.Get()) == nullptr);
    514   EXPECT_TRUE(h_dex_cache->GetResolvedString(string_idx) == nullptr);
    515   ASSERT_FALSE(h_klass->IsInitialized());
    516   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    517 }
    518 
    519 // Tests successful class initialization without class initializer.
    520 TEST_F(TransactionTest, EmptyClass) {
    521   ScopedObjectAccess soa(Thread::Current());
    522   StackHandleScope<2> hs(soa.Self());
    523   Handle<mirror::ClassLoader> class_loader(
    524       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
    525   ASSERT_TRUE(class_loader != nullptr);
    526 
    527   Handle<mirror::Class> h_klass(
    528       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$EmptyStatic;",
    529                                             class_loader)));
    530   ASSERT_TRUE(h_klass != nullptr);
    531   class_linker_->VerifyClass(soa.Self(), h_klass);
    532   ASSERT_TRUE(h_klass->IsVerified());
    533 
    534   Runtime::Current()->EnterTransactionMode();
    535   bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
    536   Runtime::Current()->ExitTransactionMode();
    537   ASSERT_TRUE(success);
    538   ASSERT_TRUE(h_klass->IsInitialized());
    539   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    540 }
    541 
    542 // Tests successful class initialization with class initializer.
    543 TEST_F(TransactionTest, StaticFieldClass) {
    544   ScopedObjectAccess soa(Thread::Current());
    545   StackHandleScope<2> hs(soa.Self());
    546   Handle<mirror::ClassLoader> class_loader(
    547       hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction"))));
    548   ASSERT_TRUE(class_loader != nullptr);
    549 
    550   Handle<mirror::Class> h_klass(
    551       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$StaticFieldClass;",
    552                                             class_loader)));
    553   ASSERT_TRUE(h_klass != nullptr);
    554   class_linker_->VerifyClass(soa.Self(), h_klass);
    555   ASSERT_TRUE(h_klass->IsVerified());
    556 
    557   Runtime::Current()->EnterTransactionMode();
    558   bool success = class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true);
    559   Runtime::Current()->ExitTransactionMode();
    560   ASSERT_TRUE(success);
    561   ASSERT_TRUE(h_klass->IsInitialized());
    562   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    563 }
    564 
    565 // Tests failing class initialization due to native call.
    566 TEST_F(TransactionTest, NativeCallAbortClass) {
    567   testTransactionAbort("LTransaction$NativeCallAbortClass;");
    568 }
    569 
    570 // Tests failing class initialization due to native call in a "synchronized" statement
    571 // (which must catch any exception, do the monitor-exit then re-throw the caught exception).
    572 TEST_F(TransactionTest, SynchronizedNativeCallAbortClass) {
    573   testTransactionAbort("LTransaction$SynchronizedNativeCallAbortClass;");
    574 }
    575 
    576 // Tests failing class initialization due to native call, even if an "all" catch handler
    577 // catches the exception thrown when aborting the transaction.
    578 TEST_F(TransactionTest, CatchNativeCallAbortClass) {
    579   testTransactionAbort("LTransaction$CatchNativeCallAbortClass;");
    580 }
    581 
    582 // Tests failing class initialization with multiple transaction aborts.
    583 TEST_F(TransactionTest, MultipleNativeCallAbortClass) {
    584   testTransactionAbort("LTransaction$MultipleNativeCallAbortClass;");
    585 }
    586 
    587 // Tests failing class initialization due to allocating instance of finalizable class.
    588 TEST_F(TransactionTest, FinalizableAbortClass) {
    589   testTransactionAbort("LTransaction$FinalizableAbortClass;");
    590 }
    591 }  // namespace art
    592