// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/object_graph.h"
#include "platform/assert.h"
#include "vm/unit_test.h"

namespace dart {

#if !defined(PRODUCT)

class CounterVisitor : public ObjectGraph::Visitor {
 public:
  // Records the number of objects and total size visited, excluding 'skip'
  // and any objects only reachable through 'skip'.
  CounterVisitor(RawObject* skip, RawObject* expected_parent)
      : count_(0), size_(0), skip_(skip), expected_parent_(expected_parent) {}

  virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
    RawObject* obj = it->Get();
    if (obj == skip_) {
      EXPECT(it->MoveToParent());
      EXPECT_EQ(expected_parent_, it->Get());
      return kBacktrack;
    }
    ++count_;
    size_ += obj->HeapSize();
    return kProceed;
  }

  int count() const { return count_; }
  int size() const { return size_; }

 private:
  int count_;
  intptr_t size_;
  RawObject* skip_;
  RawObject* expected_parent_;
};

ISOLATE_UNIT_TEST_CASE(ObjectGraph) {
  Isolate* isolate = thread->isolate();
  // Create a simple object graph with objects a, b, c, d:
  //  a+->b+->c
  //  +   +
  //  |   v
  //  +-->d
  Array& a = Array::Handle(Array::New(12, Heap::kNew));
  Array& b = Array::Handle(Array::New(2, Heap::kOld));
  Array& c = Array::Handle(Array::New(0, Heap::kOld));
  Array& d = Array::Handle(Array::New(0, Heap::kOld));
  a.SetAt(10, b);
  b.SetAt(0, c);
  b.SetAt(1, d);
  a.SetAt(11, d);
  intptr_t a_size = a.raw()->HeapSize();
  intptr_t b_size = b.raw()->HeapSize();
  intptr_t c_size = c.raw()->HeapSize();
  intptr_t d_size = d.raw()->HeapSize();
  {
    // No more allocation; raw pointers ahead.
    SafepointOperationScope safepoint(thread);
    RawObject* b_raw = b.raw();
    // Clear handles to cut unintended retained paths.
    b = Array::null();
    c = Array::null();
    d = Array::null();
    ObjectGraph graph(thread);
    {
      HeapIterationScope iteration_scope(thread, true);
      {
        // Compare count and size when 'b' is/isn't skipped.
        CounterVisitor with(Object::null(), Object::null());
        graph.IterateObjectsFrom(a, &with);
        CounterVisitor without(b_raw, a.raw());
        graph.IterateObjectsFrom(a, &without);
        // Only 'b' and 'c' were cut off.
        EXPECT_EQ(2, with.count() - without.count());
        EXPECT_EQ(b_size + c_size, with.size() - without.size());
      }
      {
        // Like above, but iterate over the entire isolate. The counts and sizes
        // are thus larger, but the difference should still be just 'b' and 'c'.
        CounterVisitor with(Object::null(), Object::null());
        graph.IterateObjects(&with);
        CounterVisitor without(b_raw, a.raw());
        graph.IterateObjects(&without);
        EXPECT_EQ(2, with.count() - without.count());
        EXPECT_EQ(b_size + c_size, with.size() - without.size());
      }
    }
    EXPECT_EQ(a_size + b_size + c_size + d_size,
              graph.SizeRetainedByInstance(a));
  }
  {
    // Get hold of c again.
    b ^= a.At(10);
    c ^= b.At(0);
    b = Array::null();
    ObjectGraph graph(thread);
    // A retaining path should end like this: c <- b <- a <- ...
    {
      HANDLESCOPE(thread);
      // Test null, empty, and length 1 array.
      intptr_t null_length =
          graph.RetainingPath(&c, Object::null_array()).length;
      intptr_t empty_length =
          graph.RetainingPath(&c, Object::empty_array()).length;
      Array& path = Array::Handle(Array::New(1, Heap::kNew));
      intptr_t one_length = graph.RetainingPath(&c, path).length;
      EXPECT_EQ(null_length, empty_length);
      EXPECT_EQ(null_length, one_length);
      EXPECT_LE(3, null_length);
    }
    {
      HANDLESCOPE(thread);
      Array& path = Array::Handle(Array::New(6, Heap::kNew));
      // Trigger a full GC to increase probability of concurrent tasks.
      isolate->heap()->CollectAllGarbage();
      intptr_t length = graph.RetainingPath(&c, path).length;
      EXPECT_LE(3, length);
      Array& expected_c = Array::Handle();
      expected_c ^= path.At(0);
      // c is the first element in b.
      Smi& offset_from_parent = Smi::Handle();
      offset_from_parent ^= path.At(1);
      EXPECT_EQ(Array::element_offset(0),
                offset_from_parent.Value() * kWordSize);
      Array& expected_b = Array::Handle();
      expected_b ^= path.At(2);
      // b is the element with index 10 in a.
      offset_from_parent ^= path.At(3);
      EXPECT_EQ(Array::element_offset(10),
                offset_from_parent.Value() * kWordSize);
      Array& expected_a = Array::Handle();
      expected_a ^= path.At(4);
      EXPECT(expected_c.raw() == c.raw());
      EXPECT(expected_b.raw() == a.At(10));
      EXPECT(expected_a.raw() == a.raw());
    }
  }
}

static void WeakHandleFinalizer(void* isolate_callback_data,
                                Dart_WeakPersistentHandle handle,
                                void* peer) {}

ISOLATE_UNIT_TEST_CASE(RetainingPathGCRoot) {
  Dart_PersistentHandle persistent_handle;
  Dart_WeakPersistentHandle weak_persistent_handle;
  Array& path = Array::Handle(Array::New(1, Heap::kNew));
  ObjectGraph graph(thread);
  Dart_Handle handle = Api::NewHandle(thread, path.raw());

  // GC root should be a local handle
  auto result = graph.RetainingPath(&path, path);
  EXPECT_STREQ(result.gc_root_type, "local handle");

  // GC root should now be a weak persistent handle
  {
    TransitionVMToNative transition(thread);
    weak_persistent_handle = Dart_NewWeakPersistentHandle(
        handle, reinterpret_cast<void*>(0xdeadbeef), 128, WeakHandleFinalizer);
  }
  result = graph.RetainingPath(&path, path);
  EXPECT_STREQ(result.gc_root_type, "weak persistent handle");

  // GC root should now be a persistent handle
  {
    TransitionVMToNative transition(thread);
    persistent_handle = Dart_NewPersistentHandle(handle);
  }
  result = graph.RetainingPath(&path, path);
  EXPECT_STREQ(result.gc_root_type, "persistent handle");

  // Delete the persistent handle. GC root should now be weak persistent handle
  {
    TransitionVMToNative transition(thread);
    Dart_DeletePersistentHandle(persistent_handle);
    persistent_handle = NULL;
  }
  result = graph.RetainingPath(&path, path);
  EXPECT_STREQ(result.gc_root_type, "weak persistent handle");

  // Delete the weak persistent handle. GC root should now be local handle.
  {
    TransitionVMToNative transition(thread);
    Dart_DeleteWeakPersistentHandle(weak_persistent_handle);
    weak_persistent_handle = NULL;
  }
  result = graph.RetainingPath(&path, path);
  EXPECT_STREQ(result.gc_root_type, "local handle");
}

#endif  // !defined(PRODUCT)

}  // namespace dart
