| /* 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, [[maybe_unused]] JvmtiAllocator<void>::pointer hint = 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, [[maybe_unused]] size_type n) { |
| 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_ |