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 "dex_file_types.h" 24 #include "gc_root.h" 25 #include "object_callbacks.h" 26 #include "offsets.h" 27 #include "primitive.h" 28 #include "safe_map.h" 29 30 #include <list> 31 #include <map> 32 33 namespace art { 34 namespace mirror { 35 class Array; 36 class DexCache; 37 class Object; 38 class String; 39 } 40 class InternTable; 41 42 class Transaction FINAL { 43 public: 44 static constexpr const char* kAbortExceptionDescriptor = "dalvik.system.TransactionAbortError"; 45 static constexpr const char* kAbortExceptionSignature = "Ldalvik/system/TransactionAbortError;"; 46 47 Transaction(); 48 ~Transaction(); 49 50 void Abort(const std::string& abort_message) 51 REQUIRES(!log_lock_) 52 REQUIRES_SHARED(Locks::mutator_lock_); 53 void ThrowAbortError(Thread* self, const std::string* abort_message) 54 REQUIRES(!log_lock_) 55 REQUIRES_SHARED(Locks::mutator_lock_); 56 bool IsAborted() REQUIRES(!log_lock_); 57 58 // Record object field changes. 59 void RecordWriteFieldBoolean(mirror::Object* obj, 60 MemberOffset field_offset, 61 uint8_t value, 62 bool is_volatile) 63 REQUIRES(!log_lock_); 64 void RecordWriteFieldByte(mirror::Object* obj, 65 MemberOffset field_offset, 66 int8_t value, 67 bool is_volatile) 68 REQUIRES(!log_lock_); 69 void RecordWriteFieldChar(mirror::Object* obj, 70 MemberOffset field_offset, 71 uint16_t value, 72 bool is_volatile) 73 REQUIRES(!log_lock_); 74 void RecordWriteFieldShort(mirror::Object* obj, 75 MemberOffset field_offset, 76 int16_t value, 77 bool is_volatile) 78 REQUIRES(!log_lock_); 79 void RecordWriteField32(mirror::Object* obj, 80 MemberOffset field_offset, 81 uint32_t value, 82 bool is_volatile) 83 REQUIRES(!log_lock_); 84 void RecordWriteField64(mirror::Object* obj, 85 MemberOffset field_offset, 86 uint64_t value, 87 bool is_volatile) 88 REQUIRES(!log_lock_); 89 void RecordWriteFieldReference(mirror::Object* obj, 90 MemberOffset field_offset, 91 mirror::Object* value, 92 bool is_volatile) 93 REQUIRES(!log_lock_); 94 95 // Record array change. 96 void RecordWriteArray(mirror::Array* array, size_t index, uint64_t value) 97 REQUIRES(!log_lock_) 98 REQUIRES_SHARED(Locks::mutator_lock_); 99 100 // Record intern string table changes. 101 void RecordStrongStringInsertion(ObjPtr<mirror::String> s) 102 REQUIRES(Locks::intern_table_lock_) 103 REQUIRES(!log_lock_); 104 void RecordWeakStringInsertion(ObjPtr<mirror::String> s) 105 REQUIRES(Locks::intern_table_lock_) 106 REQUIRES(!log_lock_); 107 void RecordStrongStringRemoval(ObjPtr<mirror::String> s) 108 REQUIRES(Locks::intern_table_lock_) 109 REQUIRES(!log_lock_); 110 void RecordWeakStringRemoval(ObjPtr<mirror::String> s) 111 REQUIRES(Locks::intern_table_lock_) 112 REQUIRES(!log_lock_); 113 114 // Record resolve string. 115 void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx) 116 REQUIRES_SHARED(Locks::mutator_lock_) 117 REQUIRES(!log_lock_); 118 119 // Abort transaction by undoing all recorded changes. 120 void Rollback() 121 REQUIRES_SHARED(Locks::mutator_lock_) 122 REQUIRES(!log_lock_); 123 124 void VisitRoots(RootVisitor* visitor) 125 REQUIRES(!log_lock_) 126 REQUIRES_SHARED(Locks::mutator_lock_); 127 128 private: 129 class ObjectLog : public ValueObject { 130 public: 131 void LogBooleanValue(MemberOffset offset, uint8_t value, bool is_volatile); 132 void LogByteValue(MemberOffset offset, int8_t value, bool is_volatile); 133 void LogCharValue(MemberOffset offset, uint16_t value, bool is_volatile); 134 void LogShortValue(MemberOffset offset, int16_t value, bool is_volatile); 135 void Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile); 136 void Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile); 137 void LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile); 138 139 void Undo(mirror::Object* obj) const REQUIRES_SHARED(Locks::mutator_lock_); 140 void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_); 141 Size()142 size_t Size() const { 143 return field_values_.size(); 144 } 145 146 ObjectLog() = default; 147 ObjectLog(ObjectLog&& log) = default; 148 149 private: 150 enum FieldValueKind { 151 kBoolean, 152 kByte, 153 kChar, 154 kShort, 155 k32Bits, 156 k64Bits, 157 kReference 158 }; 159 struct FieldValue : public ValueObject { 160 // TODO use JValue instead ? 161 uint64_t value; 162 FieldValueKind kind; 163 bool is_volatile; 164 FieldValueFieldValue165 FieldValue() : value(0), kind(FieldValueKind::kBoolean), is_volatile(false) {} 166 FieldValue(FieldValue&& log) = default; 167 168 private: 169 DISALLOW_COPY_AND_ASSIGN(FieldValue); 170 }; 171 172 void LogValue(FieldValueKind kind, MemberOffset offset, uint64_t value, bool is_volatile); 173 void UndoFieldWrite(mirror::Object* obj, 174 MemberOffset field_offset, 175 const FieldValue& field_value) const REQUIRES_SHARED(Locks::mutator_lock_); 176 177 // Maps field's offset to its value. 178 std::map<uint32_t, FieldValue> field_values_; 179 180 DISALLOW_COPY_AND_ASSIGN(ObjectLog); 181 }; 182 183 class ArrayLog : public ValueObject { 184 public: 185 void LogValue(size_t index, uint64_t value); 186 187 void Undo(mirror::Array* obj) const REQUIRES_SHARED(Locks::mutator_lock_); 188 Size()189 size_t Size() const { 190 return array_values_.size(); 191 } 192 193 ArrayLog() = default; 194 ArrayLog(ArrayLog&& log) = default; 195 196 private: 197 void UndoArrayWrite(mirror::Array* array, 198 Primitive::Type array_type, 199 size_t index, 200 uint64_t value) const REQUIRES_SHARED(Locks::mutator_lock_); 201 202 // Maps index to value. 203 // TODO use JValue instead ? 204 std::map<size_t, uint64_t> array_values_; 205 206 DISALLOW_COPY_AND_ASSIGN(ArrayLog); 207 }; 208 209 class InternStringLog : public ValueObject { 210 public: 211 enum StringKind { 212 kStrongString, 213 kWeakString 214 }; 215 enum StringOp { 216 kInsert, 217 kRemove 218 }; 219 InternStringLog(ObjPtr<mirror::String> s, StringKind kind, StringOp op); 220 221 void Undo(InternTable* intern_table) const 222 REQUIRES_SHARED(Locks::mutator_lock_) 223 REQUIRES(Locks::intern_table_lock_); 224 void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_); 225 226 InternStringLog() = default; 227 InternStringLog(InternStringLog&& log) = default; 228 229 private: 230 mutable GcRoot<mirror::String> str_; 231 const StringKind string_kind_; 232 const StringOp string_op_; 233 234 DISALLOW_COPY_AND_ASSIGN(InternStringLog); 235 }; 236 237 class ResolveStringLog : public ValueObject { 238 public: 239 ResolveStringLog(ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx); 240 241 void Undo() const REQUIRES_SHARED(Locks::mutator_lock_); 242 243 void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_); 244 245 private: 246 GcRoot<mirror::DexCache> dex_cache_; 247 const dex::StringIndex string_idx_; 248 249 DISALLOW_COPY_AND_ASSIGN(ResolveStringLog); 250 }; 251 252 void LogInternedString(InternStringLog&& log) 253 REQUIRES(Locks::intern_table_lock_) 254 REQUIRES(!log_lock_); 255 256 void UndoObjectModifications() 257 REQUIRES(log_lock_) 258 REQUIRES_SHARED(Locks::mutator_lock_); 259 void UndoArrayModifications() 260 REQUIRES(log_lock_) 261 REQUIRES_SHARED(Locks::mutator_lock_); 262 void UndoInternStringTableModifications() 263 REQUIRES(Locks::intern_table_lock_) 264 REQUIRES(log_lock_) 265 REQUIRES_SHARED(Locks::mutator_lock_); 266 void UndoResolveStringModifications() 267 REQUIRES(log_lock_) 268 REQUIRES_SHARED(Locks::mutator_lock_); 269 270 void VisitObjectLogs(RootVisitor* visitor) 271 REQUIRES(log_lock_) 272 REQUIRES_SHARED(Locks::mutator_lock_); 273 void VisitArrayLogs(RootVisitor* visitor) 274 REQUIRES(log_lock_) 275 REQUIRES_SHARED(Locks::mutator_lock_); 276 void VisitInternStringLogs(RootVisitor* visitor) 277 REQUIRES(log_lock_) 278 REQUIRES_SHARED(Locks::mutator_lock_); 279 void VisitResolveStringLogs(RootVisitor* visitor) 280 REQUIRES(log_lock_) 281 REQUIRES_SHARED(Locks::mutator_lock_); 282 283 const std::string& GetAbortMessage() REQUIRES(!log_lock_); 284 285 Mutex log_lock_ ACQUIRED_AFTER(Locks::intern_table_lock_); 286 std::map<mirror::Object*, ObjectLog> object_logs_ GUARDED_BY(log_lock_); 287 std::map<mirror::Array*, ArrayLog> array_logs_ GUARDED_BY(log_lock_); 288 std::list<InternStringLog> intern_string_logs_ GUARDED_BY(log_lock_); 289 std::list<ResolveStringLog> resolve_string_logs_ GUARDED_BY(log_lock_); 290 bool aborted_ GUARDED_BY(log_lock_); 291 std::string abort_message_ GUARDED_BY(log_lock_); 292 293 DISALLOW_COPY_AND_ASSIGN(Transaction); 294 }; 295 296 } // namespace art 297 298 #endif // ART_RUNTIME_TRANSACTION_H_ 299