1/* Copyright (C) 2016 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jvmti.h. This implementation 5 * is licensed under the same terms as the file jvmti.h. The 6 * copyright and license information for the file jvmti.h follows. 7 * 8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32#ifndef ART_RUNTIME_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_ 33#define ART_RUNTIME_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_ 34 35#include "base/logging.h" 36#include "base/macros.h" 37#include "jvmti.h" 38 39namespace openjdkjvmti { 40 41template <typename T> class JvmtiAllocator; 42 43template <> 44class JvmtiAllocator<void> { 45 public: 46 typedef void value_type; 47 typedef void* pointer; 48 typedef const void* const_pointer; 49 50 template <typename U> 51 struct rebind { 52 typedef JvmtiAllocator<U> other; 53 }; 54 55 explicit JvmtiAllocator(jvmtiEnv* env) : env_(env) {} 56 57 template <typename U> 58 JvmtiAllocator(const JvmtiAllocator<U>& other) // NOLINT, implicit 59 : env_(other.env_) {} 60 61 JvmtiAllocator(const JvmtiAllocator& other) = default; 62 JvmtiAllocator& operator=(const JvmtiAllocator& other) = default; 63 ~JvmtiAllocator() = default; 64 65 private: 66 jvmtiEnv* env_; 67 68 template <typename U> 69 friend class JvmtiAllocator; 70 71 template <typename U> 72 friend bool operator==(const JvmtiAllocator<U>& lhs, const JvmtiAllocator<U>& rhs); 73}; 74 75template <typename T> 76class JvmtiAllocator { 77 public: 78 typedef T value_type; 79 typedef T* pointer; 80 typedef T& reference; 81 typedef const T* const_pointer; 82 typedef const T& const_reference; 83 typedef size_t size_type; 84 typedef ptrdiff_t difference_type; 85 86 template <typename U> 87 struct rebind { 88 typedef JvmtiAllocator<U> other; 89 }; 90 91 explicit JvmtiAllocator(jvmtiEnv* env) : env_(env) {} 92 93 template <typename U> 94 JvmtiAllocator(const JvmtiAllocator<U>& other) // NOLINT, implicit 95 : env_(other.env_) {} 96 97 JvmtiAllocator(const JvmtiAllocator& other) = default; 98 JvmtiAllocator& operator=(const JvmtiAllocator& other) = default; 99 ~JvmtiAllocator() = default; 100 101 size_type max_size() const { 102 return static_cast<size_type>(-1) / sizeof(T); 103 } 104 105 pointer address(reference x) const { return &x; } 106 const_pointer address(const_reference x) const { return &x; } 107 108 pointer allocate(size_type n, JvmtiAllocator<void>::pointer hint ATTRIBUTE_UNUSED = nullptr) { 109 DCHECK_LE(n, max_size()); 110 if (env_ == nullptr) { 111 T* result = reinterpret_cast<T*>(malloc(n * sizeof(T))); 112 CHECK(result != nullptr || n == 0u); // Abort if malloc() fails. 113 return result; 114 } else { 115 unsigned char* result; 116 jvmtiError alloc_error = env_->Allocate(n * sizeof(T), &result); 117 CHECK(alloc_error == JVMTI_ERROR_NONE); 118 return reinterpret_cast<T*>(result); 119 } 120 } 121 void deallocate(pointer p, size_type n ATTRIBUTE_UNUSED) { 122 if (env_ == nullptr) { 123 free(p); 124 } else { 125 jvmtiError dealloc_error = env_->Deallocate(reinterpret_cast<unsigned char*>(p)); 126 CHECK(dealloc_error == JVMTI_ERROR_NONE); 127 } 128 } 129 130 void construct(pointer p, const_reference val) { 131 new (static_cast<void*>(p)) value_type(val); 132 } 133 template <class U, class... Args> 134 void construct(U* p, Args&&... args) { 135 ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...); 136 } 137 void destroy(pointer p) { 138 p->~value_type(); 139 } 140 141 inline bool operator==(JvmtiAllocator const& other) { 142 return env_ == other.env_; 143 } 144 inline bool operator!=(JvmtiAllocator const& other) { 145 return !operator==(other); 146 } 147 148 private: 149 jvmtiEnv* env_; 150 151 template <typename U> 152 friend class JvmtiAllocator; 153 154 template <typename U> 155 friend bool operator==(const JvmtiAllocator<U>& lhs, const JvmtiAllocator<U>& rhs); 156}; 157 158template <typename T> 159inline bool operator==(const JvmtiAllocator<T>& lhs, const JvmtiAllocator<T>& rhs) { 160 return lhs.env_ == rhs.env_; 161} 162 163template <typename T> 164inline bool operator!=(const JvmtiAllocator<T>& lhs, const JvmtiAllocator<T>& rhs) { 165 return !(lhs == rhs); 166} 167 168} // namespace openjdkjvmti 169 170#endif // ART_RUNTIME_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_ 171