blob: 21d3c98054fa6eb43567e3575e2776e899a71fc7 [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.
Fred Shih37f05ef2014-07-16 18:38:08 -070044 void RecordWriteFieldBoolean(mirror::Object* obj, MemberOffset field_offset, uint8_t value,
45 bool is_volatile)
46 LOCKS_EXCLUDED(log_lock_);
47 void RecordWriteFieldByte(mirror::Object* obj, MemberOffset field_offset, int8_t value,
48 bool is_volatile)
49 LOCKS_EXCLUDED(log_lock_);
50 void RecordWriteFieldChar(mirror::Object* obj, MemberOffset field_offset, uint16_t value,
51 bool is_volatile)
52 LOCKS_EXCLUDED(log_lock_);
53 void RecordWriteFieldShort(mirror::Object* obj, MemberOffset field_offset, int16_t value,
54 bool is_volatile)
55 LOCKS_EXCLUDED(log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010056 void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
57 bool is_volatile)
58 LOCKS_EXCLUDED(log_lock_);
59 void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
60 bool is_volatile)
61 LOCKS_EXCLUDED(log_lock_);
62 void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
63 mirror::Object* value, bool is_volatile)
64 LOCKS_EXCLUDED(log_lock_);
65
66 // Record array change.
67 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
68 LOCKS_EXCLUDED(log_lock_)
69 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
70
71 // Record intern string table changes.
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070072 void RecordStrongStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010073 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
74 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070075 void RecordWeakStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010076 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
77 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070078 void RecordStrongStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010079 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
80 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070081 void RecordWeakStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010082 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
83 LOCKS_EXCLUDED(log_lock_);
84
85 // Abort transaction by undoing all recorded changes.
86 void Abort()
87 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
88 LOCKS_EXCLUDED(log_lock_);
89
90 void VisitRoots(RootCallback* callback, void* arg)
91 LOCKS_EXCLUDED(log_lock_)
92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
93
94 private:
95 class ObjectLog {
96 public:
Fred Shih37f05ef2014-07-16 18:38:08 -070097 void LogBooleanValue(MemberOffset offset, uint8_t value, bool is_volatile);
98 void LogByteValue(MemberOffset offset, int8_t value, bool is_volatile);
99 void LogCharValue(MemberOffset offset, uint16_t value, bool is_volatile);
100 void LogShortValue(MemberOffset offset, int16_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100101 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
102 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
103 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
104
105 void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
106 void VisitRoots(RootCallback* callback, void* arg);
107
108 size_t Size() const {
109 return field_values_.size();
110 }
111
112 private:
113 enum FieldValueKind {
Fred Shih37f05ef2014-07-16 18:38:08 -0700114 kBoolean,
115 kByte,
116 kChar,
117 kShort,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100118 k32Bits,
119 k64Bits,
120 kReference
121 };
122 struct FieldValue {
123 // TODO use JValue instead ?
124 uint64_t value;
125 FieldValueKind kind;
126 bool is_volatile;
127 };
128
Fred Shih37f05ef2014-07-16 18:38:08 -0700129 void LogValue(FieldValueKind kind, MemberOffset offset, uint64_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100130 void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
131 const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
132
133 // Maps field's offset to its value.
134 std::map<uint32_t, FieldValue> field_values_;
135 };
136
137 class ArrayLog {
138 public:
139 void LogValue(size_t index, uint64_t value);
140
141 void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100142
143 size_t Size() const {
144 return array_values_.size();
145 }
146
147 private:
148 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
149 uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
150
151 // Maps index to value.
152 // TODO use JValue instead ?
153 std::map<size_t, uint64_t> array_values_;
154 };
155
156 class InternStringLog {
157 public:
158 enum StringKind {
159 kStrongString,
160 kWeakString
161 };
162 enum StringOp {
163 kInsert,
164 kRemove
165 };
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -0700166 InternStringLog(mirror::String* s, StringKind kind, StringOp op)
167 : str_(s), string_kind_(kind), string_op_(op) {
Sebastien Hertzee1d79a2014-02-21 15:46:30 +0100168 DCHECK(s != nullptr);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100169 }
170
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700171 void Undo(InternTable* intern_table)
172 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
173 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100174 void VisitRoots(RootCallback* callback, void* arg);
175
176 private:
177 mirror::String* str_;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100178 StringKind string_kind_;
179 StringOp string_op_;
180 };
181
182 void LogInternedString(InternStringLog& log)
183 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
184 LOCKS_EXCLUDED(log_lock_);
185
186 void UndoObjectModifications()
187 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
188 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
189 void UndoArrayModifications()
190 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
191 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
192 void UndoInternStringTableModifications()
193 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700194 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
195 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100196
197 void VisitObjectLogs(RootCallback* callback, void* arg)
198 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
199 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
200 void VisitArrayLogs(RootCallback* callback, void* arg)
201 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
202 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
203 void VisitStringLogs(RootCallback* callback, void* arg)
204 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
205 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
206
207 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
208 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
209 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
210 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
211
212 DISALLOW_COPY_AND_ASSIGN(Transaction);
213};
214
215} // namespace art
216
217#endif // ART_RUNTIME_TRANSACTION_H_