blob: 83206b282fbc226d6827b38c23f3627d3e64bed6 [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"
Mathieu Chartier12f74232015-01-14 14:55:47 -080022#include "gc_root.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
39class Transaction {
40 public:
41 Transaction();
42 ~Transaction();
43
44 // Record object field changes.
45 void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
46 bool is_volatile)
47 LOCKS_EXCLUDED(log_lock_);
48 void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
49 bool is_volatile)
50 LOCKS_EXCLUDED(log_lock_);
51 void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
52 mirror::Object* value, bool is_volatile)
53 LOCKS_EXCLUDED(log_lock_);
54
55 // Record array change.
56 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
57 LOCKS_EXCLUDED(log_lock_)
58 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
59
60 // Record intern string table changes.
Mathieu Chartierd910fce2014-08-29 18:16:58 -070061 void RecordStrongStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010062 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
63 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartierd910fce2014-08-29 18:16:58 -070064 void RecordWeakStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010065 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
66 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartierd910fce2014-08-29 18:16:58 -070067 void RecordStrongStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010068 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
69 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartierd910fce2014-08-29 18:16:58 -070070 void RecordWeakStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010071 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
72 LOCKS_EXCLUDED(log_lock_);
73
74 // Abort transaction by undoing all recorded changes.
75 void Abort()
76 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
77 LOCKS_EXCLUDED(log_lock_);
78
79 void VisitRoots(RootCallback* callback, void* arg)
80 LOCKS_EXCLUDED(log_lock_)
81 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
82
83 private:
84 class ObjectLog {
85 public:
86 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
87 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
88 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
89
90 void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
91 void VisitRoots(RootCallback* callback, void* arg);
92
93 size_t Size() const {
94 return field_values_.size();
95 }
96
97 private:
98 enum FieldValueKind {
99 k32Bits,
100 k64Bits,
101 kReference
102 };
103 struct FieldValue {
104 // TODO use JValue instead ?
105 uint64_t value;
106 FieldValueKind kind;
107 bool is_volatile;
108 };
109
110 void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
111 const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
112
113 // Maps field's offset to its value.
114 std::map<uint32_t, FieldValue> field_values_;
115 };
116
117 class ArrayLog {
118 public:
119 void LogValue(size_t index, uint64_t value);
120
121 void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100122
123 size_t Size() const {
124 return array_values_.size();
125 }
126
127 private:
128 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
129 uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
130
131 // Maps index to value.
132 // TODO use JValue instead ?
133 std::map<size_t, uint64_t> array_values_;
134 };
135
136 class InternStringLog {
137 public:
138 enum StringKind {
139 kStrongString,
140 kWeakString
141 };
142 enum StringOp {
143 kInsert,
144 kRemove
145 };
Mathieu Chartierd910fce2014-08-29 18:16:58 -0700146 InternStringLog(mirror::String* s, StringKind kind, StringOp op)
147 : str_(s), string_kind_(kind), string_op_(op) {
Sebastien Hertzee1d79a2014-02-21 15:46:30 +0100148 DCHECK(s != nullptr);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100149 }
150
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700151 void Undo(InternTable* intern_table)
152 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
153 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100154 void VisitRoots(RootCallback* callback, void* arg);
155
156 private:
157 mirror::String* str_;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100158 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_