transaction.cc revision a559ccb7aa56a5871b1e77857c2b5e7101b8d371
1d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz/* 2d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * Copyright (C) 2014 The Android Open Source Project 3d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * 4d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * Licensed under the Apache License, Version 2.0 (the "License"); 5d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * you may not use this file except in compliance with the License. 6d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * You may obtain a copy of the License at 7d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * 8d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * http://www.apache.org/licenses/LICENSE-2.0 9d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * 10d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * Unless required by applicable law or agreed to in writing, software 11d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * distributed under the License is distributed on an "AS IS" BASIS, 12d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * See the License for the specific language governing permissions and 14d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz * limitations under the License. 15d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz */ 16d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 17d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include "transaction.h" 18d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 19d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include "base/stl_util.h" 20d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include "base/logging.h" 21d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include "gc/accounting/card_table-inl.h" 22d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include "intern_table.h" 23d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include "mirror/object-inl.h" 24d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include "mirror/object_array-inl.h" 25d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 26d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include <list> 27d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 28d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertznamespace art { 29d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 30d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz// TODO: remove (only used for debugging purpose). 31d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzstatic constexpr bool kEnableTransactionStats = false; 32d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 33d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien HertzTransaction::Transaction() : log_lock_("transaction log lock", kTransactionLogLock) { 34d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK(Runtime::Current()->IsCompiler()); 35d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 36d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 37d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien HertzTransaction::~Transaction() { 38d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kEnableTransactionStats) { 39d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu(Thread::Current(), log_lock_); 40d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz size_t objects_count = object_logs_.size(); 41d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz size_t field_values_count = 0; 42d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : object_logs_) { 43d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_values_count += it.second.Size(); 44d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 45d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz size_t array_count = array_logs_.size(); 46d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz size_t array_values_count = 0; 47d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : array_logs_) { 48d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array_values_count += it.second.Size(); 49d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 50d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz size_t string_count = intern_string_logs_.size(); 51d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LOG(INFO) << "Transaction::~Transaction" 52d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << ": objects_count=" << objects_count 53d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << ", field_values_count=" << field_values_count 54d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << ", array_count=" << array_count 55d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << ", array_values_count=" << array_values_count 56d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << ", string_count=" << string_count; 57d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 58d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 59d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 60d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordWriteField32(mirror::Object* obj, MemberOffset field_offset, uint32_t value, 61d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz bool is_volatile) { 62d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(obj != nullptr); 63d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu(Thread::Current(), log_lock_); 64d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ObjectLog& object_log = object_logs_[obj]; 65d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz object_log.Log32BitsValue(field_offset, value, is_volatile); 66d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 67d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 68d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordWriteField64(mirror::Object* obj, MemberOffset field_offset, uint64_t value, 69d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz bool is_volatile) { 70d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(obj != nullptr); 71d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu(Thread::Current(), log_lock_); 72d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ObjectLog& object_log = object_logs_[obj]; 73d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz object_log.Log64BitsValue(field_offset, value, is_volatile); 74d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 75d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 76d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordWriteFieldReference(mirror::Object* obj, MemberOffset field_offset, 77d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Object* value, bool is_volatile) { 78d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(obj != nullptr); 79d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu(Thread::Current(), log_lock_); 80d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ObjectLog& object_log = object_logs_[obj]; 81d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz object_log.LogReferenceValue(field_offset, value, is_volatile); 82d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 83d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 84d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordWriteArray(mirror::Array* array, size_t index, uint64_t value) { 85d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(array != nullptr); 86d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(array->IsArrayInstance()); 87d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu(Thread::Current(), log_lock_); 88d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ArrayLog& array_log = array_logs_[array]; 89d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array_log.LogValue(index, value); 90d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 91d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 92d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordStrongStringInsertion(mirror::String* s, uint32_t hash_code) { 93d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(s != nullptr); 94d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz InternStringLog log(s, hash_code, InternStringLog::kStrongString, InternStringLog::kInsert); 95d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LogInternedString(log); 96d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 97d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 98d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordWeakStringInsertion(mirror::String* s, uint32_t hash_code) { 99d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(s != nullptr); 100d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz InternStringLog log(s, hash_code, InternStringLog::kWeakString, InternStringLog::kInsert); 101d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LogInternedString(log); 102d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 103d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 104d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordStrongStringRemoval(mirror::String* s, uint32_t hash_code) { 105d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz InternStringLog log(s, hash_code, InternStringLog::kStrongString, InternStringLog::kRemove); 106d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LogInternedString(log); 107d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 108d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 109d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::RecordWeakStringRemoval(mirror::String* s, uint32_t hash_code) { 110d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz InternStringLog log(s, hash_code, InternStringLog::kWeakString, InternStringLog::kRemove); 111d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LogInternedString(log); 112d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 113d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 114d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::LogInternedString(InternStringLog& log) { 115d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Locks::intern_table_lock_->AssertExclusiveHeld(Thread::Current()); 116d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu(Thread::Current(), log_lock_); 117d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz intern_string_logs_.push_front(log); 118d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 119d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 120d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::Abort() { 121d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK(!Runtime::Current()->IsActiveTransaction()); 122d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Thread* self = Thread::Current(); 123d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz self->AssertNoPendingException(); 124d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu1(self, *Locks::intern_table_lock_); 125d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu2(self, log_lock_); 126d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz UndoObjectModifications(); 127d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz UndoArrayModifications(); 128d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz UndoInternStringTableModifications(); 129d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 130d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 131d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::UndoObjectModifications() { 132d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // TODO we may not need to restore objects allocated during this transaction. Or we could directly 133d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // remove them from the heap. 134d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : object_logs_) { 135d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz it.second.Undo(it.first); 136d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 137d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz object_logs_.clear(); 138d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 139d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 140d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::UndoArrayModifications() { 141d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // TODO we may not need to restore array allocated during this transaction. Or we could directly 142d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // remove them from the heap. 143d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : array_logs_) { 144d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz it.second.Undo(it.first); 145d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 146d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array_logs_.clear(); 147d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 148d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 149d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::UndoInternStringTableModifications() { 150d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz InternTable* const intern_table = Runtime::Current()->GetInternTable(); 151d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // We want to undo each operation from the most recent to the oldest. List has been filled so the 152d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // most recent operation is at list begin so just have to iterate over it. 153d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (InternStringLog& string_log : intern_string_logs_) { 154d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz string_log.Undo(intern_table); 155d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 156d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz intern_string_logs_.clear(); 157d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 158d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 159d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::VisitRoots(RootCallback* callback, void* arg) { 160d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MutexLock mu(Thread::Current(), log_lock_); 161d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz VisitObjectLogs(callback, arg); 162d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz VisitArrayLogs(callback, arg); 163d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz VisitStringLogs(callback, arg); 164d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 165d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 166d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::VisitObjectLogs(RootCallback* callback, void* arg) { 167d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // List of moving roots. 168d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz typedef std::pair<mirror::Object*, mirror::Object*> ObjectPair; 169d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz std::list<ObjectPair> moving_roots; 170d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 171d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Visit roots. 172d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : object_logs_) { 173d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz it.second.VisitRoots(callback, arg); 174d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Object* old_root = it.first; 175815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier mirror::Object* new_root = old_root; 176815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier callback(&new_root, arg, 0, kRootUnknown); 177d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (new_root != old_root) { 178d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz moving_roots.push_back(std::make_pair(old_root, new_root)); 179d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 180d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 181d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 182d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Update object logs with moving roots. 183d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (const ObjectPair& pair : moving_roots) { 184d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Object* old_root = pair.first; 185d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Object* new_root = pair.second; 186d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz auto old_root_it = object_logs_.find(old_root); 187d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK(old_root_it != object_logs_.end()); 188d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK(object_logs_.find(new_root) == object_logs_.end()); 189d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz object_logs_.insert(std::make_pair(new_root, old_root_it->second)); 190d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz object_logs_.erase(old_root_it); 191d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 192d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 193d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 194d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::VisitArrayLogs(RootCallback* callback, void* arg) { 195d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // List of moving roots. 196d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz typedef std::pair<mirror::Array*, mirror::Array*> ArrayPair; 197d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz std::list<ArrayPair> moving_roots; 198d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 199d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : array_logs_) { 200d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Array* old_root = it.first; 201d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (old_root->IsObjectArray()) { 202d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz it.second.VisitRoots(callback, arg); 203d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 204815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier mirror::Array* new_root = old_root; 205815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier callback(reinterpret_cast<mirror::Object**>(&new_root), arg, 0, kRootUnknown); 206d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (new_root != old_root) { 207d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz moving_roots.push_back(std::make_pair(old_root, new_root)); 208d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 209d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 210d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 211d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Update array logs with moving roots. 212d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (const ArrayPair& pair : moving_roots) { 213d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Array* old_root = pair.first; 214d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Array* new_root = pair.second; 215d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz auto old_root_it = array_logs_.find(old_root); 216d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK(old_root_it != array_logs_.end()); 217d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK(array_logs_.find(new_root) == array_logs_.end()); 218d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array_logs_.insert(std::make_pair(new_root, old_root_it->second)); 219d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array_logs_.erase(old_root_it); 220d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 221d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 222d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 223d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::VisitStringLogs(RootCallback* callback, void* arg) { 224d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (InternStringLog& log : intern_string_logs_) { 225d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz log.VisitRoots(callback, arg); 226d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 227d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 228d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 229d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ObjectLog::Log32BitsValue(MemberOffset offset, uint32_t value, bool is_volatile) { 230d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz auto it = field_values_.find(offset.Uint32Value()); 231d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (it == field_values_.end()) { 232d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ObjectLog::FieldValue field_value; 233d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.value = value; 234d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.is_volatile = is_volatile; 235d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.kind = ObjectLog::k32Bits; 236d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_values_.insert(std::make_pair(offset.Uint32Value(), field_value)); 237d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 238d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 239d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 240d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ObjectLog::Log64BitsValue(MemberOffset offset, uint64_t value, bool is_volatile) { 241d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz auto it = field_values_.find(offset.Uint32Value()); 242d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (it == field_values_.end()) { 243d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ObjectLog::FieldValue field_value; 244d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.value = value; 245d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.is_volatile = is_volatile; 246d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.kind = ObjectLog::k64Bits; 247d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_values_.insert(std::make_pair(offset.Uint32Value(), field_value)); 248d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 249d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 250d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 251d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ObjectLog::LogReferenceValue(MemberOffset offset, mirror::Object* obj, bool is_volatile) { 252d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz auto it = field_values_.find(offset.Uint32Value()); 253d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (it == field_values_.end()) { 254d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ObjectLog::FieldValue field_value; 255d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.value = reinterpret_cast<uintptr_t>(obj); 256d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.is_volatile = is_volatile; 257d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.kind = ObjectLog::kReference; 258d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_values_.insert(std::make_pair(offset.Uint32Value(), field_value)); 259d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 260d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 261d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 262d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ObjectLog::Undo(mirror::Object* obj) { 263d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto& it : field_values_) { 264d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Garbage collector needs to access object's class and array's length. So we don't rollback 265d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // these values. 266d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz MemberOffset field_offset(it.first); 267d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (field_offset.Uint32Value() == mirror::Class::ClassOffset().Uint32Value()) { 268d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Skip Object::class field. 269d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz continue; 270d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 271d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (obj->IsArrayInstance() && 272d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_offset.Uint32Value() == mirror::Array::LengthOffset().Uint32Value()) { 273d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Skip Array::length field. 274d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz continue; 275d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 276d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz FieldValue& field_value = it.second; 277d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz UndoFieldWrite(obj, field_offset, field_value); 278d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 279d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 280d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 281d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ObjectLog::UndoFieldWrite(mirror::Object* obj, MemberOffset field_offset, 282d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz const FieldValue& field_value) { 283d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // TODO We may want to abort a transaction while still being in transaction mode. In this case, 284d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // we'd need to disable the check. 285d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz constexpr bool kCheckTransaction = true; 286d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz switch (field_value.kind) { 287d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case k32Bits: 288d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz obj->SetField32<false, kCheckTransaction>(field_offset, static_cast<uint32_t>(field_value.value), 289d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.is_volatile); 290d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 291d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case k64Bits: 292d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz obj->SetField64<false, kCheckTransaction>(field_offset, field_value.value, 293d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.is_volatile); 294d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 295d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case kReference: 296d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz obj->SetFieldObject<false, kCheckTransaction>(field_offset, 297d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz reinterpret_cast<mirror::Object*>(field_value.value), 298d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz field_value.is_volatile); 299d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 300d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz default: 301d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LOG(FATAL) << "Unknown value kind " << field_value.kind; 302d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 303d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 304d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 305d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 306d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ObjectLog::VisitRoots(RootCallback* callback, void* arg) { 307d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : field_values_) { 308d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz FieldValue& field_value = it.second; 309d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (field_value.kind == ObjectLog::kReference) { 310815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier mirror::Object* obj = 311815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier reinterpret_cast<mirror::Object*>(static_cast<uintptr_t>(field_value.value)); 312a559ccb7aa56a5871b1e77857c2b5e7101b8d371Sebastien Hertz if (obj != nullptr) { 313a559ccb7aa56a5871b1e77857c2b5e7101b8d371Sebastien Hertz callback(&obj, arg, 0, kRootUnknown); 314a559ccb7aa56a5871b1e77857c2b5e7101b8d371Sebastien Hertz field_value.value = reinterpret_cast<uintptr_t>(obj); 315a559ccb7aa56a5871b1e77857c2b5e7101b8d371Sebastien Hertz } 316d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 317d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 318d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 319d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 320d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::InternStringLog::Undo(InternTable* intern_table) { 321d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(intern_table != nullptr); 322d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz switch (string_op_) { 323d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case InternStringLog::kInsert: { 324d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz switch (string_kind_) { 325d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case InternStringLog::kStrongString: 326d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz intern_table->RemoveStrongFromTransaction(str_, hash_code_); 327d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 328d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case InternStringLog::kWeakString: 329d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz intern_table->RemoveWeakFromTransaction(str_, hash_code_); 330d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 331d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz default: 332d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LOG(FATAL) << "Unknown interned string kind"; 333d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 334d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 335d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 336d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 337d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case InternStringLog::kRemove: { 338d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz switch (string_kind_) { 339d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case InternStringLog::kStrongString: 340d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz intern_table->InsertStrongFromTransaction(str_, hash_code_); 341d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 342d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case InternStringLog::kWeakString: 343d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz intern_table->InsertWeakFromTransaction(str_, hash_code_); 344d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 345d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz default: 346d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LOG(FATAL) << "Unknown interned string kind"; 347d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 348d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 349d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 350d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 351d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz default: 352d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LOG(FATAL) << "Unknown interned string op"; 353d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 354d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 355d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 356d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 357d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::InternStringLog::VisitRoots(RootCallback* callback, void* arg) { 358815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier callback(reinterpret_cast<mirror::Object**>(&str_), arg, 0, kRootInternedString); 359d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 360d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 361d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ArrayLog::LogValue(size_t index, uint64_t value) { 362d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz auto it = array_values_.find(index); 363d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (it == array_values_.end()) { 364d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array_values_.insert(std::make_pair(index, value)); 365d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 366d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 367d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 368d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ArrayLog::Undo(mirror::Array* array) { 369d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(array != nullptr); 370d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(array->IsArrayInstance()); 371d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Primitive::Type type = array->GetClass()->GetComponentType()->GetPrimitiveType(); 372d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto it : array_values_) { 373d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz UndoArrayWrite(array, type, it.first, it.second); 374d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 375d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 376d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 377d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ArrayLog::UndoArrayWrite(mirror::Array* array, Primitive::Type array_type, 378d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz size_t index, uint64_t value) { 379d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // TODO We may want to abort a transaction while still being in transaction mode. In this case, 380d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // we'd need to disable the check. 381d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz switch (array_type) { 382d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimBoolean: 383d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsBooleanArray()->SetWithoutChecks<false>(index, static_cast<uint8_t>(value)); 384d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 385d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimByte: 386d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsByteArray()->SetWithoutChecks<false>(index, static_cast<int8_t>(value)); 387d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 388d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimChar: 389d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsCharArray()->SetWithoutChecks<false>(index, static_cast<uint16_t>(value)); 390d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 391d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimShort: 392d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsShortArray()->SetWithoutChecks<false>(index, static_cast<int16_t>(value)); 393d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 394d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimInt: 395d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsIntArray()->SetWithoutChecks<false>(index, static_cast<int32_t>(value)); 396d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 397d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimFloat: 398d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsFloatArray()->SetWithoutChecks<false>(index, static_cast<float>(value)); 399d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 400d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimLong: 401d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsLongArray()->SetWithoutChecks<false>(index, static_cast<int64_t>(value)); 402d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 403d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimDouble: 404d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz array->AsDoubleArray()->SetWithoutChecks<false>(index, static_cast<double>(value)); 405d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 406d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz case Primitive::kPrimNot: { 407d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::ObjectArray<mirror::Object>* obj_array = array->AsObjectArray<mirror::Object>(); 408d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz obj_array->SetWithoutChecks<false>(index, reinterpret_cast<mirror::Object*>( 409d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz static_cast<uintptr_t>(value))); 410d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz break; 411d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 412d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz default: 413d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz LOG(FATAL) << "Unsupported type " << array_type; 414d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 415d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 416d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 417d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzvoid Transaction::ArrayLog::VisitRoots(RootCallback* callback, void* arg) { 418d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz for (auto& it : array_values_) { 419d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz mirror::Object* obj = reinterpret_cast<mirror::Object*>(static_cast<uintptr_t>(it.second)); 420815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier callback(&obj, arg, 0, kRootUnknown); 421815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier it.second = reinterpret_cast<uintptr_t>(obj); 422d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 423d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 424d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 425d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} // namespace art 426