/*
 * Copyright (C) 2015 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 "mod_union_table-inl.h"

#include "class_linker-inl.h"
#include "common_runtime_test.h"
#include "gc/space/space-inl.h"
#include "mirror/array-inl.h"
#include "space_bitmap-inl.h"
#include "thread-inl.h"

namespace art {
namespace gc {
namespace accounting {

class ModUnionTableFactory {
 public:
  enum TableType {
    kTableTypeCardCache,
    kTableTypeReferenceCache,
    kTableTypeCount,  // Number of values in the enum.
  };

  // Target space is ignored for the card cache implementation.
  static ModUnionTable* Create(
      TableType type, space::ContinuousSpace* space, space::ContinuousSpace* target_space);
};

class ModUnionTableTest : public CommonRuntimeTest {
 public:
  ModUnionTableTest() : java_lang_object_array_(nullptr) {
  }
  mirror::ObjectArray<mirror::Object>* AllocObjectArray(
      Thread* self, space::ContinuousMemMapAllocSpace* space, size_t component_count)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    auto* klass = GetObjectArrayClass(self, space);
    const size_t size = mirror::ComputeArraySize(component_count, 2);
    size_t bytes_allocated = 0, bytes_tl_bulk_allocated;
    auto* obj = down_cast<mirror::ObjectArray<mirror::Object>*>(
        space->Alloc(self, size, &bytes_allocated, nullptr, &bytes_tl_bulk_allocated));
    if (obj != nullptr) {
      obj->SetClass(klass);
      obj->SetLength(static_cast<int32_t>(component_count));
      space->GetLiveBitmap()->Set(obj);
      EXPECT_GE(bytes_allocated, size);
    }
    return obj;
  }
  void ResetClass() {
    java_lang_object_array_ = nullptr;
  }
  void RunTest(ModUnionTableFactory::TableType type);

 private:
  mirror::Class* GetObjectArrayClass(Thread* self, space::ContinuousMemMapAllocSpace* space)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    if (java_lang_object_array_ == nullptr) {
      java_lang_object_array_ =
          Runtime::Current()->GetClassLinker()->GetClassRoot(ClassLinker::kObjectArrayClass);
      // Since the test doesn't have an image, the class of the object array keeps cards live
      // inside the card cache mod-union table and causes the check
      // ASSERT_FALSE(table->ContainsCardFor(reinterpret_cast<uintptr_t>(obj3)));
      // to fail since the class ends up keeping the card dirty. To get around this, we make a fake
      // copy of the class in the same space that we are allocating in.
      DCHECK(java_lang_object_array_ != nullptr);
      const size_t class_size = java_lang_object_array_->GetClassSize();
      size_t bytes_allocated = 0, bytes_tl_bulk_allocated;
      auto* klass = down_cast<mirror::Class*>(space->Alloc(self, class_size, &bytes_allocated,
                                                           nullptr,
                                                           &bytes_tl_bulk_allocated));
      DCHECK(klass != nullptr);
      memcpy(klass, java_lang_object_array_, class_size);
      Runtime::Current()->GetHeap()->GetCardTable()->MarkCard(klass);
      java_lang_object_array_ = klass;
    }
    return java_lang_object_array_;
  }
  mirror::Class* java_lang_object_array_;
};

// Collect visited objects into container.
static void CollectVisitedCallback(mirror::HeapReference<mirror::Object>* ref, void* arg)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  DCHECK(ref != nullptr);
  DCHECK(arg != nullptr);
  reinterpret_cast<std::set<mirror::Object*>*>(arg)->insert(ref->AsMirrorPtr());
}

// A mod union table that only holds references to a specified target space.
class ModUnionTableRefCacheToSpace : public ModUnionTableReferenceCache {
 public:
  explicit ModUnionTableRefCacheToSpace(
      const std::string& name, Heap* heap, space::ContinuousSpace* space,
      space::ContinuousSpace* target_space)
      : ModUnionTableReferenceCache(name, heap, space), target_space_(target_space) {}

  bool ShouldAddReference(const mirror::Object* ref) const OVERRIDE {
    return target_space_->HasAddress(ref);
  }

 private:
  space::ContinuousSpace* const target_space_;
};

std::ostream& operator<<(std::ostream& oss, ModUnionTableFactory::TableType type) {
  switch (type) {
    case ModUnionTableFactory::kTableTypeCardCache: {
      oss << "CardCache";
      break;
    }
    case ModUnionTableFactory::kTableTypeReferenceCache: {
      oss << "ReferenceCache";
      break;
    }
    default: {
      UNIMPLEMENTED(FATAL) << static_cast<size_t>(type);
    }
  }
  return oss;
}

ModUnionTable* ModUnionTableFactory::Create(
    TableType type, space::ContinuousSpace* space, space::ContinuousSpace* target_space) {
  std::ostringstream name;
  name << "Mod union table: " << type;
  switch (type) {
    case kTableTypeCardCache: {
      return new ModUnionTableCardCache(name.str(), Runtime::Current()->GetHeap(), space);
    }
    case kTableTypeReferenceCache: {
      return new ModUnionTableRefCacheToSpace(name.str(), Runtime::Current()->GetHeap(), space,
                                              target_space);
    }
    default: {
      UNIMPLEMENTED(FATAL) << "Invalid type " << type;
    }
  }
  return nullptr;
}

TEST_F(ModUnionTableTest, TestCardCache) {
  RunTest(ModUnionTableFactory::kTableTypeCardCache);
}

TEST_F(ModUnionTableTest, TestReferenceCache) {
  RunTest(ModUnionTableFactory::kTableTypeReferenceCache);
}

void ModUnionTableTest::RunTest(ModUnionTableFactory::TableType type) {
  Thread* const self = Thread::Current();
  ScopedObjectAccess soa(self);
  Runtime* const runtime = Runtime::Current();
  gc::Heap* const heap = runtime->GetHeap();
  // Use non moving space since moving GC don't necessarily have a primary free list space.
  auto* space = heap->GetNonMovingSpace();
  ResetClass();
  // Create another space that we can put references in.
  std::unique_ptr<space::DlMallocSpace> other_space(space::DlMallocSpace::Create(
      "other space", 128 * KB, 4 * MB, 4 * MB, nullptr, false));
  ASSERT_TRUE(other_space.get() != nullptr);
  heap->AddSpace(other_space.get());
  std::unique_ptr<ModUnionTable> table(ModUnionTableFactory::Create(
      type, space, other_space.get()));
  ASSERT_TRUE(table.get() != nullptr);
  // Create some fake objects and put the main space and dirty cards in the non moving space.
  auto* obj1 = AllocObjectArray(self, space, CardTable::kCardSize);
  ASSERT_TRUE(obj1 != nullptr);
  auto* obj2 = AllocObjectArray(self, space, CardTable::kCardSize);
  ASSERT_TRUE(obj2 != nullptr);
  auto* obj3 = AllocObjectArray(self, space, CardTable::kCardSize);
  ASSERT_TRUE(obj3 != nullptr);
  auto* obj4 = AllocObjectArray(self, space, CardTable::kCardSize);
  ASSERT_TRUE(obj4 != nullptr);
  // Dirty some cards.
  obj1->Set(0, obj2);
  obj2->Set(0, obj3);
  obj3->Set(0, obj4);
  obj4->Set(0, obj1);
  // Dirty some more cards to objects in another space.
  auto* other_space_ref1 = AllocObjectArray(self, other_space.get(), CardTable::kCardSize);
  ASSERT_TRUE(other_space_ref1 != nullptr);
  auto* other_space_ref2 = AllocObjectArray(self, other_space.get(), CardTable::kCardSize);
  ASSERT_TRUE(other_space_ref2 != nullptr);
  obj1->Set(1, other_space_ref1);
  obj2->Set(3, other_space_ref2);
  table->ClearCards();
  std::set<mirror::Object*> visited;
  table->UpdateAndMarkReferences(&CollectVisitedCallback, &visited);
  // Check that we visited all the references in other spaces only.
  ASSERT_GE(visited.size(), 2u);
  ASSERT_TRUE(visited.find(other_space_ref1) != visited.end());
  ASSERT_TRUE(visited.find(other_space_ref2) != visited.end());
  // Verify that all the other references were visited.
  // obj1, obj2 cards should still be in mod union table since they have references to other
  // spaces.
  ASSERT_TRUE(table->ContainsCardFor(reinterpret_cast<uintptr_t>(obj1)));
  ASSERT_TRUE(table->ContainsCardFor(reinterpret_cast<uintptr_t>(obj2)));
  // obj3, obj4 don't have a reference to any object in the other space, their cards should have
  // been removed from the mod union table during UpdateAndMarkReferences.
  ASSERT_FALSE(table->ContainsCardFor(reinterpret_cast<uintptr_t>(obj3)));
  ASSERT_FALSE(table->ContainsCardFor(reinterpret_cast<uintptr_t>(obj4)));
  {
    // Currently no-op, make sure it still works however.
    ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_);
    table->Verify();
  }
  // Verify that dump doesn't crash.
  std::ostringstream oss;
  table->Dump(oss);
  // Set all the cards, then verify.
  table->SetCards();
  // TODO: Check that the cards are actually set.
  for (auto* ptr = space->Begin(); ptr < AlignUp(space->End(), CardTable::kCardSize);
      ptr += CardTable::kCardSize) {
    ASSERT_TRUE(table->ContainsCardFor(reinterpret_cast<uintptr_t>(ptr)));
  }
  // Visit again and make sure the cards got cleared back to their sane state.
  visited.clear();
  table->UpdateAndMarkReferences(&CollectVisitedCallback, &visited);
  // Verify that the dump matches what we saw earlier.
  std::ostringstream oss2;
  table->Dump(oss2);
  ASSERT_EQ(oss.str(), oss2.str());
  // Remove the space we added so it doesn't persist to the next test.
  heap->RemoveSpace(other_space.get());
}

}  // namespace accounting
}  // namespace gc
}  // namespace art
