xref: /aosp_15_r20/art/openjdkjvmti/jvmti_allocator.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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