transaction.h revision 70c71ab1c2e44a74fc4eb76d6a0530f773850196
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 "object_callbacks.h"
23#include "offsets.h"
24#include "primitive.h"
25#include "safe_map.h"
26
27#include <list>
28#include <map>
29
30namespace art {
31namespace mirror {
32class Array;
33class Object;
34class String;
35}
36class InternTable;
37
38class Transaction {
39 public:
40  Transaction();
41  ~Transaction();
42
43  // Record object field changes.
44  void RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value,
45                          bool is_volatile)
46      LOCKS_EXCLUDED(log_lock_);
47  void RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value,
48                          bool is_volatile)
49      LOCKS_EXCLUDED(log_lock_);
50  void RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset,
51                                 mirror::Object* value, bool is_volatile)
52      LOCKS_EXCLUDED(log_lock_);
53
54  // Record array change.
55  void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value)
56      LOCKS_EXCLUDED(log_lock_)
57      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
58
59  // Record intern string table changes.
60  void RecordStrongStringInsertion(mirror::String* s)
61      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
62      LOCKS_EXCLUDED(log_lock_);
63  void RecordWeakStringInsertion(mirror::String* s)
64      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
65      LOCKS_EXCLUDED(log_lock_);
66  void RecordStrongStringRemoval(mirror::String* s)
67      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
68      LOCKS_EXCLUDED(log_lock_);
69  void RecordWeakStringRemoval(mirror::String* s)
70      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
71      LOCKS_EXCLUDED(log_lock_);
72
73  // Abort transaction by undoing all recorded changes.
74  void Abort()
75      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
76      LOCKS_EXCLUDED(log_lock_);
77
78  void VisitRoots(RootCallback* callback, void* arg)
79      LOCKS_EXCLUDED(log_lock_)
80      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
81
82 private:
83  class ObjectLog {
84   public:
85    void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile);
86    void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile);
87    void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile);
88
89    void Undo(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
90    void VisitRoots(RootCallback* callback, void* arg);
91
92    size_t Size() const {
93      return field_values_.size();
94    }
95
96   private:
97    enum FieldValueKind {
98      k32Bits,
99      k64Bits,
100      kReference
101    };
102    struct FieldValue {
103      // TODO use JValue instead ?
104      uint64_t value;
105      FieldValueKind kind;
106      bool is_volatile;
107    };
108
109    void UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset,
110                        const FieldValue& field_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
111
112    // Maps field's offset to its value.
113    std::map<uint32_t, FieldValue> field_values_;
114  };
115
116  class ArrayLog {
117   public:
118    void LogValue(size_t index, uint64_t value);
119
120    void Undo(mirror::Array* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
121
122    size_t Size() const {
123      return array_values_.size();
124    }
125
126   private:
127    void UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, size_t index,
128                        uint64_t value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
129
130    // Maps index to value.
131    // TODO use JValue instead ?
132    std::map<size_t, uint64_t> array_values_;
133  };
134
135  class InternStringLog {
136   public:
137    enum StringKind {
138      kStrongString,
139      kWeakString
140    };
141    enum StringOp {
142      kInsert,
143      kRemove
144    };
145    InternStringLog(mirror::String* s, StringKind kind, StringOp op)
146      : str_(s), string_kind_(kind), string_op_(op) {
147      DCHECK(s != nullptr);
148    }
149
150    void Undo(InternTable* intern_table)
151        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
152        EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
153    void VisitRoots(RootCallback* callback, void* arg);
154
155   private:
156    mirror::String* str_;
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      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
175
176  void VisitObjectLogs(RootCallback* callback, void* arg)
177      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
178      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
179  void VisitArrayLogs(RootCallback* callback, void* arg)
180      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
181      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
182  void VisitStringLogs(RootCallback* callback, void* arg)
183      EXCLUSIVE_LOCKS_REQUIRED(log_lock_)
184      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
185
186  Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_);
187  std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_);
188  std::map<mirror::Array*, ArrayLog> array_logs_  GUARDED_BY(log_lock_);
189  std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_);
190
191  DISALLOW_COPY_AND_ASSIGN(Transaction);
192};
193
194}  // namespace art
195
196#endif  // ART_RUNTIME_TRANSACTION_H_
197