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 "common_runtime_test.h"
     20 #include "mirror/array-inl.h"
     21 #include "mirror/art_field-inl.h"
     22 #include "mirror/art_method-inl.h"
     23 #include "scoped_thread_state_change.h"
     24 
     25 namespace art {
     26 
     27 class TransactionTest : public CommonRuntimeTest {};
     28 
     29 TEST_F(TransactionTest, Object_class) {
     30   ScopedObjectAccess soa(Thread::Current());
     31   StackHandleScope<2> hs(soa.Self());
     32   Handle<mirror::Class> h_klass(
     33       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
     34   ASSERT_TRUE(h_klass.Get() != nullptr);
     35 
     36   Transaction transaction;
     37   Runtime::Current()->EnterTransactionMode(&transaction);
     38   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
     39   ASSERT_TRUE(h_obj.Get() != nullptr);
     40   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
     41   Runtime::Current()->ExitTransactionMode();
     42 
     43   // Aborting transaction must not clear the Object::class field.
     44   transaction.Abort();
     45   EXPECT_EQ(h_obj->GetClass(), h_klass.Get());
     46 }
     47 
     48 TEST_F(TransactionTest, Object_monitor) {
     49   ScopedObjectAccess soa(Thread::Current());
     50   StackHandleScope<2> hs(soa.Self());
     51   Handle<mirror::Class> h_klass(
     52       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
     53   ASSERT_TRUE(h_klass.Get() != nullptr);
     54   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
     55   ASSERT_TRUE(h_obj.Get() != nullptr);
     56   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
     57 
     58   // Lock object's monitor outside the transaction.
     59   h_obj->MonitorEnter(soa.Self());
     60   uint32_t old_lock_word = h_obj->GetLockWord(false).GetValue();
     61 
     62   Transaction transaction;
     63   Runtime::Current()->EnterTransactionMode(&transaction);
     64   // Unlock object's monitor inside the transaction.
     65   h_obj->MonitorExit(soa.Self());
     66   uint32_t new_lock_word = h_obj->GetLockWord(false).GetValue();
     67   Runtime::Current()->ExitTransactionMode();
     68 
     69   // Aborting transaction must not clear the Object::class field.
     70   transaction.Abort();
     71   uint32_t aborted_lock_word = h_obj->GetLockWord(false).GetValue();
     72   EXPECT_NE(old_lock_word, new_lock_word);
     73   EXPECT_EQ(aborted_lock_word, new_lock_word);
     74 }
     75 
     76 TEST_F(TransactionTest, Array_length) {
     77   ScopedObjectAccess soa(Thread::Current());
     78   StackHandleScope<2> hs(soa.Self());
     79   Handle<mirror::Class> h_klass(
     80       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Object;")));
     81   ASSERT_TRUE(h_klass.Get() != nullptr);
     82 
     83   constexpr int32_t kArraySize = 2;
     84 
     85   Transaction transaction;
     86   Runtime::Current()->EnterTransactionMode(&transaction);
     87 
     88   // Allocate an array during transaction.
     89   Handle<mirror::Array> h_obj(
     90       hs.NewHandle(
     91           mirror::Array::Alloc<true>(soa.Self(), h_klass.Get(), kArraySize,
     92                                      h_klass->GetComponentSize(),
     93                                      Runtime::Current()->GetHeap()->GetCurrentAllocator())));
     94   ASSERT_TRUE(h_obj.Get() != nullptr);
     95   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
     96   Runtime::Current()->ExitTransactionMode();
     97 
     98   // Aborting transaction must not clear the Object::class field.
     99   transaction.Abort();
    100   EXPECT_EQ(h_obj->GetLength(), kArraySize);
    101 }
    102 
    103 TEST_F(TransactionTest, StaticFieldsTest) {
    104   ScopedObjectAccess soa(Thread::Current());
    105   StackHandleScope<4> hs(soa.Self());
    106   Handle<mirror::ClassLoader> class_loader(
    107       hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction"))));
    108   ASSERT_TRUE(class_loader.Get() != nullptr);
    109 
    110   Handle<mirror::Class> h_klass(
    111       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticFieldsTest;", class_loader)));
    112   ASSERT_TRUE(h_klass.Get() != nullptr);
    113   class_linker_->EnsureInitialized(h_klass, true, true);
    114   ASSERT_TRUE(h_klass->IsInitialized());
    115 
    116   // Lookup fields.
    117   mirror::ArtField* booleanField = h_klass->FindDeclaredStaticField("booleanField", "Z");
    118   ASSERT_TRUE(booleanField != nullptr);
    119   ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
    120   ASSERT_EQ(booleanField->GetBoolean(h_klass.Get()), false);
    121 
    122   mirror::ArtField* byteField = h_klass->FindDeclaredStaticField("byteField", "B");
    123   ASSERT_TRUE(byteField != nullptr);
    124   ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
    125   ASSERT_EQ(byteField->GetByte(h_klass.Get()), 0);
    126 
    127   mirror::ArtField* charField = h_klass->FindDeclaredStaticField("charField", "C");
    128   ASSERT_TRUE(charField != nullptr);
    129   ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
    130   ASSERT_EQ(charField->GetChar(h_klass.Get()), 0u);
    131 
    132   mirror::ArtField* shortField = h_klass->FindDeclaredStaticField("shortField", "S");
    133   ASSERT_TRUE(shortField != nullptr);
    134   ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
    135   ASSERT_EQ(shortField->GetShort(h_klass.Get()), 0);
    136 
    137   mirror::ArtField* intField = h_klass->FindDeclaredStaticField("intField", "I");
    138   ASSERT_TRUE(intField != nullptr);
    139   ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
    140   ASSERT_EQ(intField->GetInt(h_klass.Get()), 0);
    141 
    142   mirror::ArtField* longField = h_klass->FindDeclaredStaticField("longField", "J");
    143   ASSERT_TRUE(longField != nullptr);
    144   ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
    145   ASSERT_EQ(longField->GetLong(h_klass.Get()), static_cast<int64_t>(0));
    146 
    147   mirror::ArtField* floatField = h_klass->FindDeclaredStaticField("floatField", "F");
    148   ASSERT_TRUE(floatField != nullptr);
    149   ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
    150   ASSERT_EQ(floatField->GetFloat(h_klass.Get()), static_cast<float>(0.0f));
    151 
    152   mirror::ArtField* doubleField = h_klass->FindDeclaredStaticField("doubleField", "D");
    153   ASSERT_TRUE(doubleField != nullptr);
    154   ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
    155   ASSERT_EQ(doubleField->GetDouble(h_klass.Get()), static_cast<double>(0.0));
    156 
    157   mirror::ArtField* objectField = h_klass->FindDeclaredStaticField("objectField",
    158                                                                       "Ljava/lang/Object;");
    159   ASSERT_TRUE(objectField != nullptr);
    160   ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
    161   ASSERT_EQ(objectField->GetObject(h_klass.Get()), nullptr);
    162 
    163   // Create a java.lang.Object instance to set objectField.
    164   Handle<mirror::Class> object_klass(
    165       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
    166   ASSERT_TRUE(object_klass.Get() != nullptr);
    167   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    168   ASSERT_TRUE(h_obj.Get() != nullptr);
    169   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    170 
    171   // Modify fields inside transaction and abort it.
    172   Transaction transaction;
    173   Runtime::Current()->EnterTransactionMode(&transaction);
    174   booleanField->SetBoolean<true>(h_klass.Get(), true);
    175   byteField->SetByte<true>(h_klass.Get(), 1);
    176   charField->SetChar<true>(h_klass.Get(), 1u);
    177   shortField->SetShort<true>(h_klass.Get(), 1);
    178   intField->SetInt<true>(h_klass.Get(), 1);
    179   longField->SetLong<true>(h_klass.Get(), 1);
    180   floatField->SetFloat<true>(h_klass.Get(), 1.0);
    181   doubleField->SetDouble<true>(h_klass.Get(), 1.0);
    182   objectField->SetObject<true>(h_klass.Get(), h_obj.Get());
    183   Runtime::Current()->ExitTransactionMode();
    184   transaction.Abort();
    185 
    186   // Check values have properly been restored to their original (default) value.
    187   EXPECT_EQ(booleanField->GetBoolean(h_klass.Get()), false);
    188   EXPECT_EQ(byteField->GetByte(h_klass.Get()), 0);
    189   EXPECT_EQ(charField->GetChar(h_klass.Get()), 0u);
    190   EXPECT_EQ(shortField->GetShort(h_klass.Get()), 0);
    191   EXPECT_EQ(intField->GetInt(h_klass.Get()), 0);
    192   EXPECT_EQ(longField->GetLong(h_klass.Get()), static_cast<int64_t>(0));
    193   EXPECT_EQ(floatField->GetFloat(h_klass.Get()), static_cast<float>(0.0f));
    194   EXPECT_EQ(doubleField->GetDouble(h_klass.Get()), static_cast<double>(0.0));
    195   EXPECT_EQ(objectField->GetObject(h_klass.Get()), nullptr);
    196 }
    197 
    198 TEST_F(TransactionTest, InstanceFieldsTest) {
    199   ScopedObjectAccess soa(Thread::Current());
    200   StackHandleScope<5> hs(soa.Self());
    201   Handle<mirror::ClassLoader> class_loader(
    202       hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction"))));
    203   ASSERT_TRUE(class_loader.Get() != nullptr);
    204 
    205   Handle<mirror::Class> h_klass(
    206       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInstanceFieldsTest;", class_loader)));
    207   ASSERT_TRUE(h_klass.Get() != nullptr);
    208   class_linker_->EnsureInitialized(h_klass, true, true);
    209   ASSERT_TRUE(h_klass->IsInitialized());
    210 
    211   // Allocate an InstanceFieldTest object.
    212   Handle<mirror::Object> h_instance(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    213   ASSERT_TRUE(h_instance.Get() != nullptr);
    214 
    215   // Lookup fields.
    216   mirror::ArtField* booleanField = h_klass->FindDeclaredInstanceField("booleanField", "Z");
    217   ASSERT_TRUE(booleanField != nullptr);
    218   ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
    219   ASSERT_EQ(booleanField->GetBoolean(h_instance.Get()), false);
    220 
    221   mirror::ArtField* byteField = h_klass->FindDeclaredInstanceField("byteField", "B");
    222   ASSERT_TRUE(byteField != nullptr);
    223   ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
    224   ASSERT_EQ(byteField->GetByte(h_instance.Get()), 0);
    225 
    226   mirror::ArtField* charField = h_klass->FindDeclaredInstanceField("charField", "C");
    227   ASSERT_TRUE(charField != nullptr);
    228   ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
    229   ASSERT_EQ(charField->GetChar(h_instance.Get()), 0u);
    230 
    231   mirror::ArtField* shortField = h_klass->FindDeclaredInstanceField("shortField", "S");
    232   ASSERT_TRUE(shortField != nullptr);
    233   ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
    234   ASSERT_EQ(shortField->GetShort(h_instance.Get()), 0);
    235 
    236   mirror::ArtField* intField = h_klass->FindDeclaredInstanceField("intField", "I");
    237   ASSERT_TRUE(intField != nullptr);
    238   ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
    239   ASSERT_EQ(intField->GetInt(h_instance.Get()), 0);
    240 
    241   mirror::ArtField* longField = h_klass->FindDeclaredInstanceField("longField", "J");
    242   ASSERT_TRUE(longField != nullptr);
    243   ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
    244   ASSERT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0));
    245 
    246   mirror::ArtField* floatField = h_klass->FindDeclaredInstanceField("floatField", "F");
    247   ASSERT_TRUE(floatField != nullptr);
    248   ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
    249   ASSERT_EQ(floatField->GetFloat(h_instance.Get()), static_cast<float>(0.0f));
    250 
    251   mirror::ArtField* doubleField = h_klass->FindDeclaredInstanceField("doubleField", "D");
    252   ASSERT_TRUE(doubleField != nullptr);
    253   ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
    254   ASSERT_EQ(doubleField->GetDouble(h_instance.Get()), static_cast<double>(0.0));
    255 
    256   mirror::ArtField* objectField = h_klass->FindDeclaredInstanceField("objectField",
    257                                                                         "Ljava/lang/Object;");
    258   ASSERT_TRUE(objectField != nullptr);
    259   ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
    260   ASSERT_EQ(objectField->GetObject(h_instance.Get()), nullptr);
    261 
    262   // Create a java.lang.Object instance to set objectField.
    263   Handle<mirror::Class> object_klass(
    264       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
    265   ASSERT_TRUE(object_klass.Get() != nullptr);
    266   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    267   ASSERT_TRUE(h_obj.Get() != nullptr);
    268   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    269 
    270   // Modify fields inside transaction and abort it.
    271   Transaction transaction;
    272   Runtime::Current()->EnterTransactionMode(&transaction);
    273   booleanField->SetBoolean<true>(h_instance.Get(), true);
    274   byteField->SetByte<true>(h_instance.Get(), 1);
    275   charField->SetChar<true>(h_instance.Get(), 1u);
    276   shortField->SetShort<true>(h_instance.Get(), 1);
    277   intField->SetInt<true>(h_instance.Get(), 1);
    278   longField->SetLong<true>(h_instance.Get(), 1);
    279   floatField->SetFloat<true>(h_instance.Get(), 1.0);
    280   doubleField->SetDouble<true>(h_instance.Get(), 1.0);
    281   objectField->SetObject<true>(h_instance.Get(), h_obj.Get());
    282   Runtime::Current()->ExitTransactionMode();
    283   transaction.Abort();
    284 
    285   // Check values have properly been restored to their original (default) value.
    286   EXPECT_EQ(booleanField->GetBoolean(h_instance.Get()), false);
    287   EXPECT_EQ(byteField->GetByte(h_instance.Get()), 0);
    288   EXPECT_EQ(charField->GetChar(h_instance.Get()), 0u);
    289   EXPECT_EQ(shortField->GetShort(h_instance.Get()), 0);
    290   EXPECT_EQ(intField->GetInt(h_instance.Get()), 0);
    291   EXPECT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0));
    292   EXPECT_EQ(floatField->GetFloat(h_instance.Get()), static_cast<float>(0.0f));
    293   EXPECT_EQ(doubleField->GetDouble(h_instance.Get()), static_cast<double>(0.0));
    294   EXPECT_EQ(objectField->GetObject(h_instance.Get()), nullptr);
    295 }
    296 
    297 
    298 TEST_F(TransactionTest, StaticArrayFieldsTest) {
    299   ScopedObjectAccess soa(Thread::Current());
    300   StackHandleScope<4> hs(soa.Self());
    301   Handle<mirror::ClassLoader> class_loader(
    302       hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction"))));
    303   ASSERT_TRUE(class_loader.Get() != nullptr);
    304 
    305   Handle<mirror::Class> h_klass(
    306       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStaticArrayFieldsTest;", class_loader)));
    307   ASSERT_TRUE(h_klass.Get() != nullptr);
    308   class_linker_->EnsureInitialized(h_klass, true, true);
    309   ASSERT_TRUE(h_klass->IsInitialized());
    310 
    311   // Lookup fields.
    312   mirror::ArtField* booleanArrayField = h_klass->FindDeclaredStaticField("booleanArrayField", "[Z");
    313   ASSERT_TRUE(booleanArrayField != nullptr);
    314   mirror::BooleanArray* booleanArray = booleanArrayField->GetObject(h_klass.Get())->AsBooleanArray();
    315   ASSERT_TRUE(booleanArray != nullptr);
    316   ASSERT_EQ(booleanArray->GetLength(), 1);
    317   ASSERT_EQ(booleanArray->GetWithoutChecks(0), false);
    318 
    319   mirror::ArtField* byteArrayField = h_klass->FindDeclaredStaticField("byteArrayField", "[B");
    320   ASSERT_TRUE(byteArrayField != nullptr);
    321   mirror::ByteArray* byteArray = byteArrayField->GetObject(h_klass.Get())->AsByteArray();
    322   ASSERT_TRUE(byteArray != nullptr);
    323   ASSERT_EQ(byteArray->GetLength(), 1);
    324   ASSERT_EQ(byteArray->GetWithoutChecks(0), 0);
    325 
    326   mirror::ArtField* charArrayField = h_klass->FindDeclaredStaticField("charArrayField", "[C");
    327   ASSERT_TRUE(charArrayField != nullptr);
    328   mirror::CharArray* charArray = charArrayField->GetObject(h_klass.Get())->AsCharArray();
    329   ASSERT_TRUE(charArray != nullptr);
    330   ASSERT_EQ(charArray->GetLength(), 1);
    331   ASSERT_EQ(charArray->GetWithoutChecks(0), 0u);
    332 
    333   mirror::ArtField* shortArrayField = h_klass->FindDeclaredStaticField("shortArrayField", "[S");
    334   ASSERT_TRUE(shortArrayField != nullptr);
    335   mirror::ShortArray* shortArray = shortArrayField->GetObject(h_klass.Get())->AsShortArray();
    336   ASSERT_TRUE(shortArray != nullptr);
    337   ASSERT_EQ(shortArray->GetLength(), 1);
    338   ASSERT_EQ(shortArray->GetWithoutChecks(0), 0);
    339 
    340   mirror::ArtField* intArrayField = h_klass->FindDeclaredStaticField("intArrayField", "[I");
    341   ASSERT_TRUE(intArrayField != nullptr);
    342   mirror::IntArray* intArray = intArrayField->GetObject(h_klass.Get())->AsIntArray();
    343   ASSERT_TRUE(intArray != nullptr);
    344   ASSERT_EQ(intArray->GetLength(), 1);
    345   ASSERT_EQ(intArray->GetWithoutChecks(0), 0);
    346 
    347   mirror::ArtField* longArrayField = h_klass->FindDeclaredStaticField("longArrayField", "[J");
    348   ASSERT_TRUE(longArrayField != nullptr);
    349   mirror::LongArray* longArray = longArrayField->GetObject(h_klass.Get())->AsLongArray();
    350   ASSERT_TRUE(longArray != nullptr);
    351   ASSERT_EQ(longArray->GetLength(), 1);
    352   ASSERT_EQ(longArray->GetWithoutChecks(0), static_cast<int64_t>(0));
    353 
    354   mirror::ArtField* floatArrayField = h_klass->FindDeclaredStaticField("floatArrayField", "[F");
    355   ASSERT_TRUE(floatArrayField != nullptr);
    356   mirror::FloatArray* floatArray = floatArrayField->GetObject(h_klass.Get())->AsFloatArray();
    357   ASSERT_TRUE(floatArray != nullptr);
    358   ASSERT_EQ(floatArray->GetLength(), 1);
    359   ASSERT_EQ(floatArray->GetWithoutChecks(0), static_cast<float>(0.0f));
    360 
    361   mirror::ArtField* doubleArrayField = h_klass->FindDeclaredStaticField("doubleArrayField", "[D");
    362   ASSERT_TRUE(doubleArrayField != nullptr);
    363   mirror::DoubleArray* doubleArray = doubleArrayField->GetObject(h_klass.Get())->AsDoubleArray();
    364   ASSERT_TRUE(doubleArray != nullptr);
    365   ASSERT_EQ(doubleArray->GetLength(), 1);
    366   ASSERT_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
    367 
    368   mirror::ArtField* objectArrayField = h_klass->FindDeclaredStaticField("objectArrayField",
    369                                                                            "[Ljava/lang/Object;");
    370   ASSERT_TRUE(objectArrayField != nullptr);
    371   mirror::ObjectArray<mirror::Object>* objectArray =
    372       objectArrayField->GetObject(h_klass.Get())->AsObjectArray<mirror::Object>();
    373   ASSERT_TRUE(objectArray != nullptr);
    374   ASSERT_EQ(objectArray->GetLength(), 1);
    375   ASSERT_EQ(objectArray->GetWithoutChecks(0), nullptr);
    376 
    377   // Create a java.lang.Object instance to set objectField.
    378   Handle<mirror::Class> object_klass(
    379       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
    380   ASSERT_TRUE(object_klass.Get() != nullptr);
    381   Handle<mirror::Object> h_obj(hs.NewHandle(h_klass->AllocObject(soa.Self())));
    382   ASSERT_TRUE(h_obj.Get() != nullptr);
    383   ASSERT_EQ(h_obj->GetClass(), h_klass.Get());
    384 
    385   // Modify fields inside transaction and abort it.
    386   Transaction transaction;
    387   Runtime::Current()->EnterTransactionMode(&transaction);
    388   booleanArray->SetWithoutChecks<true>(0, true);
    389   byteArray->SetWithoutChecks<true>(0, 1);
    390   charArray->SetWithoutChecks<true>(0, 1u);
    391   shortArray->SetWithoutChecks<true>(0, 1);
    392   intArray->SetWithoutChecks<true>(0, 1);
    393   longArray->SetWithoutChecks<true>(0, 1);
    394   floatArray->SetWithoutChecks<true>(0, 1.0);
    395   doubleArray->SetWithoutChecks<true>(0, 1.0);
    396   objectArray->SetWithoutChecks<true>(0, h_obj.Get());
    397   Runtime::Current()->ExitTransactionMode();
    398   transaction.Abort();
    399 
    400   // Check values have properly been restored to their original (default) value.
    401   EXPECT_EQ(booleanArray->GetWithoutChecks(0), false);
    402   EXPECT_EQ(byteArray->GetWithoutChecks(0), 0);
    403   EXPECT_EQ(charArray->GetWithoutChecks(0), 0u);
    404   EXPECT_EQ(shortArray->GetWithoutChecks(0), 0);
    405   EXPECT_EQ(intArray->GetWithoutChecks(0), 0);
    406   EXPECT_EQ(longArray->GetWithoutChecks(0), static_cast<int64_t>(0));
    407   EXPECT_EQ(floatArray->GetWithoutChecks(0), static_cast<float>(0.0f));
    408   EXPECT_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
    409   EXPECT_EQ(objectArray->GetWithoutChecks(0), nullptr);
    410 }
    411 
    412 TEST_F(TransactionTest, EmptyClass) {
    413   ScopedObjectAccess soa(Thread::Current());
    414   StackHandleScope<2> hs(soa.Self());
    415   Handle<mirror::ClassLoader> class_loader(
    416       hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction"))));
    417   ASSERT_TRUE(class_loader.Get() != nullptr);
    418 
    419   Handle<mirror::Class> h_klass(
    420       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$EmptyStatic;", class_loader)));
    421   ASSERT_TRUE(h_klass.Get() != nullptr);
    422   class_linker_->VerifyClass(h_klass);
    423   ASSERT_TRUE(h_klass->IsVerified());
    424 
    425   Transaction transaction;
    426   Runtime::Current()->EnterTransactionMode(&transaction);
    427   class_linker_->EnsureInitialized(h_klass, true, true);
    428   Runtime::Current()->ExitTransactionMode();
    429   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    430 }
    431 
    432 TEST_F(TransactionTest, StaticFieldClass) {
    433   ScopedObjectAccess soa(Thread::Current());
    434   StackHandleScope<2> hs(soa.Self());
    435   Handle<mirror::ClassLoader> class_loader(
    436       hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction"))));
    437   ASSERT_TRUE(class_loader.Get() != nullptr);
    438 
    439   Handle<mirror::Class> h_klass(
    440       hs.NewHandle(class_linker_->FindClass(soa.Self(), "LTransaction$StaticFieldClass;",
    441                                             class_loader)));
    442   ASSERT_TRUE(h_klass.Get() != nullptr);
    443   class_linker_->VerifyClass(h_klass);
    444   ASSERT_TRUE(h_klass->IsVerified());
    445 
    446   Transaction transaction;
    447   Runtime::Current()->EnterTransactionMode(&transaction);
    448   class_linker_->EnsureInitialized(h_klass, true, true);
    449   Runtime::Current()->ExitTransactionMode();
    450   ASSERT_FALSE(soa.Self()->IsExceptionPending());
    451 }
    452 
    453 TEST_F(TransactionTest, BlacklistedClass) {
    454   ScopedObjectAccess soa(Thread::Current());
    455   jobject jclass_loader = LoadDex("Transaction");
    456   StackHandleScope<2> hs(soa.Self());
    457   Handle<mirror::ClassLoader> class_loader(
    458       hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
    459   ASSERT_TRUE(class_loader.Get() != nullptr);
    460 
    461   // Load and verify java.lang.ExceptionInInitializerError and java.lang.InternalError which will
    462   // be thrown by class initialization due to native call.
    463   Handle<mirror::Class> h_klass(
    464       hs.NewHandle(class_linker_->FindSystemClass(soa.Self(),
    465                                                   "Ljava/lang/ExceptionInInitializerError;")));
    466   ASSERT_TRUE(h_klass.Get() != nullptr);
    467   class_linker_->VerifyClass(h_klass);
    468   ASSERT_TRUE(h_klass->IsVerified());
    469   h_klass.Assign(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/InternalError;"));
    470   ASSERT_TRUE(h_klass.Get() != nullptr);
    471   class_linker_->VerifyClass(h_klass);
    472   ASSERT_TRUE(h_klass->IsVerified());
    473 
    474   // Load and verify Transaction$NativeSupport used in class initialization.
    475   h_klass.Assign(class_linker_->FindClass(soa.Self(), "LTransaction$NativeSupport;",
    476                                              class_loader));
    477   ASSERT_TRUE(h_klass.Get() != nullptr);
    478   class_linker_->VerifyClass(h_klass);
    479   ASSERT_TRUE(h_klass->IsVerified());
    480 
    481   h_klass.Assign(class_linker_->FindClass(soa.Self(), "LTransaction$BlacklistedClass;",
    482                                              class_loader));
    483   ASSERT_TRUE(h_klass.Get() != nullptr);
    484   class_linker_->VerifyClass(h_klass);
    485   ASSERT_TRUE(h_klass->IsVerified());
    486 
    487   Transaction transaction;
    488   Runtime::Current()->EnterTransactionMode(&transaction);
    489   class_linker_->EnsureInitialized(h_klass, true, true);
    490   Runtime::Current()->ExitTransactionMode();
    491   ASSERT_TRUE(soa.Self()->IsExceptionPending());
    492 }
    493 
    494 
    495 }  // namespace art
    496