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