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