/*
 * Copyright (C) 2013 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 "object_registry.h"

#include "handle_scope-inl.h"
#include "jni/jni_internal.h"
#include "mirror/class.h"
#include "mirror/throwable.h"
#include "obj_ptr-inl.h"
#include "scoped_thread_state_change-inl.h"

namespace art {

std::ostream& operator<<(std::ostream& os, const ObjectRegistryEntry& rhs) {
  os << "ObjectRegistryEntry[" << rhs.jni_reference_type
     << ",reference=" << rhs.jni_reference
     << ",count=" << rhs.reference_count
     << ",id=" << rhs.id << "]";
  return os;
}

ObjectRegistry::ObjectRegistry()
    : lock_("ObjectRegistry lock", kJdwpObjectRegistryLock), next_id_(1) {
  Locks::AddToExpectedMutexesOnWeakRefAccess(&lock_);
}

ObjectRegistry::~ObjectRegistry() {
  Locks::RemoveFromExpectedMutexesOnWeakRefAccess(&lock_);
}

JDWP::RefTypeId ObjectRegistry::AddRefType(ObjPtr<mirror::Class> c) {
  return Add(c);
}

JDWP::RefTypeId ObjectRegistry::AddRefType(Handle<mirror::Class> c_h) {
  return Add(c_h);
}

JDWP::ObjectId ObjectRegistry::Add(ObjPtr<mirror::Object> o) {
  if (o == nullptr) {
    return 0;
  }
  Thread* const self = Thread::Current();
  StackHandleScope<1> hs(self);
  return InternalAdd(hs.NewHandle(o));
}

// Template instantiations must be declared below.
template<class T>
JDWP::ObjectId ObjectRegistry::Add(Handle<T> obj_h) {
  if (obj_h == nullptr) {
    return 0;
  }
  return InternalAdd(obj_h);
}

// Explicit template instantiation.
template
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
JDWP::ObjectId ObjectRegistry::Add(Handle<mirror::Object> obj_h);

template
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
JDWP::ObjectId ObjectRegistry::Add(Handle<mirror::Throwable> obj_h);

template<class T>
JDWP::ObjectId ObjectRegistry::InternalAdd(Handle<T> obj_h) {
  CHECK(obj_h != nullptr);

  Thread* const self = Thread::Current();
  self->AssertNoPendingException();
  // Object::IdentityHashCode may cause these locks to be held so check we do not already
  // hold them.
  Locks::thread_list_lock_->AssertNotHeld(self);
  Locks::thread_suspend_count_lock_->AssertNotHeld(self);

  // Call IdentityHashCode here to avoid a lock level violation between lock_ and monitor_lock.
  int32_t identity_hash_code = obj_h->IdentityHashCode();

  ScopedObjectAccessUnchecked soa(self);
  MutexLock mu(soa.Self(), lock_);
  ObjectRegistryEntry* entry = nullptr;
  if (ContainsLocked(soa.Self(), obj_h.Get(), identity_hash_code, &entry)) {
    // This object was already in our map.
    ++entry->reference_count;
  } else {
    entry = new ObjectRegistryEntry;
    entry->jni_reference_type = JNIWeakGlobalRefType;
    entry->jni_reference = nullptr;
    entry->reference_count = 0;
    entry->id = 0;
    entry->identity_hash_code = identity_hash_code;
    object_to_entry_.insert(std::make_pair(identity_hash_code, entry));

    // This object isn't in the registry yet, so add it.
    JNIEnv* env = soa.Env();

    jobject local_reference = soa.AddLocalReference<jobject>(obj_h.Get());

    entry->jni_reference_type = JNIWeakGlobalRefType;
    entry->jni_reference = env->NewWeakGlobalRef(local_reference);
    entry->reference_count = 1;
    entry->id = next_id_++;

    id_to_entry_.Put(entry->id, entry);

    env->DeleteLocalRef(local_reference);
  }
  return entry->id;
}

bool ObjectRegistry::ContainsLocked(Thread* self,
                                    ObjPtr<mirror::Object> o,
                                    int32_t identity_hash_code,
                                    ObjectRegistryEntry** out_entry) {
  DCHECK(o != nullptr);
  for (auto it = object_to_entry_.lower_bound(identity_hash_code), end = object_to_entry_.end();
       it != end && it->first == identity_hash_code; ++it) {
    ObjectRegistryEntry* entry = it->second;
    if (o == self->DecodeJObject(entry->jni_reference)) {
      if (out_entry != nullptr) {
        *out_entry = entry;
      }
      return true;
    }
  }
  return false;
}

void ObjectRegistry::Clear() {
  Thread* const self = Thread::Current();

  // We must not hold the mutator lock exclusively if we want to delete weak global
  // references. Otherwise this can lead to a deadlock with a running GC:
  // 1. GC thread disables access to weak global references, then releases
  //    mutator lock.
  // 2. JDWP thread takes mutator lock exclusively after suspending all
  //    threads.
  // 3. GC thread waits for shared mutator lock which is held by JDWP
  //    thread.
  // 4. JDWP thread clears weak global references but need to wait for GC
  //    thread to re-enable access to them.
  Locks::mutator_lock_->AssertNotExclusiveHeld(self);

  MutexLock mu(self, lock_);
  VLOG(jdwp) << "Object registry contained " << object_to_entry_.size() << " entries";
  // Delete all the JNI references.
  JNIEnv* env = self->GetJniEnv();
  for (const auto& pair : object_to_entry_) {
    const ObjectRegistryEntry* entry = pair.second;
    if (entry->jni_reference_type == JNIWeakGlobalRefType) {
      env->DeleteWeakGlobalRef(entry->jni_reference);
    } else {
      env->DeleteGlobalRef(entry->jni_reference);
    }
    delete entry;
  }
  // Clear the maps.
  object_to_entry_.clear();
  id_to_entry_.clear();
}

mirror::Object* ObjectRegistry::InternalGet(JDWP::ObjectId id, JDWP::JdwpError* error) {
  Thread* self = Thread::Current();
  MutexLock mu(self, lock_);
  auto it = id_to_entry_.find(id);
  if (it == id_to_entry_.end()) {
    *error = JDWP::ERR_INVALID_OBJECT;
    return nullptr;
  }
  ObjectRegistryEntry& entry = *it->second;
  *error = JDWP::ERR_NONE;
  return self->DecodeJObject(entry.jni_reference).Ptr();
}

jobject ObjectRegistry::GetJObject(JDWP::ObjectId id) {
  if (id == 0) {
    return nullptr;
  }
  Thread* self = Thread::Current();
  MutexLock mu(self, lock_);
  auto it = id_to_entry_.find(id);
  CHECK(it != id_to_entry_.end()) << id;
  ObjectRegistryEntry& entry = *it->second;
  return entry.jni_reference;
}

void ObjectRegistry::DisableCollection(JDWP::ObjectId id) {
  Thread* self = Thread::Current();
  MutexLock mu(self, lock_);
  auto it = id_to_entry_.find(id);
  CHECK(it != id_to_entry_.end());
  Promote(*it->second);
}

void ObjectRegistry::EnableCollection(JDWP::ObjectId id) {
  Thread* self = Thread::Current();
  MutexLock mu(self, lock_);
  auto it = id_to_entry_.find(id);
  CHECK(it != id_to_entry_.end());
  Demote(*it->second);
}

void ObjectRegistry::Demote(ObjectRegistryEntry& entry) {
  if (entry.jni_reference_type == JNIGlobalRefType) {
    Thread* self = Thread::Current();
    JNIEnv* env = self->GetJniEnv();
    jobject global = entry.jni_reference;
    entry.jni_reference = env->NewWeakGlobalRef(entry.jni_reference);
    entry.jni_reference_type = JNIWeakGlobalRefType;
    env->DeleteGlobalRef(global);
  }
}

void ObjectRegistry::Promote(ObjectRegistryEntry& entry) {
  if (entry.jni_reference_type == JNIWeakGlobalRefType) {
    Thread* self = Thread::Current();
    JNIEnv* env = self->GetJniEnv();
    jobject weak = entry.jni_reference;
    entry.jni_reference = env->NewGlobalRef(entry.jni_reference);
    entry.jni_reference_type = JNIGlobalRefType;
    env->DeleteWeakGlobalRef(weak);
  }
}

bool ObjectRegistry::IsCollected(JDWP::ObjectId id) {
  Thread* self = Thread::Current();
  MutexLock mu(self, lock_);
  auto it = id_to_entry_.find(id);
  CHECK(it != id_to_entry_.end());
  ObjectRegistryEntry& entry = *it->second;
  if (entry.jni_reference_type == JNIWeakGlobalRefType) {
    JNIEnv* env = self->GetJniEnv();
    return env->IsSameObject(entry.jni_reference, nullptr);  // Has the jweak been collected?
  } else {
    return false;  // We hold a strong reference, so we know this is live.
  }
}

void ObjectRegistry::DisposeObject(JDWP::ObjectId id, uint32_t reference_count) {
  Thread* self = Thread::Current();
  MutexLock mu(self, lock_);
  auto it = id_to_entry_.find(id);
  if (it == id_to_entry_.end()) {
    return;
  }
  ObjectRegistryEntry* entry = it->second;
  entry->reference_count -= reference_count;
  if (entry->reference_count <= 0) {
    JNIEnv* env = self->GetJniEnv();
    // Erase the object from the maps. Note object may be null if it's
    // a weak ref and the GC has cleared it.
    int32_t hash_code = entry->identity_hash_code;
    for (auto inner_it = object_to_entry_.lower_bound(hash_code), end = object_to_entry_.end();
         inner_it != end && inner_it->first == hash_code; ++inner_it) {
      if (entry == inner_it->second) {
        object_to_entry_.erase(inner_it);
        break;
      }
    }
    if (entry->jni_reference_type == JNIWeakGlobalRefType) {
      env->DeleteWeakGlobalRef(entry->jni_reference);
    } else {
      env->DeleteGlobalRef(entry->jni_reference);
    }
    id_to_entry_.erase(id);
    delete entry;
  }
}

}  // namespace art
