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