blob: 8c82847683cf18f71b70c422a239e678f27c7673 [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
45 // Record object field changes.
Fred Shih37f05ef2014-07-16 18:38:08 -070046 void RecordWriteFieldBoolean(mirror::Object* obj, MemberOffset field_offset, uint8_t value,
47 bool is_volatile)
48 LOCKS_EXCLUDED(log_lock_);
49 void RecordWriteFieldByte(mirror::Object* obj, MemberOffset field_offset, int8_t value,
50 bool is_volatile)
51 LOCKS_EXCLUDED(log_lock_);
52 void RecordWriteFieldChar(mirror::Object* obj, MemberOffset field_offset, uint16_t value,
53 bool is_volatile)
54 LOCKS_EXCLUDED(log_lock_);
55 void RecordWriteFieldShort(mirror::Object* obj, MemberOffset field_offset, int16_t value,
56 bool is_volatile)
57 LOCKS_EXCLUDED(log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010058 void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
59 bool is_volatile)
60 LOCKS_EXCLUDED(log_lock_);
61 void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
62 bool is_volatile)
63 LOCKS_EXCLUDED(log_lock_);
64 void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
65 mirror::Object* value, bool is_volatile)
66 LOCKS_EXCLUDED(log_lock_);
67
68 // Record array change.
69 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
70 LOCKS_EXCLUDED(log_lock_)
71 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
72
73 // Record intern string table changes.
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070074 void RecordStrongStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010075 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
76 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070077 void RecordWeakStringInsertion(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010078 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
79 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070080 void RecordStrongStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010081 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
82 LOCKS_EXCLUDED(log_lock_);
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -070083 void RecordWeakStringRemoval(mirror::String* s)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010084 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
85 LOCKS_EXCLUDED(log_lock_);
86
87 // Abort transaction by undoing all recorded changes.
88 void Abort()
89 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
90 LOCKS_EXCLUDED(log_lock_);
91
92 void VisitRoots(RootCallback* callback, void* arg)
93 LOCKS_EXCLUDED(log_lock_)
94 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
95
96 private:
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070097 class ObjectLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010098 public:
Fred Shih37f05ef2014-07-16 18:38:08 -070099 void LogBooleanValue(MemberOffset offset, uint8_t value, bool is_volatile);
100 void LogByteValue(MemberOffset offset, int8_t value, bool is_volatile);
101 void LogCharValue(MemberOffset offset, uint16_t value, bool is_volatile);
102 void LogShortValue(MemberOffset offset, int16_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100103 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
104 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
105 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
106
107 void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
108 void VisitRoots(RootCallback* callback, void* arg);
109
110 size_t Size() const {
111 return field_values_.size();
112 }
113
114 private:
115 enum FieldValueKind {
Fred Shih37f05ef2014-07-16 18:38:08 -0700116 kBoolean,
117 kByte,
118 kChar,
119 kShort,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100120 k32Bits,
121 k64Bits,
122 kReference
123 };
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700124 struct FieldValue : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100125 // TODO use JValue instead ?
126 uint64_t value;
127 FieldValueKind kind;
128 bool is_volatile;
129 };
130
Fred Shih37f05ef2014-07-16 18:38:08 -0700131 void LogValue(FieldValueKind kind, MemberOffset offset, uint64_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100132 void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
133 const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
134
135 // Maps field's offset to its value.
136 std::map<uint32_t, FieldValue> field_values_;
137 };
138
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700139 class ArrayLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100140 public:
141 void LogValue(size_t index, uint64_t value);
142
143 void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100144
145 size_t Size() const {
146 return array_values_.size();
147 }
148
149 private:
150 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
151 uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
152
153 // Maps index to value.
154 // TODO use JValue instead ?
155 std::map<size_t, uint64_t> array_values_;
156 };
157
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700158 class InternStringLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100159 public:
160 enum StringKind {
161 kStrongString,
162 kWeakString
163 };
164 enum StringOp {
165 kInsert,
166 kRemove
167 };
Mathieu Chartiercdfd39f2014-08-29 18:16:58 -0700168 InternStringLog(mirror::String* s, StringKind kind, StringOp op)
169 : str_(s), string_kind_(kind), string_op_(op) {
Sebastien Hertzee1d79a2014-02-21 15:46:30 +0100170 DCHECK(s != nullptr);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100171 }
172
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700173 void Undo(InternTable* intern_table)
174 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
175 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100176 void VisitRoots(RootCallback* callback, void* arg);
177
178 private:
179 mirror::String* str_;
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700180 const StringKind string_kind_;
181 const StringOp string_op_;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100182 };
183
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700184 void LogInternedString(const InternStringLog& log)
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100185 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
186 LOCKS_EXCLUDED(log_lock_);
187
188 void UndoObjectModifications()
189 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
190 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
191 void UndoArrayModifications()
192 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
193 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
194 void UndoInternStringTableModifications()
195 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700196 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
197 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100198
199 void VisitObjectLogs(RootCallback* callback, void* arg)
200 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
201 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
202 void VisitArrayLogs(RootCallback* callback, void* arg)
203 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
204 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
205 void VisitStringLogs(RootCallback* callback, void* arg)
206 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
207 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
208
209 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
210 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
211 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
212 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
213
214 DISALLOW_COPY_AND_ASSIGN(Transaction);
215};
216
217} // namespace art
218
219#endif // ART_RUNTIME_TRANSACTION_H_