1 /*
2  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #ifndef _ALLOC_H_
27 #define _ALLOC_H_
28 
29 /* Use THIS_FILE when it is available. */
30 #ifndef THIS_FILE
31     #define THIS_FILE __FILE__
32 #endif
33 
34 #include "stdhdrs.h"
35 
36 // By defining std::bad_alloc in a local header file instead of including
37 // the Standard C++ <new> header file, we avoid making awt.dll dependent
38 // on msvcp50.dll. This reduces the size of the JRE by 500kb.
39 namespace std {
40     class bad_alloc {};
41 }
42 
43 #define SIZECALC_ALLOC_THROWING_BAD_ALLOC
44 #include "sizecalc.h"
45 
46 class awt_toolkit_shutdown {};
47 
48 // Disable "C++ Exception Specification ignored" warnings.
49 // These warnings are generated because VC++ 5.0 allows, but does not enforce,
50 // exception specifications. This #pragma can be safely removed when VC++
51 // is updated to enforce exception specifications.
52 #pragma warning(disable : 4290)
53 
54 #ifdef TRY
55 #error Multiple definitions of TRY
56 #endif
57 
58 #ifdef TRY_NO_VERIFY
59 #error Multiple definitions of TRY_NO_VERIFY
60 #endif
61 
62 #ifdef CATCH_BAD_ALLOC
63 #error Multiple definitions of CATCH_BAD_ALLOC
64 #endif
65 
66 #ifdef CATCH_BAD_ALLOC_RET
67 #error Multiple defintions of CATCH_BAD_ALLOC_RET
68 #endif
69 
70 #ifdef TRY_NO_JNI
71 #error Multiple definitions of TRY_NO_JNI
72 #endif
73 
74 #ifdef TRY_NO_VERIFY_NO_JNI
75 #error Multiple definitions of TRY_NO_VERIFY_NO_JNI
76 #endif
77 
78 #ifdef CATCH_BAD_ALLOC_NO_JNI
79 #error Multiple definitions of CATCH_BAD_ALLOC_NO_JNI
80 #endif
81 
82 #ifdef CATCH_BAD_ALLOC_RET_NO_JNI
83 #error Multiple defintions of CATCH_BAD_ALLOC_RET_NO_JNI
84 #endif
85 
86 // The unsafe versions of malloc, calloc, and realloc should not be used
87 #define malloc Do_Not_Use_malloc_Use_safe_Malloc_Instead
88 #define calloc Do_Not_Use_calloc_Use_safe_Calloc_Instead
89 #define realloc Do_Not_Use_realloc_Use_safe_Realloc_Instead
90 #define ExceptionOccurred Do_Not_Use_ExceptionOccurred_Use_safe_\
91 ExceptionOccurred_Instead
92 
93 // These three functions throw std::bad_alloc in an out of memory condition
94 // instead of returning 0. safe_Realloc will return 0 if memblock is not
95 // NULL and size is 0. safe_Malloc and safe_Calloc will never return 0.
96 void *safe_Malloc(size_t size) throw (std::bad_alloc);
97 void *safe_Calloc(size_t num, size_t size) throw (std::bad_alloc);
98 void *safe_Realloc(void *memblock, size_t size) throw (std::bad_alloc);
99 
100 // This function should be called instead of ExceptionOccurred. It throws
101 // std::bad_alloc if a java.lang.OutOfMemoryError is currently pending
102 // on the calling thread.
103 jthrowable safe_ExceptionOccurred(JNIEnv *env) throw (std::bad_alloc);
104 
105 // This function is called at the beginning of an entry point.
106 // Entry points are functions which are declared:
107 //   1. CALLBACK,
108 //   2. JNIEXPORT,
109 //   3. __declspec(dllexport), or
110 //   4. extern "C"
111 // A function which returns an HRESULT (an OLE function) is also an entry
112 // point.
113 void entry_point(void);
114 
115 // This function hangs indefinitely if the Toolkit is not active
116 void hang_if_shutdown(void);
117 
118 // This function throws awt_toolkit_shutdown if the Toolkit is not active
119 void throw_if_shutdown(void) throw (awt_toolkit_shutdown);
120 
121 // This function is called when a std::bad_alloc exception is caught
122 void handle_bad_alloc(void);
123 
124 // Uncomment to nondeterministically test OutOfMemory errors
125 // #define OUTOFMEM_TEST
126 
127 #ifdef OUTOFMEM_TEST
128     void *safe_Malloc_outofmem(size_t size, const char *, int)
129         throw (std::bad_alloc);
130     void *safe_Calloc_outofmem(size_t num, size_t size, const char *, int)
131         throw (std::bad_alloc);
132     void *safe_Realloc_outofmem(void *memblock, size_t size, const char *, int)
133         throw (std::bad_alloc);
134     void * CDECL operator new(size_t size, const char *, int)
135         throw (std::bad_alloc);
136 
137     #define safe_Malloc(size) \
138         safe_Malloc_outofmem(size, THIS_FILE, __LINE__)
139     #define safe_Calloc(num, size) \
140         safe_Calloc_outofmem(num, size, THIS_FILE, __LINE__)
141     #define safe_Realloc(memblock, size) \
142         safe_Realloc_outofmem(memblock, size, THIS_FILE, __LINE__)
143     #define new new(THIS_FILE, __LINE__)
144 #endif /* OUTOFMEM_TEST */
145 
146 #define TRY \
147     try { \
148         entry_point(); \
149         hang_if_shutdown();
150 // The _NO_HANG version of TRY causes the AWT native code to return to Java
151 // immediately if the Toolkit is not active. Normal AWT operations should
152 // never use this macro. It should only be used for cleanup routines where:
153 // (1) Hanging is not a valid option, because the method is called during
154 // execution of runFinalizersOnExit; and, (2) Execution of the method would
155 // generate a NullPointerException or other Exception.
156 #define TRY_NO_HANG \
157     try { \
158         entry_point(); \
159         throw_if_shutdown();
160 // The _NO_VERIFY version of TRY does not verify that the Toolkit is still
161 // active before proceeding. Normal AWT operations should never use this
162 // macro. It should only be used for cleanup routines which can safely
163 // execute after the Toolkit is disposed, and then only with caution. Users
164 // of this macro must be able to guarantee that the code which will execute
165 // will not generate a NullPointerException or other Exception.
166 #define TRY_NO_VERIFY \
167     try { \
168         entry_point();
169 #define CATCH_BAD_ALLOC \
170     } catch (std::bad_alloc&) { \
171         handle_bad_alloc(); \
172         return; \
173     } catch (awt_toolkit_shutdown&) {\
174         return; \
175     }
176 #define CATCH_BAD_ALLOC_RET(x) \
177     } catch (std::bad_alloc&) { \
178         handle_bad_alloc(); \
179         return (x); \
180     } catch (awt_toolkit_shutdown&) {\
181         return (0); \
182     }
183 
184 // The _NO_JNI versions of TRY and CATCH_BAD_ALLOC simply discard
185 // std::bad_alloc exceptions and thus should be avoided at all costs. They
186 // are only useful if the calling function currently holds the JNI lock
187 // for the thread. This lock is acquired by calling GetPrimitiveArrayCritical
188 // or GetStringCritical. No JNI function should be called by that thread
189 // until the corresponding Release function has been called.
190 
191 #define TRY_NO_JNI \
192     try { \
193         hang_if_shutdown();
194 #define TRY_NO_HANG_NO_JNI \
195     try { \
196         throw_if_shutdown();
197 #define TRY_NO_VERIFY_NO_JNI \
198     try {
199 #define CATCH_BAD_ALLOC_NO_JNI \
200     } catch (std::bad_alloc&) { \
201         return; \
202     } catch (awt_toolkit_shutdown&) {\
203         return; \
204     }
205 #define CATCH_BAD_ALLOC_RET_NO_JNI(x) \
206     } catch (std::bad_alloc&) { \
207         return (x); \
208     } catch (awt_toolkit_shutdown&) {\
209         return (0); \
210     }
211 
212 #endif /* _ALLOC_H_ */
213