/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "intern_table-inl.h"

#include <memory>

#include "class_linker.h"
#include "dex/utf.h"
#include "gc/collector/garbage_collector.h"
#include "gc/space/image_space.h"
#include "gc/weak_root_state.h"
#include "gc_root-inl.h"
#include "handle_scope-inl.h"
#include "mirror/dex_cache-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/string-inl.h"
#include "oat/image-inl.h"
#include "object_callbacks.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
#include "thread-inl.h"

namespace art HIDDEN {

InternTable::InternTable()
    : log_new_roots_(false),
      weak_intern_condition_("New intern condition", *Locks::intern_table_lock_),
      weak_root_state_(gc::kWeakRootStateNormal) {
}

size_t InternTable::Size() const {
  MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
  return strong_interns_.Size() + weak_interns_.Size();
}

size_t InternTable::StrongSize() const {
  MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
  return strong_interns_.Size();
}

size_t InternTable::WeakSize() const {
  MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
  return weak_interns_.Size();
}

void InternTable::DumpForSigQuit(std::ostream& os) const {
  os << "Intern table: " << StrongSize() << " strong; " << WeakSize() << " weak\n";
}

void InternTable::VisitRoots(RootVisitor* visitor, VisitRootFlags flags) {
  MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
  if ((flags & kVisitRootFlagAllRoots) != 0) {
    strong_interns_.VisitRoots(visitor);
  } else if ((flags & kVisitRootFlagNewRoots) != 0) {
    for (auto& root : new_strong_intern_roots_) {
      ObjPtr<mirror::String> old_ref = root.Read<kWithoutReadBarrier>();
      root.VisitRoot(visitor, RootInfo(kRootInternedString));
      ObjPtr<mirror::String> new_ref = root.Read<kWithoutReadBarrier>();
      if (new_ref != old_ref) {
        // The GC moved a root in the log. Need to search the strong interns and update the
        // corresponding object. This is slow, but luckily for us, this may only happen with a
        // concurrent moving GC.
        DCHECK(new_ref != nullptr);
        uint32_t hash = static_cast<uint32_t>(old_ref->GetStoredHashCode());
        DCHECK_EQ(hash, static_cast<uint32_t>(new_ref->GetStoredHashCode()));
        DCHECK(new_ref->Equals(old_ref));
        bool found = false;
        for (Table::InternalTable& table : strong_interns_.tables_) {
          auto it = table.set_.FindWithHash(GcRoot<mirror::String>(old_ref), hash);
          if (it != table.set_.end()) {
            *it = GcRoot<mirror::String>(new_ref);
            found = true;
            break;
          }
        }
        DCHECK(found);
      }
    }
  }
  if ((flags & kVisitRootFlagClearRootLog) != 0) {
    new_strong_intern_roots_.clear();
  }
  if ((flags & kVisitRootFlagStartLoggingNewRoots) != 0) {
    log_new_roots_ = true;
  } else if ((flags & kVisitRootFlagStopLoggingNewRoots) != 0) {
    log_new_roots_ = false;
  }
  // Note: we deliberately don't visit the weak_interns_ table and the immutable image roots.
}

ObjPtr<mirror::String> InternTable::LookupWeak(Thread* self, ObjPtr<mirror::String> s) {
  DCHECK(s != nullptr);
  // `String::GetHashCode()` ensures that the stored hash is calculated.
  uint32_t hash = static_cast<uint32_t>(s->GetHashCode());
  MutexLock mu(self, *Locks::intern_table_lock_);
  return weak_interns_.Find(s, hash);
}

ObjPtr<mirror::String> InternTable::LookupStrong(Thread* self, ObjPtr<mirror::String> s) {
  DCHECK(s != nullptr);
  // `String::GetHashCode()` ensures that the stored hash is calculated.
  uint32_t hash = static_cast<uint32_t>(s->GetHashCode());
  MutexLock mu(self, *Locks::intern_table_lock_);
  return strong_interns_.Find(s, hash);
}

ObjPtr<mirror::String> InternTable::LookupStrong(Thread* self,
                                                 uint32_t utf16_length,
                                                 const char* utf8_data) {
  uint32_t hash = Utf8String::Hash(utf16_length, utf8_data);
  MutexLock mu(self, *Locks::intern_table_lock_);
  return strong_interns_.Find(Utf8String(utf16_length, utf8_data), hash);
}

ObjPtr<mirror::String> InternTable::LookupWeakLocked(ObjPtr<mirror::String> s) {
  DCHECK(s != nullptr);
  // `String::GetHashCode()` ensures that the stored hash is calculated.
  uint32_t hash = static_cast<uint32_t>(s->GetHashCode());
  return weak_interns_.Find(s, hash);
}

ObjPtr<mirror::String> InternTable::LookupStrongLocked(ObjPtr<mirror::String> s) {
  DCHECK(s != nullptr);
  // `String::GetHashCode()` ensures that the stored hash is calculated.
  uint32_t hash = static_cast<uint32_t>(s->GetHashCode());
  return strong_interns_.Find(s, hash);
}

void InternTable::AddNewTable() {
  MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
  weak_interns_.AddNewTable();
  strong_interns_.AddNewTable();
}

ObjPtr<mirror::String> InternTable::InsertStrong(ObjPtr<mirror::String> s, uint32_t hash) {
  Runtime* runtime = Runtime::Current();
  if (runtime->IsActiveTransaction()) {
    runtime->GetClassLinker()->RecordStrongStringInsertion(s);
  }
  if (log_new_roots_) {
    new_strong_intern_roots_.push_back(GcRoot<mirror::String>(s));
  }
  strong_interns_.Insert(s, hash);
  return s;
}

ObjPtr<mirror::String> InternTable::InsertWeak(ObjPtr<mirror::String> s, uint32_t hash) {
  Runtime* runtime = Runtime::Current();
  if (runtime->IsActiveTransaction()) {
    runtime->GetClassLinker()->RecordWeakStringInsertion(s);
  }
  weak_interns_.Insert(s, hash);
  return s;
}

void InternTable::RemoveStrong(ObjPtr<mirror::String> s, uint32_t hash) {
  strong_interns_.Remove(s, hash);
}

void InternTable::RemoveWeak(ObjPtr<mirror::String> s, uint32_t hash) {
  Runtime* runtime = Runtime::Current();
  if (runtime->IsActiveTransaction()) {
    runtime->GetClassLinker()->RecordWeakStringRemoval(s);
  }
  weak_interns_.Remove(s, hash);
}

void InternTable::BroadcastForNewInterns() {
  Thread* self = Thread::Current();
  MutexLock mu(self, *Locks::intern_table_lock_);
  weak_intern_condition_.Broadcast(self);
}

void InternTable::WaitUntilAccessible(Thread* self) {
  Locks::intern_table_lock_->ExclusiveUnlock(self);
  {
    ScopedThreadSuspension sts(self, ThreadState::kWaitingWeakGcRootRead);
    MutexLock mu(self, *Locks::intern_table_lock_);
    while ((!gUseReadBarrier && weak_root_state_ == gc::kWeakRootStateNoReadsOrWrites) ||
           (gUseReadBarrier && !self->GetWeakRefAccessEnabled())) {
      weak_intern_condition_.Wait(self);
    }
  }
  Locks::intern_table_lock_->ExclusiveLock(self);
}

ObjPtr<mirror::String> InternTable::Insert(ObjPtr<mirror::String> s,
                                           uint32_t hash,
                                           bool is_strong,
                                           size_t num_searched_strong_frozen_tables) {
  DCHECK(s != nullptr);
  DCHECK_EQ(hash, static_cast<uint32_t>(s->GetStoredHashCode()));
  DCHECK_IMPLIES(hash == 0u, s->ComputeHashCode() == 0);
  Thread* const self = Thread::Current();
  MutexLock mu(self, *Locks::intern_table_lock_);
  if (kDebugLocking) {
    Locks::mutator_lock_->AssertSharedHeld(self);
    CHECK_EQ(2u, self->NumberOfHeldMutexes()) << "may only safely hold the mutator lock";
  }
  while (true) {
    // Check the strong table for a match.
    ObjPtr<mirror::String> strong =
        strong_interns_.Find(s, hash, num_searched_strong_frozen_tables);
    if (strong != nullptr) {
      return strong;
    }
    if (gUseReadBarrier ? self->GetWeakRefAccessEnabled()
                        : weak_root_state_ != gc::kWeakRootStateNoReadsOrWrites) {
      break;
    }
    num_searched_strong_frozen_tables = strong_interns_.tables_.size() - 1u;
    // weak_root_state_ is set to gc::kWeakRootStateNoReadsOrWrites in the GC pause but is only
    // cleared after SweepSystemWeaks has completed. This is why we need to wait until it is
    // cleared.
    StackHandleScope<1> hs(self);
    auto h = hs.NewHandleWrapper(&s);
    WaitUntilAccessible(self);
  }
  if (!gUseReadBarrier) {
    CHECK_EQ(weak_root_state_, gc::kWeakRootStateNormal);
  } else {
    CHECK(self->GetWeakRefAccessEnabled());
  }
  // There is no match in the strong table, check the weak table.
  ObjPtr<mirror::String> weak = weak_interns_.Find(s, hash);
  if (weak != nullptr) {
    if (is_strong) {
      // A match was found in the weak table. Promote to the strong table.
      RemoveWeak(weak, hash);
      return InsertStrong(weak, hash);
    }
    return weak;
  }
  // No match in the strong table or the weak table. Insert into the strong / weak table.
  return is_strong ? InsertStrong(s, hash) : InsertWeak(s, hash);
}

ObjPtr<mirror::String> InternTable::InternStrong(uint32_t utf16_length, const char* utf8_data) {
  DCHECK(utf8_data != nullptr);
  uint32_t hash = Utf8String::Hash(utf16_length, utf8_data);
  Thread* self = Thread::Current();
  ObjPtr<mirror::String> s;
  size_t num_searched_strong_frozen_tables;
  {
    // Try to avoid allocation. If we need to allocate, release the mutex before the allocation.
    MutexLock mu(self, *Locks::intern_table_lock_);
    DCHECK(!strong_interns_.tables_.empty());
    num_searched_strong_frozen_tables = strong_interns_.tables_.size() - 1u;
    s = strong_interns_.Find(Utf8String(utf16_length, utf8_data), hash);
  }
  if (s != nullptr) {
    return s;
  }
  bool is_ascii = (utf8_data[utf16_length] == 0);
  int32_t utf8_length = utf16_length + (LIKELY(is_ascii) ? 0 : strlen(utf8_data + utf16_length));
  DCHECK_EQ(static_cast<size_t>(utf8_length), strlen(utf8_data));
  s = mirror::String::AllocFromModifiedUtf8(self, utf16_length, utf8_data, utf8_length);
  if (UNLIKELY(s == nullptr)) {
    self->AssertPendingOOMException();
    return nullptr;
  }
  s->SetHashCode(static_cast<int32_t>(hash));
  return Insert(s, hash, /*is_strong=*/ true, num_searched_strong_frozen_tables);
}

ObjPtr<mirror::String> InternTable::InternStrong(const char* utf8_data) {
  DCHECK(utf8_data != nullptr);
  Thread* self = Thread::Current();
  ObjPtr<mirror::String> s = mirror::String::AllocFromModifiedUtf8(self, utf8_data);
  if (UNLIKELY(s == nullptr)) {
    self->AssertPendingOOMException();
    return nullptr;
  }
  return InternStrong(s);
}

ObjPtr<mirror::String> InternTable::InternStrong(ObjPtr<mirror::String> s) {
  DCHECK(s != nullptr);
  // `String::GetHashCode()` ensures that the stored hash is calculated.
  uint32_t hash = static_cast<uint32_t>(s->GetHashCode());
  return Insert(s, hash, /*is_strong=*/ true);
}

ObjPtr<mirror::String> InternTable::InternWeak(const char* utf8_data) {
  DCHECK(utf8_data != nullptr);
  Thread* self = Thread::Current();
  ObjPtr<mirror::String> s = mirror::String::AllocFromModifiedUtf8(self, utf8_data);
  if (UNLIKELY(s == nullptr)) {
    self->AssertPendingOOMException();
    return nullptr;
  }
  return InternWeak(s);
}

ObjPtr<mirror::String> InternTable::InternWeak(ObjPtr<mirror::String> s) {
  DCHECK(s != nullptr);
  // `String::GetHashCode()` ensures that the stored hash is calculated.
  uint32_t hash = static_cast<uint32_t>(s->GetHashCode());
  return Insert(s, hash, /*is_strong=*/ false);
}

void InternTable::SweepInternTableWeaks(IsMarkedVisitor* visitor) {
  MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
  weak_interns_.SweepWeaks(visitor);
}

void InternTable::Table::Remove(ObjPtr<mirror::String> s, uint32_t hash) {
  // Note: We can remove weak interns even from frozen tables when promoting to strong interns.
  // We can remove strong interns only for a transaction rollback.
  for (InternalTable& table : tables_) {
    auto it = table.set_.FindWithHash(GcRoot<mirror::String>(s), hash);
    if (it != table.set_.end()) {
      table.set_.erase(it);
      return;
    }
  }
  LOG(FATAL) << "Attempting to remove non-interned string " << s->ToModifiedUtf8();
}

FLATTEN
ObjPtr<mirror::String> InternTable::Table::Find(ObjPtr<mirror::String> s,
                                                uint32_t hash,
                                                size_t num_searched_frozen_tables) {
  Locks::intern_table_lock_->AssertHeld(Thread::Current());
  auto mid = tables_.begin() + num_searched_frozen_tables;
  for (Table::InternalTable& table : MakeIterationRange(tables_.begin(), mid)) {
    DCHECK(table.set_.FindWithHash(GcRoot<mirror::String>(s), hash) == table.set_.end());
  }
  // Search from the last table, assuming that apps shall search for their own
  // strings more often than for boot image strings.
  for (Table::InternalTable& table : ReverseRange(MakeIterationRange(mid, tables_.end()))) {
    auto it = table.set_.FindWithHash(GcRoot<mirror::String>(s), hash);
    if (it != table.set_.end()) {
      return it->Read();
    }
  }
  return nullptr;
}

FLATTEN
ObjPtr<mirror::String> InternTable::Table::Find(const Utf8String& string, uint32_t hash) {
  Locks::intern_table_lock_->AssertHeld(Thread::Current());
  // Search from the last table, assuming that apps shall search for their own
  // strings more often than for boot image strings.
  for (InternalTable& table : ReverseRange(tables_)) {
    auto it = table.set_.FindWithHash(string, hash);
    if (it != table.set_.end()) {
      return it->Read();
    }
  }
  return nullptr;
}

void InternTable::Table::AddNewTable() {
  // Propagate the min/max load factor from the old active set.
  DCHECK(!tables_.empty());
  const UnorderedSet& last_set = tables_.back().set_;
  InternalTable new_table;
  new_table.set_.SetLoadFactor(last_set.GetMinLoadFactor(), last_set.GetMaxLoadFactor());
  tables_.push_back(std::move(new_table));
}

void InternTable::Table::Insert(ObjPtr<mirror::String> s, uint32_t hash) {
  // Always insert the last table, the image tables are before and we avoid inserting into these
  // to prevent dirty pages.
  DCHECK(!tables_.empty());
  tables_.back().set_.PutWithHash(GcRoot<mirror::String>(s), hash);
}

void InternTable::Table::VisitRoots(RootVisitor* visitor) {
  BufferedRootVisitor<kDefaultBufferedRootCount> buffered_visitor(
      visitor, RootInfo(kRootInternedString));
  for (InternalTable& table : tables_) {
    for (auto& intern : table.set_) {
      buffered_visitor.VisitRoot(intern);
    }
  }
}

void InternTable::Table::SweepWeaks(IsMarkedVisitor* visitor) {
  for (InternalTable& table : tables_) {
    SweepWeaks(&table.set_, visitor);
  }
}

void InternTable::Table::SweepWeaks(UnorderedSet* set, IsMarkedVisitor* visitor) {
  for (auto it = set->begin(), end = set->end(); it != end;) {
    // This does not need a read barrier because this is called by GC.
    mirror::Object* object = it->Read<kWithoutReadBarrier>();
    mirror::Object* new_object = visitor->IsMarked(object);
    if (new_object == nullptr) {
      it = set->erase(it);
    } else {
      // Don't use AsString as it does IsString check in debug builds which, in
      // case of userfaultfd GC, is called when the object's content isn't
      // thereyet.
      *it = GcRoot<mirror::String>(ObjPtr<mirror::String>::DownCast(new_object));
      ++it;
    }
  }
}

size_t InternTable::Table::Size() const {
  return std::accumulate(tables_.begin(),
                         tables_.end(),
                         0U,
                         [](size_t sum, const InternalTable& table) {
                           return sum + table.Size();
                         });
}

void InternTable::ChangeWeakRootState(gc::WeakRootState new_state) {
  MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
  ChangeWeakRootStateLocked(new_state);
}

void InternTable::ChangeWeakRootStateLocked(gc::WeakRootState new_state) {
  CHECK(!gUseReadBarrier);
  weak_root_state_ = new_state;
  if (new_state != gc::kWeakRootStateNoReadsOrWrites) {
    weak_intern_condition_.Broadcast(Thread::Current());
  }
}

InternTable::Table::Table() {
  Runtime* const runtime = Runtime::Current();
  InternalTable initial_table;
  initial_table.set_.SetLoadFactor(runtime->GetHashTableMinLoadFactor(),
                                   runtime->GetHashTableMaxLoadFactor());
  tables_.push_back(std::move(initial_table));
}

}  // namespace art
