Home | History | Annotate | Download | only in runtime
      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 
     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