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