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