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