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