* Updated header: Added 2006. Changed address of FSF. Changed email
[cacao.git] / src / native / vm / VMRuntime.c
1 /* src/native/vm/VMRuntime.c - java/lang/VMRuntime
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Roman Obermaiser
28
29    Changes: Joseph Wenninger
30             Christian Thalinger
31
32    $Id: VMRuntime.c 4357 2006-01-22 23:33:38Z twisti $
33
34 */
35
36
37 #include "config.h"
38
39 #include <assert.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include <sys/utsname.h>
43
44 #if !defined(ENABLE_STATICVM)
45 # include <ltdl.h>
46 #endif
47
48 #if defined(__DARWIN__)
49 # define OS_INLINE    /* required for <libkern/ppc/OSByteOrder.h> */
50 # include <mach/mach.h>
51 #endif
52
53 #include "vm/types.h"
54
55 #include "cacao/cacao.h"
56 #include "mm/boehm.h"
57 #include "mm/memory.h"
58 #include "native/jni.h"
59 #include "native/native.h"
60 #include "native/include/java_io_File.h"
61 #include "native/include/java_lang_String.h"
62 #include "native/include/java_lang_Process.h"
63 #include "toolbox/logging.h"
64 #include "vm/builtin.h"
65 #include "vm/exceptions.h"
66 #include "vm/loader.h"
67 #include "vm/stringlocal.h"
68
69
70 /* this should work on BSD */
71 /*
72 #if defined(__DARWIN__)
73 #include <sys/sysctl.h>
74 #endif
75 */
76
77
78 /* should we run all finalizers on exit? */
79 static bool finalizeOnExit = false;
80
81
82 /*
83  * Class:     java/lang/VMRuntime
84  * Method:    execInternal
85  * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
86  */
87 JNIEXPORT java_lang_Process* JNICALL Java_java_lang_VMRuntime_execInternal(JNIEnv *env, jclass clazz, java_objectarray *cmd, java_objectarray *shellenv, java_io_File *workingdir)
88 {
89         log_text("Java_java_lang_Runtime_execInternal called");
90
91         return NULL;
92 }
93
94
95 /*
96  * Class:     java/lang/VMRuntime
97  * Method:    exitInternal
98  * Signature: (I)V
99  */
100 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, s4 par1)
101 {
102         if (finalizeOnExit)
103                 gc_finalize_all();
104
105         cacao_shutdown(par1);
106 }
107
108
109 /*
110  * Class:     java/lang/VMRuntime
111  * Method:    freeMemory
112  * Signature: ()J
113  */
114 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
115 {
116         return gc_get_free_bytes();
117 }
118
119
120 /*
121  * Class:     java/lang/VMRuntime
122  * Method:    gc
123  * Signature: ()V
124  */
125 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
126 {
127         gc_call();
128 }
129
130
131 /*
132  * Class:     java/lang/VMRuntime
133  * Method:    runFinalization
134  * Signature: ()V
135  */
136 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jclass clazz)
137 {
138         gc_invoke_finalizers();
139 }
140
141
142 /*
143  * Class:     java/lang/VMRuntime
144  * Method:    runFinalizersOnExit
145  * Signature: (Z)V
146  */
147 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, s4 value)
148 {
149         /* XXX threading */
150
151         finalizeOnExit = value;
152 }
153
154
155 /*
156  * Class:     java/lang/VMRuntime
157  * Method:    runFinalizationsForExit
158  * Signature: ()V
159  */
160 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *env, jclass clazz)
161 {
162 /*      if (finalizeOnExit) { */
163 /*              gc_call(); */
164         /* gc_finalize_all(); */
165 /*      } */
166 /*      log_text("Java_java_lang_VMRuntime_runFinalizationForExit called"); */
167         /*gc_finalize_all();*/
168         /*gc_invoke_finalizers();*/
169         /*gc_call();*/
170 }
171
172
173 /*
174  * Class:     java/lang/VMRuntime
175  * Method:    totalMemory
176  * Signature: ()J
177  */
178 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
179 {
180         return gc_get_heap_size();
181 }
182
183
184 /*
185  * Class:     java/lang/VMRuntime
186  * Method:    traceInstructions
187  * Signature: (Z)V
188  */
189 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, jclass clazz, s4 par1)
190 {
191         /* not supported */
192 }
193
194
195 /*
196  * Class:     java/lang/VMRuntime
197  * Method:    traceMethodCalls
198  * Signature: (Z)V
199  */
200 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls(JNIEnv *env, jclass clazz, s4 par1)
201 {
202         /* not supported */
203 }
204
205
206 /*
207  * Class:     java_lang_Runtime
208  * Method:    availableProcessors
209  * Signature: ()I
210  */
211 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, jclass clazz)
212 {
213 #if defined(_SC_NPROC_ONLN)
214         return (s4) sysconf(_SC_NPROC_ONLN);
215
216 #elif defined(_SC_NPROCESSORS_ONLN)
217         return (s4) sysconf(_SC_NPROCESSORS_ONLN);
218
219 #elif defined(__DARWIN__)
220         /* this should work in BSD */
221         /*
222         int ncpu, mib[2], rc;
223         size_t len;
224
225         mib[0] = CTL_HW;
226         mib[1] = HW_NCPU;
227         len = sizeof(ncpu);
228         rc = sysctl(mib, 2, &ncpu, &len, NULL, 0);
229
230         return (s4) ncpu;
231         */
232
233         host_basic_info_data_t hinfo;
234         mach_msg_type_number_t hinfo_count = HOST_BASIC_INFO_COUNT;
235         kern_return_t rc;
236
237         rc = host_info(mach_host_self(), HOST_BASIC_INFO,
238                                    (host_info_t) &hinfo, &hinfo_count);
239  
240         if (rc != KERN_SUCCESS) {
241                 return -1;
242         }
243
244     return (s4) hinfo.avail_cpus;
245
246 #else
247         return 1;
248 #endif
249 }
250
251
252 /*
253  * Class:     java/lang/VMRuntime
254  * Method:    nativeLoad
255  * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)I
256  */
257 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *filename, java_lang_ClassLoader *loader)
258 {
259         utf         *name;
260 #if !defined(ENABLE_STATICVM)
261         lt_dlhandle  handle;
262         lt_ptr       onload;
263         s4           version;
264 #endif
265
266         if (!filename) {
267                 exceptions_throw_nullpointerexception();
268                 return 0;
269         }
270
271 #if defined(ENABLE_STATICVM)
272         return 1;
273 #else
274         name = javastring_toutf(filename, 0);
275
276         /* is the library already loaded? */
277
278         if (native_hashtable_library_find(name, (java_objectheader *) loader))
279                 return 1;
280
281         /* try to open the library */
282
283         if (!(handle = lt_dlopen(name->text)))
284                 return 0;
285
286         /* resolve JNI_OnLoad function */
287
288         if ((onload = lt_dlsym(handle, "JNI_OnLoad"))) {
289                 JNIEXPORT s4 (JNICALL *JNI_OnLoad) (JavaVM *, void *);
290                 JavaVM *vm;
291
292                 JNI_OnLoad = (JNIEXPORT s4 (JNICALL *)(JavaVM *, void *)) (ptrint) onload;
293
294                 (*env)->GetJavaVM(env, &vm);
295
296                 version = JNI_OnLoad(vm, NULL);
297
298                 /* if the version is not 1.2 and not 1.4 the library cannot be loaded */
299
300                 if (version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4) {
301                         lt_dlclose(handle);
302
303                         return 0;
304                 }
305         }
306
307         /* insert the library name into the library hash */
308
309         native_hashtable_library_add(name, (java_objectheader *) loader, handle);
310
311         return 1;
312 #endif
313 }
314
315
316 /*
317  * Class:     java/lang/VMRuntime
318  * Method:    mapLibraryName
319  * Signature: (Ljava/lang/String;)Ljava/lang/String;
320  */
321 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_mapLibraryName(JNIEnv *env, jclass clazz, java_lang_String *libname)
322 {
323         utf              *u;
324         char             *buffer;
325         s4                buffer_len;
326         s4                dumpsize;
327         java_lang_String *s;
328
329         if (!libname) {
330                 exceptions_throw_nullpointerexception();
331                 return NULL;
332         }
333
334         u = javastring_toutf(libname, 0);
335
336         /* calculate length of library name */
337
338         buffer_len = strlen("lib");
339
340         buffer_len += utf_strlen(u);
341
342 #if defined(__DARWIN__)
343         buffer_len += strlen(".dylib");
344 #else
345         buffer_len += strlen(".so");
346 #endif
347
348         buffer_len += strlen("0");
349
350         dumpsize = dump_size();
351         buffer = DMNEW(char, buffer_len);
352
353         /* generate library name, we use lt_dlopenext so we don't need an */
354         /* extension */
355
356         strcpy(buffer, "lib");
357         utf_strcat(buffer, u);
358
359 #if defined(__DARWIN__)
360         strcat(buffer, ".dylib");
361 #else
362         strcat(buffer, ".so");
363 #endif
364
365         s = javastring_new_char(buffer);
366
367         /* release memory */
368
369         dump_release(dumpsize);
370
371         return s;
372 }
373
374
375 /*
376  * Class:     java_lang_VMRuntime
377  * Method:    maxMemory
378  * Signature: ()J
379  */
380 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
381 {
382         return gc_get_max_heap_size();
383 }
384
385
386 /*
387  * These are local overrides for various environment variables in Emacs.
388  * Please do not remove this and leave it at the end of the file, where
389  * Emacs will automagically detect them.
390  * ---------------------------------------------------------------------
391  * Local variables:
392  * mode: c
393  * indent-tabs-mode: t
394  * c-basic-offset: 4
395  * tab-width: 4
396  * End:
397  */