blob: 68f95402c6579bc2491cfa3528209d0fb7673757 [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"
22#include "locks.h"
23#include "offsets.h"
24#include "primitive.h"
25#include "object_callbacks.h"
26#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.
61 void RecordStrongStringInsertion(mirror::String* s, uint32_t hash_code)
62 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
63 LOCKS_EXCLUDED(log_lock_);
64 void RecordWeakStringInsertion(mirror::String* s, uint32_t hash_code)
65 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
66 LOCKS_EXCLUDED(log_lock_);
67 void RecordStrongStringRemoval(mirror::String* s, uint32_t hash_code)
68 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
69 LOCKS_EXCLUDED(log_lock_);
70 void RecordWeakStringRemoval(mirror::String* s, uint32_t hash_code)
71 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_);
122 void VisitRoots(RootCallback* callback, void* arg);
123
124 size_t Size() const {
125 return array_values_.size();
126 }
127
128 private:
129 void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
130 uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
131
132 // Maps index to value.
133 // TODO use JValue instead ?
134 std::map<size_t, uint64_t> array_values_;
135 };
136
137 class InternStringLog {
138 public:
139 enum StringKind {
140 kStrongString,
141 kWeakString
142 };
143 enum StringOp {
144 kInsert,
145 kRemove
146 };
147 InternStringLog(mirror::String* s, uint32_t hash_code, StringKind kind, StringOp op)
148 : str_(s), hash_code_(hash_code), string_kind_(kind), string_op_(op) {
149 }
150
151 void Undo(InternTable* intern_table) EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
152 void VisitRoots(RootCallback* callback, void* arg);
153
154 private:
155 mirror::String* str_;
156 uint32_t hash_code_;
157 StringKind string_kind_;
158 StringOp string_op_;
159 };
160
161 void LogInternedString(InternStringLog& log)
162 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
163 LOCKS_EXCLUDED(log_lock_);
164
165 void UndoObjectModifications()
166 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
167 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
168 void UndoArrayModifications()
169 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
170 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
171 void UndoInternStringTableModifications()
172 EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
173 EXCLUSIVE_LOCKS_REQUIRED(log_lock_);
174
175 void VisitObjectLogs(RootCallback* callback, void* arg)
176 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
177 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
178 void VisitArrayLogs(RootCallback* callback, void* arg)
179 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
180 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
181 void VisitStringLogs(RootCallback* callback, void* arg)
182 EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
183 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
184
185 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
186 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
187 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_);
188 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
189
190 DISALLOW_COPY_AND_ASSIGN(Transaction);
191};
192
193} // namespace art
194
195#endif // ART_RUNTIME_TRANSACTION_H_