• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
30 namespace art {
31 namespace mirror {
32 class Array;
33 class Object;
34 class String;
35 }
36 class InternTable;
37 
38 class 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 
Size()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 
Size()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     };
InternStringLog(mirror::String * s,StringKind kind,StringOp op)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