blob: 566f231de69556ce2a76908dc7edced88528b0d3 [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"
Ian Rogers719d1a32014-03-06 12:13:39 -080023#include "object_callbacks.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010024#include "offsets.h"
25#include "primitive.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010026#include "safe_map.h"
27
28#include <list>
29#include <map>
30
31namespace art {
32namespace mirror {
33class Array;
34class Object;
35class String;
36}
37class InternTable;
38
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070039class Transaction FINAL {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010040 public:
41 Transaction();
42 ~Transaction();
43
44 // Record object field changes.
Fred Shih37f05ef2014-07-16 18:38:08 -070045 void RecordWriteFieldBoolean(mirror::Object* obj, MemberOffset field_offset, uint8_t value,
46 bool is_volatile)
47 LOCKS_EXCLUDED(log_lock_);
48 void RecordWriteFieldByte(mirror::Object* obj, MemberOffset field_offset, int8_t value,
49 bool is_volatile)
50 LOCKS_EXCLUDED(log_lock_);
51 void RecordWriteFieldChar(mirror::Object* obj, MemberOffset field_offset, uint16_t value,
52 bool is_volatile)
53 LOCKS_EXCLUDED(log_lock_);
54 void RecordWriteFieldShort(mirror::Object* obj, MemberOffset field_offset, int16_t value,
55 bool is_volatile)
56 LOCKS_EXCLUDED(log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010057 void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
58 bool is_volatile)
59 LOCKS_EXCLUDED(log_lock_);
60 void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
61 bool is_volatile)
62 LOCKS_EXCLUDED(log_lock_);
63 void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
64 mirror::Object* value, bool is_volatile)
65 LOCKS_EXCLUDED(log_lock_);
66
67 // Record array change.
68 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
69 LOCKS_EXCLUDED(log_lock_)
70 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
71
72 // Record intern string table changes.
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070073 void RecordStrongStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010074 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
75 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070076 void RecordWeakStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010077 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
78 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070079 void RecordStrongStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010080 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
81 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070082 void RecordWeakStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010083 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
84 LOCKS_EXCLUDED(log_lock_);
85
86 // Abort transaction by undoing all recorded changes.
87 void Abort()
88 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
89 LOCKS_EXCLUDED(log_lock_);
90
91 void VisitRoots(RootCallback* callback, void* arg)
92 LOCKS_EXCLUDED(log_lock_)
93 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
94
95 private:
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070096 class ObjectLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010097 public:
Fred Shih37f05ef2014-07-16 18:38:08 -070098 void LogBooleanValue(MemberOffset offset, uint8_t value, bool is_volatile);
99 void LogByteValue(MemberOffset offset, int8_t value, bool is_volatile);
100 void LogCharValue(MemberOffset offset, uint16_t value, bool is_volatile);
101 void LogShortValue(MemberOffset offset, int16_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100102 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
103 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
104 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
105
106 void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
107 void VisitRoots(RootCallback* callback, void* arg);
108
109 size_t Size() const {
110 return field_values_.size();
111 }
112
113 private:
114 enum FieldValueKind {
Fred Shih37f05ef2014-07-16 18:38:08 -0700115 kBoolean,
116 kByte,
117 kChar,
118 kShort,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100119 k32Bits,
120 k64Bits,
121 kReference
122 };
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700123 struct FieldValue : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100124 // TODO use JValue instead ?
125 uint64_t value;
126 FieldValueKind kind;
127 bool is_volatile;
128 };
129
Fred Shih37f05ef2014-07-16 18:38:08 -0700130 void LogValue(FieldValueKind kind, MemberOffset offset, uint64_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100131 void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
132 const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
133
134 // Maps field's offset to its value.
135 std::map<uint32_t, FieldValue> field_values_;
136 };
137
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700138 class ArrayLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100139 public:
140 void LogValue(size_t index, uint64_t value);
141
142 void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100143
144 size_t Size() const {
145 return array_values_.size();
146 }
147
148 private:
149 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
150 uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
151
152 // Maps index to value.
153 // TODO use JValue instead ?
154 std::map<size_t, uint64_t> array_values_;
155 };
156
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700157 class InternStringLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100158 public:
159 enum StringKind {
160 kStrongString,
161 kWeakString
162 };
163 enum StringOp {
164 kInsert,
165 kRemove
166 };
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -0700167 InternStringLog(mirror::String* s, StringKind kind, StringOp op)
168 : str_(s), string_kind_(kind), string_op_(op) {
Sebastien Hertzee1d79a2014-02-21 15:46:30 +0100169 DCHECK(s != nullptr);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100170 }
171
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700172 void Undo(InternTable* intern_table)
173 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
174 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100175 void VisitRoots(RootCallback* callback, void* arg);
176
177 private:
178 mirror::String* str_;
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700179 const StringKind string_kind_;
180 const StringOp string_op_;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100181 };
182
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700183 void LogInternedString(const InternStringLog& log)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100184 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
185 LOCKS_EXCLUDED(log_lock_);
186
187 void UndoObjectModifications()
188 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
189 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
190 void UndoArrayModifications()
191 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
192 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
193 void UndoInternStringTableModifications()
194 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700195 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
196 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100197
198 void VisitObjectLogs(RootCallback* callback, void* arg)
199 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
200 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
201 void VisitArrayLogs(RootCallback* callback, void* arg)
202 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
203 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
204 void VisitStringLogs(RootCallback* callback, void* arg)
205 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
206 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
207
208 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
209 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
210 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
211 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
212
213 DISALLOW_COPY_AND_ASSIGN(Transaction);
214};
215
216} // namespace art
217
218#endif // ART_RUNTIME_TRANSACTION_H_