blob: 2ec2f506fa3a013eac732a5fbe12ecd6399d728e [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;
Mathieu Chartierbb816d62016-09-07 10:17:46 -070035class DexCache;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010036class Object;
37class String;
38}
39class InternTable;
40
Ian Rogers6a3c1fc2014-10-31 00:33:20 -070041class Transaction FINAL {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010042 public:
Sebastien Hertz2fd7e692015-04-02 11:11:19 +020043 static constexpr const char* kAbortExceptionDescriptor = "dalvik.system.TransactionAbortError";
44 static constexpr const char* kAbortExceptionSignature = "Ldalvik/system/TransactionAbortError;";
45
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010046 Transaction();
47 ~Transaction();
48
Sebastien Hertz1c80bec2015-02-03 11:58:06 +010049 void Abort(const std::string& abort_message)
Mathieu Chartier90443472015-07-16 20:32:27 -070050 REQUIRES(!log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070051 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzb81e1cd2015-04-28 12:31:41 +020052 void ThrowAbortError(Thread* self, const std::string* abort_message)
Mathieu Chartier90443472015-07-16 20:32:27 -070053 REQUIRES(!log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070054 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier90443472015-07-16 20:32:27 -070055 bool IsAborted() REQUIRES(!log_lock_);
Sebastien Hertz1c80bec2015-02-03 11:58:06 +010056
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010057 // Record object field changes.
Fred Shih37f05ef2014-07-16 18:38:08 -070058 void RecordWriteFieldBoolean(mirror::Object* obj, MemberOffset field_offset, uint8_t value,
59 bool is_volatile)
Mathieu Chartier90443472015-07-16 20:32:27 -070060 REQUIRES(!log_lock_);
Fred Shih37f05ef2014-07-16 18:38:08 -070061 void RecordWriteFieldByte(mirror::Object* obj, MemberOffset field_offset, int8_t value,
62 bool is_volatile)
Mathieu Chartier90443472015-07-16 20:32:27 -070063 REQUIRES(!log_lock_);
Fred Shih37f05ef2014-07-16 18:38:08 -070064 void RecordWriteFieldChar(mirror::Object* obj, MemberOffset field_offset, uint16_t value,
65 bool is_volatile)
Mathieu Chartier90443472015-07-16 20:32:27 -070066 REQUIRES(!log_lock_);
Fred Shih37f05ef2014-07-16 18:38:08 -070067 void RecordWriteFieldShort(mirror::Object* obj, MemberOffset field_offset, int16_t value,
68 bool is_volatile)
Mathieu Chartier90443472015-07-16 20:32:27 -070069 REQUIRES(!log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010070 void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
71 bool is_volatile)
Mathieu Chartier90443472015-07-16 20:32:27 -070072 REQUIRES(!log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010073 void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
74 bool is_volatile)
Mathieu Chartier90443472015-07-16 20:32:27 -070075 REQUIRES(!log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010076 void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
77 mirror::Object* value, bool is_volatile)
Mathieu Chartier90443472015-07-16 20:32:27 -070078 REQUIRES(!log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010079
80 // Record array change.
81 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
Mathieu Chartier90443472015-07-16 20:32:27 -070082 REQUIRES(!log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070083 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010084
85 // Record intern string table changes.
Mathieu Chartier9e868092016-10-31 14:58:04 -070086 void RecordStrongStringInsertion(ObjPtr<mirror::String> s)
Mathieu Chartier90443472015-07-16 20:32:27 -070087 REQUIRES(Locks::intern_table_lock_)
88 REQUIRES(!log_lock_);
Mathieu Chartier9e868092016-10-31 14:58:04 -070089 void RecordWeakStringInsertion(ObjPtr<mirror::String> s)
Mathieu Chartier90443472015-07-16 20:32:27 -070090 REQUIRES(Locks::intern_table_lock_)
91 REQUIRES(!log_lock_);
Mathieu Chartier9e868092016-10-31 14:58:04 -070092 void RecordStrongStringRemoval(ObjPtr<mirror::String> s)
Mathieu Chartier90443472015-07-16 20:32:27 -070093 REQUIRES(Locks::intern_table_lock_)
94 REQUIRES(!log_lock_);
Mathieu Chartier9e868092016-10-31 14:58:04 -070095 void RecordWeakStringRemoval(ObjPtr<mirror::String> s)
Mathieu Chartier90443472015-07-16 20:32:27 -070096 REQUIRES(Locks::intern_table_lock_)
97 REQUIRES(!log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010098
Mathieu Chartierbb816d62016-09-07 10:17:46 -070099 // Record resolve string.
Mathieu Chartier9e868092016-10-31 14:58:04 -0700100 void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, uint32_t string_idx)
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700101 REQUIRES_SHARED(Locks::mutator_lock_)
102 REQUIRES(!log_lock_);
103
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100104 // Abort transaction by undoing all recorded changes.
Sebastien Hertz1c80bec2015-02-03 11:58:06 +0100105 void Rollback()
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700106 REQUIRES_SHARED(Locks::mutator_lock_)
Mathieu Chartier90443472015-07-16 20:32:27 -0700107 REQUIRES(!log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100108
Mathieu Chartierbb87e0f2015-04-03 11:21:55 -0700109 void VisitRoots(RootVisitor* visitor)
Mathieu Chartier90443472015-07-16 20:32:27 -0700110 REQUIRES(!log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700111 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100112
113 private:
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700114 class ObjectLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100115 public:
Fred Shih37f05ef2014-07-16 18:38:08 -0700116 void LogBooleanValue(MemberOffset offset, uint8_t value, bool is_volatile);
117 void LogByteValue(MemberOffset offset, int8_t value, bool is_volatile);
118 void LogCharValue(MemberOffset offset, uint16_t value, bool is_volatile);
119 void LogShortValue(MemberOffset offset, int16_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100120 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
121 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
122 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
123
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700124 void Undo(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_);
125 void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100126
127 size_t Size() const {
128 return field_values_.size();
129 }
130
131 private:
132 enum FieldValueKind {
Fred Shih37f05ef2014-07-16 18:38:08 -0700133 kBoolean,
134 kByte,
135 kChar,
136 kShort,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100137 k32Bits,
138 k64Bits,
139 kReference
140 };
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700141 struct FieldValue : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100142 // TODO use JValue instead ?
143 uint64_t value;
144 FieldValueKind kind;
145 bool is_volatile;
146 };
147
Fred Shih37f05ef2014-07-16 18:38:08 -0700148 void LogValue(FieldValueKind kind, MemberOffset offset, uint64_t value, bool is_volatile);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100149 void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700150 const FieldValue& field_value) REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100151
152 // Maps field's offset to its value.
153 std::map<uint32_t, FieldValue> field_values_;
154 };
155
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700156 class ArrayLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100157 public:
158 void LogValue(size_t index, uint64_t value);
159
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700160 void Undo(mirror::Array* obj) REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100161
162 size_t Size() const {
163 return array_values_.size();
164 }
165
166 private:
167 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700168 uint64_t value) REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100169
170 // Maps index to value.
171 // TODO use JValue instead ?
172 std::map<size_t, uint64_t> array_values_;
173 };
174
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700175 class InternStringLog : public ValueObject {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100176 public:
177 enum StringKind {
178 kStrongString,
179 kWeakString
180 };
181 enum StringOp {
182 kInsert,
183 kRemove
184 };
Mathieu Chartier9e868092016-10-31 14:58:04 -0700185 InternStringLog(ObjPtr<mirror::String> s, StringKind kind, StringOp op);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100186
Hiroshi Yamauchi1bd48722014-05-23 19:58:15 -0700187 void Undo(InternTable* intern_table)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700188 REQUIRES_SHARED(Locks::mutator_lock_)
Mathieu Chartier90443472015-07-16 20:32:27 -0700189 REQUIRES(Locks::intern_table_lock_);
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700190 void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100191
192 private:
Mathieu Chartier9e868092016-10-31 14:58:04 -0700193 GcRoot<mirror::String> str_;
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700194 const StringKind string_kind_;
195 const StringOp string_op_;
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100196 };
197
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700198 class ResolveStringLog : public ValueObject {
199 public:
Mathieu Chartier9e868092016-10-31 14:58:04 -0700200 ResolveStringLog(ObjPtr<mirror::DexCache> dex_cache, uint32_t string_idx);
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700201
202 void Undo() REQUIRES_SHARED(Locks::mutator_lock_);
203
204 void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
205
206 private:
207 GcRoot<mirror::DexCache> dex_cache_;
208 const uint32_t string_idx_;
209 };
210
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700211 void LogInternedString(const InternStringLog& log)
Mathieu Chartier90443472015-07-16 20:32:27 -0700212 REQUIRES(Locks::intern_table_lock_)
213 REQUIRES(!log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100214
215 void UndoObjectModifications()
Mathieu Chartier90443472015-07-16 20:32:27 -0700216 REQUIRES(log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700217 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100218 void UndoArrayModifications()
Mathieu Chartier90443472015-07-16 20:32:27 -0700219 REQUIRES(log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700220 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100221 void UndoInternStringTableModifications()
Mathieu Chartier90443472015-07-16 20:32:27 -0700222 REQUIRES(Locks::intern_table_lock_)
223 REQUIRES(log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700224 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700225 void UndoResolveStringModifications()
226 REQUIRES(log_lock_)
227 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100228
Mathieu Chartierbb87e0f2015-04-03 11:21:55 -0700229 void VisitObjectLogs(RootVisitor* visitor)
Mathieu Chartier90443472015-07-16 20:32:27 -0700230 REQUIRES(log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700231 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierbb87e0f2015-04-03 11:21:55 -0700232 void VisitArrayLogs(RootVisitor* visitor)
Mathieu Chartier90443472015-07-16 20:32:27 -0700233 REQUIRES(log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700234 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700235 void VisitInternStringLogs(RootVisitor* visitor)
236 REQUIRES(log_lock_)
237 REQUIRES_SHARED(Locks::mutator_lock_);
238 void VisitResolveStringLogs(RootVisitor* visitor)
Mathieu Chartier90443472015-07-16 20:32:27 -0700239 REQUIRES(log_lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700240 REQUIRES_SHARED(Locks::mutator_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100241
Mathieu Chartier90443472015-07-16 20:32:27 -0700242 const std::string& GetAbortMessage() REQUIRES(!log_lock_);
Sebastien Hertz1c80bec2015-02-03 11:58:06 +0100243
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100244 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
245 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
246 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
247 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
Mathieu Chartierbb816d62016-09-07 10:17:46 -0700248 std::list<ResolveStringLog> resolve_string_logs_ GUARDED_BY(log_lock_);
Sebastien Hertz1c80bec2015-02-03 11:58:06 +0100249 bool aborted_ GUARDED_BY(log_lock_);
250 std::string abort_message_ GUARDED_BY(log_lock_);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100251
252 DISALLOW_COPY_AND_ASSIGN(Transaction);
253};
254
255} // namespace art
256
257#endif // ART_RUNTIME_TRANSACTION_H_