blob: be614f9a3f029cb59f5b48dfa06a9f51f5a8ec96 [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 Rogers6a3c1fc2014-10-31 00:33:20 -070022#include "base/value_object.h"
Mathieu Chartiere34fa1d2015-01-14 14:55:47 -080023#include "gc_root.h"
Ian Rogers719d1a32014-03-06 12:13:39 -080024#include "object_callbacks.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010025#include "offsets.h"
26#include "primitive.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010027#include "safe_map.h"
28
29#include <list>
30#include <map>
31
32namespace art {
33namespace mirror {
34class Array;
35class Object;
36class String;
37}
38class InternTable;
39
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070040class Transaction FINAL {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010041 public:
42 Transaction();
43 ~Transaction();
44
Sebastien Hertz1c80bec2015-02-03 11:58:06 +010045 void Abort(const std::string& abort_message)
46 LOCKS_EXCLUDED(log_lock_)
47 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
48 void ThrowInternalError(Thread* self)
49 LOCKS_EXCLUDED(log_lock_)
50 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
51 bool IsAborted() LOCKS_EXCLUDED(log_lock_);
52
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010053 // Record object field changes.
Fred Shih37f05ef2014-07-16 18:38:08 -070054 void RecordWriteFieldBoolean(mirror::Object* obj, MemberOffset field_offset, uint8_t value,
55 bool is_volatile)
56 LOCKS_EXCLUDED(log_lock_);
57 void RecordWriteFieldByte(mirror::Object* obj, MemberOffset field_offset, int8_t value,
58 bool is_volatile)
59 LOCKS_EXCLUDED(log_lock_);
60 void RecordWriteFieldChar(mirror::Object* obj, MemberOffset field_offset, uint16_t value,
61 bool is_volatile)
62 LOCKS_EXCLUDED(log_lock_);
63 void RecordWriteFieldShort(mirror::Object* obj, MemberOffset field_offset, int16_t value,
64 bool is_volatile)
65 LOCKS_EXCLUDED(log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010066 void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
67 bool is_volatile)
68 LOCKS_EXCLUDED(log_lock_);
69 void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
70 bool is_volatile)
71 LOCKS_EXCLUDED(log_lock_);
72 void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
73 mirror::Object* value, bool is_volatile)
74 LOCKS_EXCLUDED(log_lock_);
75
76 // Record array change.
77 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
78 LOCKS_EXCLUDED(log_lock_)
79 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
80
81 // Record intern string table changes.
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070082 void RecordStrongStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010083 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
84 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070085 void RecordWeakStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010086 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
87 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070088 void RecordStrongStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010089 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
90 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070091 void RecordWeakStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010092 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
93 LOCKS_EXCLUDED(log_lock_);
94
95 // Abort transaction by undoing all recorded changes.
Sebastien Hertz1c80bec2015-02-03 11:58:06 +010096 void Rollback()
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010097 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
98 LOCKS_EXCLUDED(log_lock_);
99
100 void VisitRoots(RootCallback* callback, void* arg)
101 LOCKS_EXCLUDED(log_lock_)
102 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
103
104 private:
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700105 class ObjectLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100106 public:
Fred Shih37f05ef2014-07-16 18:38:08 -0700107 void LogBooleanValue(MemberOffset offset, uint8_t value, bool is_volatile);
108 void LogByteValue(MemberOffset offset, int8_t value, bool is_volatile);
109 void LogCharValue(MemberOffset offset, uint16_t value, bool is_volatile);
110 void LogShortValue(MemberOffset offset, int16_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100111 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
112 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
113 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
114
115 void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
116 void VisitRoots(RootCallback* callback, void* arg);
117
118 size_t Size() const {
119 return field_values_.size();
120 }
121
122 private:
123 enum FieldValueKind {
Fred Shih37f05ef2014-07-16 18:38:08 -0700124 kBoolean,
125 kByte,
126 kChar,
127 kShort,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100128 k32Bits,
129 k64Bits,
130 kReference
131 };
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700132 struct FieldValue : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100133 // TODO use JValue instead ?
134 uint64_t value;
135 FieldValueKind kind;
136 bool is_volatile;
137 };
138
Fred Shih37f05ef2014-07-16 18:38:08 -0700139 void LogValue(FieldValueKind kind, MemberOffset offset, uint64_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100140 void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
141 const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
142
143 // Maps field's offset to its value.
144 std::map<uint32_t, FieldValue> field_values_;
145 };
146
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700147 class ArrayLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100148 public:
149 void LogValue(size_t index, uint64_t value);
150
151 void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100152
153 size_t Size() const {
154 return array_values_.size();
155 }
156
157 private:
158 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
159 uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
160
161 // Maps index to value.
162 // TODO use JValue instead ?
163 std::map<size_t, uint64_t> array_values_;
164 };
165
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700166 class InternStringLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100167 public:
168 enum StringKind {
169 kStrongString,
170 kWeakString
171 };
172 enum StringOp {
173 kInsert,
174 kRemove
175 };
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -0700176 InternStringLog(mirror::String* s, StringKind kind, StringOp op)
177 : str_(s), string_kind_(kind), string_op_(op) {
Sebastien Hertzee1d79a2014-02-21 15:46:30 +0100178 DCHECK(s != nullptr);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100179 }
180
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700181 void Undo(InternTable* intern_table)
182 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
183 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100184 void VisitRoots(RootCallback* callback, void* arg);
185
186 private:
187 mirror::String* str_;
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700188 const StringKind string_kind_;
189 const StringOp string_op_;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100190 };
191
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700192 void LogInternedString(const InternStringLog& log)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100193 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
194 LOCKS_EXCLUDED(log_lock_);
195
196 void UndoObjectModifications()
197 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
198 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
199 void UndoArrayModifications()
200 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
201 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
202 void UndoInternStringTableModifications()
203 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700204 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
205 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100206
207 void VisitObjectLogs(RootCallback* callback, void* arg)
208 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
209 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
210 void VisitArrayLogs(RootCallback* callback, void* arg)
211 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
212 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
213 void VisitStringLogs(RootCallback* callback, void* arg)
214 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
215 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
216
Sebastien Hertz1c80bec2015-02-03 11:58:06 +0100217 const std::string& GetAbortMessage() LOCKS_EXCLUDED(log_lock_);
218
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100219 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
220 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
221 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
222 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
Sebastien Hertz1c80bec2015-02-03 11:58:06 +0100223 bool aborted_ GUARDED_BY(log_lock_);
224 std::string abort_message_ GUARDED_BY(log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100225
226 DISALLOW_COPY_AND_ASSIGN(Transaction);
227};
228
229} // namespace art
230
231#endif // ART_RUNTIME_TRANSACTION_H_