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 "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 
     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 
    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     };
    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