/* Copyright (C) 2016 The Android Open Source Project
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This file implements interfaces from the file jvmti.h. This implementation
 * is licensed under the same terms as the file jvmti.h.  The
 * copyright and license information for the file jvmti.h follows.
 *
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#ifndef ART_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_
#define ART_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_

#include <android-base/logging.h>
#include <android-base/macros.h>

#include "jvmti.h"

#include "ti_allocator.h"

namespace openjdkjvmti {

template <typename T> class JvmtiAllocator;

template <>
class JvmtiAllocator<void> {
 public:
  using value_type = void;
  using pointer = void*;
  using const_pointer = const void*;

  template <typename U>
  struct rebind {
    using other = JvmtiAllocator<U>;
  };

  explicit JvmtiAllocator(jvmtiEnv* env) : env_(env) {}
  JvmtiAllocator() : env_(nullptr) {}

  template <typename U>
  JvmtiAllocator(const JvmtiAllocator<U>& other)
      : env_(other.env_) {}

  JvmtiAllocator(const JvmtiAllocator& other) = default;
  JvmtiAllocator& operator=(const JvmtiAllocator& other) = default;
  ~JvmtiAllocator() = default;

 private:
  jvmtiEnv* env_;

  template <typename U>
  friend class JvmtiAllocator;

  template <typename U>
  friend bool operator==(const JvmtiAllocator<U>& lhs, const JvmtiAllocator<U>& rhs);
};

template <typename T>
class JvmtiAllocator {
 public:
  using value_type = T;
  using pointer = T*;
  using reference = T&;
  using const_pointer = const T*;
  using const_reference = const T&;
  using size_type = size_t;
  using difference_type = ptrdiff_t;

  template <typename U>
  struct rebind {
    using other = JvmtiAllocator<U>;
  };

  explicit JvmtiAllocator(jvmtiEnv* env) : env_(env) {}
  JvmtiAllocator() : env_(nullptr) {}

  template <typename U>
  JvmtiAllocator(const JvmtiAllocator<U>& other)
      : env_(other.env_) {}

  JvmtiAllocator(const JvmtiAllocator& other) = default;
  JvmtiAllocator& operator=(const JvmtiAllocator& other) = default;
  ~JvmtiAllocator() = default;

  size_type max_size() const {
    return static_cast<size_type>(-1) / sizeof(T);
  }

  pointer address(reference x) const { return &x; }
  const_pointer address(const_reference x) const { return &x; }

  pointer allocate(size_type n, JvmtiAllocator<void>::pointer hint ATTRIBUTE_UNUSED = nullptr) {
    DCHECK_LE(n, max_size());
    if (env_ == nullptr) {
      T* result = reinterpret_cast<T*>(AllocUtil::AllocateImpl(n * sizeof(T)));
      CHECK(result != nullptr || n == 0u);  // Abort if AllocateImpl() fails.
      return result;
    } else {
      unsigned char* result;
      jvmtiError alloc_error = env_->Allocate(n * sizeof(T), &result);
      CHECK(alloc_error == JVMTI_ERROR_NONE);
      return reinterpret_cast<T*>(result);
    }
  }
  void deallocate(pointer p, size_type n ATTRIBUTE_UNUSED) {
    if (env_ == nullptr) {
      AllocUtil::DeallocateImpl(reinterpret_cast<unsigned char*>(p));
    } else {
      jvmtiError dealloc_error = env_->Deallocate(reinterpret_cast<unsigned char*>(p));
      CHECK(dealloc_error == JVMTI_ERROR_NONE);
    }
  }

  void construct(pointer p, const_reference val) {
    new (static_cast<void*>(p)) value_type(val);
  }
  template <class U, class... Args>
  void construct(U* p, Args&&... args) {
    ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...);
  }
  void destroy(pointer p) {
    p->~value_type();
  }

  inline bool operator==(JvmtiAllocator const& other) {
    return env_ == other.env_;
  }
  inline bool operator!=(JvmtiAllocator const& other) {
    return !operator==(other);
  }

 private:
  jvmtiEnv* env_;

  template <typename U>
  friend class JvmtiAllocator;

  template <typename U>
  friend bool operator==(const JvmtiAllocator<U>& lhs, const JvmtiAllocator<U>& rhs);
};

template <typename T>
inline bool operator==(const JvmtiAllocator<T>& lhs, const JvmtiAllocator<T>& rhs) {
  return lhs.env_ == rhs.env_;
}

template <typename T>
inline bool operator!=(const JvmtiAllocator<T>& lhs, const JvmtiAllocator<T>& rhs) {
  return !(lhs == rhs);
}

}  // namespace openjdkjvmti

#endif  // ART_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_
