transaction.h revision bb87e0f1a52de656bc77cb01cb887e51a0e5198b
1/*
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 "base/value_object.h"
23#include "gc_root.h"
24#include "object_callbacks.h"
25#include "offsets.h"
26#include "primitive.h"
27#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
40class Transaction FINAL {
41 public:
42  static constexpr const char* kAbortExceptionDescriptor = "dalvik.system.TransactionAbortError";
43  static constexpr const char* kAbortExceptionSignature = "Ldalvik/system/TransactionAbortError;";
44
45  Transaction();
46  ~Transaction();
47
48  void Abort(const std::string& abort_message)
49      LOCKS_EXCLUDED(log_lock_)
50      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
51  void ThrowAbortError(Thread* self, bool rethrow)
52      LOCKS_EXCLUDED(log_lock_)
53      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
54  bool IsAborted() LOCKS_EXCLUDED(log_lock_);
55
56  // Record object field changes.
57  void RecordWriteFieldBoolean(mirror::Object* obj, MemberOffset field_offset, uint8_t value,
58                               bool is_volatile)
59      LOCKS_EXCLUDED(log_lock_);
60  void RecordWriteFieldByte(mirror::Object* obj, MemberOffset field_offset, int8_t value,
61                               bool is_volatile)
62      LOCKS_EXCLUDED(log_lock_);
63  void RecordWriteFieldChar(mirror::Object* obj, MemberOffset field_offset, uint16_t value,
64                            bool is_volatile)
65      LOCKS_EXCLUDED(log_lock_);
66  void RecordWriteFieldShort(mirror::Object* obj, MemberOffset field_offset, int16_t value,
67                             bool is_volatile)
68      LOCKS_EXCLUDED(log_lock_);
69  void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
70                          bool is_volatile)
71      LOCKS_EXCLUDED(log_lock_);
72  void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
73                          bool is_volatile)
74      LOCKS_EXCLUDED(log_lock_);
75  void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
76                                 mirror::Object* value, bool is_volatile)
77      LOCKS_EXCLUDED(log_lock_);
78
79  // Record array change.
80  void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
81      LOCKS_EXCLUDED(log_lock_)
82      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
83
84  // Record intern string table changes.
85  void RecordStrongStringInsertion(mirror::String* s)
86      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
87      LOCKS_EXCLUDED(log_lock_);
88  void RecordWeakStringInsertion(mirror::String* s)
89      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
90      LOCKS_EXCLUDED(log_lock_);
91  void RecordStrongStringRemoval(mirror::String* s)
92      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
93      LOCKS_EXCLUDED(log_lock_);
94  void RecordWeakStringRemoval(mirror::String* s)
95      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
96      LOCKS_EXCLUDED(log_lock_);
97
98  // Abort transaction by undoing all recorded changes.
99  void Rollback()
100      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
101      LOCKS_EXCLUDED(log_lock_);
102
103  void VisitRoots(RootVisitor* visitor)
104      LOCKS_EXCLUDED(log_lock_)
105      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
106
107 private:
108  class ObjectLog : public ValueObject {
109   public:
110    void LogBooleanValue(MemberOffset offset, uint8_t value, bool is_volatile);
111    void LogByteValue(MemberOffset offset, int8_t value, bool is_volatile);
112    void LogCharValue(MemberOffset offset, uint16_t value, bool is_volatile);
113    void LogShortValue(MemberOffset offset, int16_t value, bool is_volatile);
114    void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
115    void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
116    void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
117
118    void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
119    void VisitRoots(RootVisitor* visitor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
120
121    size_t Size() const {
122      return field_values_.size();
123    }
124
125   private:
126    enum FieldValueKind {
127      kBoolean,
128      kByte,
129      kChar,
130      kShort,
131      k32Bits,
132      k64Bits,
133      kReference
134    };
135    struct FieldValue : public ValueObject {
136      // TODO use JValue instead ?
137      uint64_t value;
138      FieldValueKind kind;
139      bool is_volatile;
140    };
141
142    void LogValue(FieldValueKind kind, MemberOffset offset, uint64_t value, bool is_volatile);
143    void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
144                        const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
145
146    // Maps field's offset to its value.
147    std::map<uint32_t, FieldValue> field_values_;
148  };
149
150  class ArrayLog : public ValueObject {
151   public:
152    void LogValue(size_t index, uint64_t value);
153
154    void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
155
156    size_t Size() const {
157      return array_values_.size();
158    }
159
160   private:
161    void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
162                        uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
163
164    // Maps index to value.
165    // TODO use JValue instead ?
166    std::map<size_t, uint64_t> array_values_;
167  };
168
169  class InternStringLog : public ValueObject {
170   public:
171    enum StringKind {
172      kStrongString,
173      kWeakString
174    };
175    enum StringOp {
176      kInsert,
177      kRemove
178    };
179    InternStringLog(mirror::String* s, StringKind kind, StringOp op)
180      : str_(s), string_kind_(kind), string_op_(op) {
181      DCHECK(s != nullptr);
182    }
183
184    void Undo(InternTable* intern_table)
185        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
186        EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
187    void VisitRoots(RootVisitor* visitor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
188
189   private:
190    mirror::String* str_;
191    const StringKind string_kind_;
192    const StringOp string_op_;
193  };
194
195  void LogInternedString(const InternStringLog& log)
196      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
197      LOCKS_EXCLUDED(log_lock_);
198
199  void UndoObjectModifications()
200      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
201      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
202  void UndoArrayModifications()
203      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
204      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
205  void UndoInternStringTableModifications()
206      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
207      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
208      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
209
210  void VisitObjectLogs(RootVisitor* visitor)
211      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
212      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
213  void VisitArrayLogs(RootVisitor* visitor)
214      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
215      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
216  void VisitStringLogs(RootVisitor* visitor)
217      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
218      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
219
220  const std::string& GetAbortMessage() LOCKS_EXCLUDED(log_lock_);
221
222  Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
223  std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
224  std::map<mirror::Array*, ArrayLog> array_logs_  GUARDED_BY(log_lock_);
225  std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
226  bool aborted_ GUARDED_BY(log_lock_);
227  std::string abort_message_ GUARDED_BY(log_lock_);
228
229  DISALLOW_COPY_AND_ASSIGN(Transaction);
230};
231
232}  // namespace art
233
234#endif  // ART_RUNTIME_TRANSACTION_H_
235