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