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