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_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_ 33 #define ART_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_ 34 35 #include <android-base/logging.h> 36 #include <android-base/macros.h> 37 38 #include "jvmti.h" 39 40 #include "ti_allocator.h" 41 42 namespace openjdkjvmti { 43 44 template <typename T> class JvmtiAllocator; 45 46 template <> 47 class JvmtiAllocator<void> { 48 public: 49 typedef void value_type; 50 typedef void* pointer; 51 typedef const void* const_pointer; 52 53 template <typename U> 54 struct rebind { 55 typedef JvmtiAllocator<U> other; 56 }; 57 JvmtiAllocator(jvmtiEnv * env)58 explicit JvmtiAllocator(jvmtiEnv* env) : env_(env) {} JvmtiAllocator()59 JvmtiAllocator() : env_(nullptr) {} 60 61 template <typename U> JvmtiAllocator(const JvmtiAllocator<U> & other)62 JvmtiAllocator(const JvmtiAllocator<U>& other) 63 : env_(other.env_) {} 64 65 JvmtiAllocator(const JvmtiAllocator& other) = default; 66 JvmtiAllocator& operator=(const JvmtiAllocator& other) = default; 67 ~JvmtiAllocator() = default; 68 69 private: 70 jvmtiEnv* env_; 71 72 template <typename U> 73 friend class JvmtiAllocator; 74 75 template <typename U> 76 friend bool operator==(const JvmtiAllocator<U>& lhs, const JvmtiAllocator<U>& rhs); 77 }; 78 79 template <typename T> 80 class JvmtiAllocator { 81 public: 82 typedef T value_type; 83 typedef T* pointer; 84 typedef T& reference; 85 typedef const T* const_pointer; 86 typedef const T& const_reference; 87 typedef size_t size_type; 88 typedef ptrdiff_t difference_type; 89 90 template <typename U> 91 struct rebind { 92 typedef JvmtiAllocator<U> other; 93 }; 94 JvmtiAllocator(jvmtiEnv * env)95 explicit JvmtiAllocator(jvmtiEnv* env) : env_(env) {} JvmtiAllocator()96 JvmtiAllocator() : env_(nullptr) {} 97 98 template <typename U> JvmtiAllocator(const JvmtiAllocator<U> & other)99 JvmtiAllocator(const JvmtiAllocator<U>& other) 100 : env_(other.env_) {} 101 102 JvmtiAllocator(const JvmtiAllocator& other) = default; 103 JvmtiAllocator& operator=(const JvmtiAllocator& other) = default; 104 ~JvmtiAllocator() = default; 105 max_size()106 size_type max_size() const { 107 return static_cast<size_type>(-1) / sizeof(T); 108 } 109 address(reference x)110 pointer address(reference x) const { return &x; } address(const_reference x)111 const_pointer address(const_reference x) const { return &x; } 112 113 pointer allocate(size_type n, JvmtiAllocator<void>::pointer hint ATTRIBUTE_UNUSED = nullptr) { 114 DCHECK_LE(n, max_size()); 115 if (env_ == nullptr) { 116 T* result = reinterpret_cast<T*>(AllocUtil::AllocateImpl(n * sizeof(T))); 117 CHECK(result != nullptr || n == 0u); // Abort if AllocateImpl() fails. 118 return result; 119 } else { 120 unsigned char* result; 121 jvmtiError alloc_error = env_->Allocate(n * sizeof(T), &result); 122 CHECK(alloc_error == JVMTI_ERROR_NONE); 123 return reinterpret_cast<T*>(result); 124 } 125 } deallocate(pointer p,size_type n ATTRIBUTE_UNUSED)126 void deallocate(pointer p, size_type n ATTRIBUTE_UNUSED) { 127 if (env_ == nullptr) { 128 AllocUtil::DeallocateImpl(reinterpret_cast<unsigned char*>(p)); 129 } else { 130 jvmtiError dealloc_error = env_->Deallocate(reinterpret_cast<unsigned char*>(p)); 131 CHECK(dealloc_error == JVMTI_ERROR_NONE); 132 } 133 } 134 construct(pointer p,const_reference val)135 void construct(pointer p, const_reference val) { 136 new (static_cast<void*>(p)) value_type(val); 137 } 138 template <class U, class... Args> construct(U * p,Args &&...args)139 void construct(U* p, Args&&... args) { 140 ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...); 141 } destroy(pointer p)142 void destroy(pointer p) { 143 p->~value_type(); 144 } 145 146 inline bool operator==(JvmtiAllocator const& other) { 147 return env_ == other.env_; 148 } 149 inline bool operator!=(JvmtiAllocator const& other) { 150 return !operator==(other); 151 } 152 153 private: 154 jvmtiEnv* env_; 155 156 template <typename U> 157 friend class JvmtiAllocator; 158 159 template <typename U> 160 friend bool operator==(const JvmtiAllocator<U>& lhs, const JvmtiAllocator<U>& rhs); 161 }; 162 163 template <typename T> 164 inline bool operator==(const JvmtiAllocator<T>& lhs, const JvmtiAllocator<T>& rhs) { 165 return lhs.env_ == rhs.env_; 166 } 167 168 template <typename T> 169 inline bool operator!=(const JvmtiAllocator<T>& lhs, const JvmtiAllocator<T>& rhs) { 170 return !(lhs == rhs); 171 } 172 173 } // namespace openjdkjvmti 174 175 #endif // ART_OPENJDKJVMTI_JVMTI_ALLOCATOR_H_ 176