blob: 7859126764469a8adaa3c667066171e727f3d3b2 [file] [log] [blame]
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_TRANSACTION_H_
18#define ART_RUNTIME_TRANSACTION_H_
19
20#include "base/macros.h"
21#include "base/mutex.h"
Ian Rogers719d1a32014-03-06 12:13:39 -080022#include "object_callbacks.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010023#include "offsets.h"
24#include "primitive.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010025#include "safe_map.h"
26
27#include <list>
28#include <map>
29
30namespace art {
31namespace mirror {
32class Array;
33class Object;
34class String;
35}
36class InternTable;
37
38class Transaction {
39 public:
40 Transaction();
41 ~Transaction();
42
43 // Record object field changes.
44 void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
45 bool is_volatile)
46 LOCKS_EXCLUDED(log_lock_);
47 void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
48 bool is_volatile)
49 LOCKS_EXCLUDED(log_lock_);
50 void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
51 mirror::Object* value, bool is_volatile)
52 LOCKS_EXCLUDED(log_lock_);
53
54 // Record array change.
55 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
56 LOCKS_EXCLUDED(log_lock_)
57 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
58
59 // Record intern string table changes.
60 void RecordStrongStringInsertion(mirror::String* s, uint32_t hash_code)
61 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
62 LOCKS_EXCLUDED(log_lock_);
63 void RecordWeakStringInsertion(mirror::String* s, uint32_t hash_code)
64 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
65 LOCKS_EXCLUDED(log_lock_);
66 void RecordStrongStringRemoval(mirror::String* s, uint32_t hash_code)
67 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
68 LOCKS_EXCLUDED(log_lock_);
69 void RecordWeakStringRemoval(mirror::String* s, uint32_t hash_code)
70 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
71 LOCKS_EXCLUDED(log_lock_);
72
73 // Abort transaction by undoing all recorded changes.
74 void Abort()
75 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
76 LOCKS_EXCLUDED(log_lock_);
77
78 void VisitRoots(RootCallback* callback, void* arg)
79 LOCKS_EXCLUDED(log_lock_)
80 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
81
82 private:
83 class ObjectLog {
84 public:
85 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
86 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
87 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
88
89 void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
90 void VisitRoots(RootCallback* callback, void* arg);
91
92 size_t Size() const {
93 return field_values_.size();
94 }
95
96 private:
97 enum FieldValueKind {
98 k32Bits,
99 k64Bits,
100 kReference
101 };
102 struct FieldValue {
103 // TODO use JValue instead ?
104 uint64_t value;
105 FieldValueKind kind;
106 bool is_volatile;
107 };
108
109 void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
110 const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
111
112 // Maps field's offset to its value.
113 std::map<uint32_t, FieldValue> field_values_;
114 };
115
116 class ArrayLog {
117 public:
118 void LogValue(size_t index, uint64_t value);
119
120 void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100121
122 size_t Size() const {
123 return array_values_.size();
124 }
125
126 private:
127 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
128 uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
129
130 // Maps index to value.
131 // TODO use JValue instead ?
132 std::map<size_t, uint64_t> array_values_;
133 };
134
135 class InternStringLog {
136 public:
137 enum StringKind {
138 kStrongString,
139 kWeakString
140 };
141 enum StringOp {
142 kInsert,
143 kRemove
144 };
145 InternStringLog(mirror::String* s, uint32_t hash_code, StringKind kind, StringOp op)
146 : str_(s), hash_code_(hash_code), string_kind_(kind), string_op_(op) {
Sebastien Hertzee1d79a2014-02-21 15:46:30 +0100147 DCHECK(s != nullptr);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100148 }
149
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700150 void Undo(InternTable* intern_table)
151 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
152 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100153 void VisitRoots(RootCallback* callback, void* arg);
154
155 private:
156 mirror::String* str_;
157 uint32_t hash_code_;
158 StringKind string_kind_;
159 StringOp string_op_;
160 };
161
162 void LogInternedString(InternStringLog& log)
163 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
164 LOCKS_EXCLUDED(log_lock_);
165
166 void UndoObjectModifications()
167 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
168 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
169 void UndoArrayModifications()
170 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
171 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
172 void UndoInternStringTableModifications()
173 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700174 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
175 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100176
177 void VisitObjectLogs(RootCallback* callback, void* arg)
178 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
179 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
180 void VisitArrayLogs(RootCallback* callback, void* arg)
181 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
182 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
183 void VisitStringLogs(RootCallback* callback, void* arg)
184 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
185 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
186
187 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
188 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
189 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
190 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
191
192 DISALLOW_COPY_AND_ASSIGN(Transaction);
193};
194
195} // namespace art
196
197#endif // ART_RUNTIME_TRANSACTION_H_