a few finalizer testcases, old thread implementation uses now VMThread, no mor contex...
[cacao.git] / src / native / vm / VMRuntime.c
1 /* nat/Runtime.c - java/lang/Runtime
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Roman Obermaiser
28
29    Changes: Joseph Wenninger
30             Christian Thalinger
31
32    $Id: VMRuntime.c 1173 2004-06-16 14:56:18Z jowenn $
33
34 */
35
36
37 #include <string.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <sys/utsname.h>
41 #include "main.h"
42 #include "jni.h"
43 #include "builtin.h"
44 #include "loader.h"
45 #include "native.h"
46 #include "tables.h"
47 #include "asmpart.h"
48 #include "mm/boehm.h"
49 #include "toolbox/logging.h"
50 #include "toolbox/memory.h"
51 #include "java_io_File.h"
52 #include "java_lang_String.h"
53 #include "java_lang_Process.h"
54 #include "java_util_Properties.h"    /* needed for java_lang_Runtime.h */
55 #include "java_lang_VMRuntime.h"
56
57
58 #define JOWENN_DEBUG
59
60 /* should we run all finalizers on exit? */
61 static s4 finalizeOnExit = false;
62
63 #define MAXPROPS 100
64 static bool shouldFinalizersBeRunOnExit=false;
65 static int activeprops = 19;  
66    
67 static char *proplist[MAXPROPS][2] = {
68         { "java.class.path", NULL },
69         { "java.home", NULL },
70         { "user.home", NULL },  
71         { "user.name", NULL },
72         { "user.dir",  NULL },
73                                 
74         { "os.arch", NULL },
75         { "os.name", NULL },
76         { "os.version", NULL },
77                                          
78         { "java.class.version", "45.3" },
79         { "java.version", PACKAGE":"VERSION },
80         { "java.vendor", "CACAO Team" },
81         { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
82         { "java.vm.name", "CACAO"}, 
83         { "java.tmpdir", "/tmp/"},
84         { "java.io.tmpdir", "/tmp/"},
85
86         { "path.separator", ":" },
87         { "file.separator", "/" },
88         { "line.separator", "\n" },
89         { "java.protocol.handler.pkgs", "gnu.java.net.protocol"}
90 };
91
92 void attach_property(char *name, char *value)
93 {
94         if (activeprops >= MAXPROPS) panic("Too many properties defined");
95         proplist[activeprops][0] = name;
96         proplist[activeprops][1] = value;
97         activeprops++;
98 }
99 /*
100  * Class:     java_lang_VMRuntime
101  * Method:    execInternal
102  * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
103  */
104 JNIEXPORT java_lang_Process* JNICALL Java_java_lang_VMRuntime_execInternal(JNIEnv *env, jclass clazz, java_objectarray *cmd, java_objectarray *shellenv, java_io_File *workingdir)
105 {
106         log_text("Java_java_lang_Runtime_execInternal called");
107
108         return NULL;
109 }
110
111
112 /*
113  * Class:     java/lang/VMRuntime
114  * Method:    exitInternal
115  * Signature: (I)V
116  */
117 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, s4 par1)
118 {
119         if (finalizeOnExit)
120                 gc_finalize_all();
121
122         cacao_shutdown(par1);
123 }
124
125
126 /*
127  * Class:     java/lang/Runtime
128  * Method:    freeMemory
129  * Signature: ()J
130  */
131 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
132 {
133         return gc_get_free_bytes();
134 }
135
136
137 /*
138  * Class:     java/lang/Runtime
139  * Method:    gc
140  * Signature: ()V
141  */
142 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
143 {
144         gc_call();
145 }
146
147
148 /*
149  * Class:     java/lang/Runtime
150  * Method:    runFinalization
151  * Signature: ()V
152  */
153 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jclass clazz)
154 {
155         gc_invoke_finalizers();
156 }
157
158
159 /*
160  * Class:     java/lang/Runtime
161  * Method:    runFinalizersOnExit
162  * Signature: (Z)V
163  */
164 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, s4 par1)
165 {
166 #warning threading
167         shouldFinalizersBeRunOnExit=par1;
168 }
169
170 /*
171  * Class:     java/lang/Runtime
172  * Method:    runFinalizationsForExit
173  * Signature: ()V
174  */
175 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *env, jclass clazz)
176 {
177         if (shouldFinalizersBeRunOnExit) {
178                 gc_call();
179         //      gc_finalize_all();
180         }
181         log_text("Java_java_lang_VMRuntime_runFinalizationForExit called");
182
183 }
184
185
186 /*
187  * Class:     java/lang/Runtime
188  * Method:    totalMemory
189  * Signature: ()J
190  */
191 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
192 {
193         return gc_get_heap_size();
194 }
195
196
197 /*
198  * Class:     java/lang/Runtime
199  * Method:    traceInstructions
200  * Signature: (Z)V
201  */
202 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, jclass clazz, s4 par1)
203 {
204         /* not supported */
205 }
206
207
208 /*
209  * Class:     java/lang/Runtime
210  * Method:    traceMethodCalls
211  * Signature: (Z)V
212  */
213 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls(JNIEnv *env, jclass clazz, s4 par1)
214 {
215         /* not supported */
216 }
217
218
219 /*
220  * Class:     java_lang_Runtime
221  * Method:    availableProcessors
222  * Signature: ()I
223  */
224 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, jclass clazz)
225 {
226 #if defined(_SC_NPROC_ONLN)
227         return (s4) sysconf(_SC_NPROC_ONLN);
228
229 #elif defined(_SC_NPROCESSORS_ONLN)
230         return (s4) sysconf(_SC_NPROCESSORS_ONLN);
231
232 #else
233         return 1;
234 #endif
235 }
236
237
238 /*
239  * Class:     java_lang_Runtime
240  * Method:    nativeLoad
241  * Signature: (Ljava/lang/String;)I
242  */
243 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *par1)
244 {
245 #ifdef JOWENN_DEBUG     
246         char *buffer;
247         int buffer_len;
248         utf *data;
249         
250         data = javastring_toutf(par1, 0);
251         
252         if (!data) {
253                 log_text("nativeLoad: Error: empty string");
254                 return 1;
255         }
256         
257         buffer_len = utf_strlen(data) + 40;
258
259                 
260         buffer = MNEW(char, buffer_len);
261
262         strcpy(buffer, "Java_java_lang_VMRuntime_nativeLoad:");
263         utf_sprint(buffer + strlen((char *) data), data);
264         log_text(buffer);       
265
266         MFREE(buffer, char, buffer_len);
267 #endif
268         log_text("Java_java_lang_VMRuntime_nativeLoad");
269
270         return 1;
271 }
272
273
274 /*
275  * Class:     java_lang_VMRuntime
276  * Method:    nativeGetLibname
277  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
278  */
279 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_nativeGetLibname(JNIEnv *env, jclass clazz, java_lang_String *par1, java_lang_String *par2)
280 {
281         char *buffer;
282         int buffer_len;
283         utf *data;
284         java_lang_String *resultString; 
285         data = javastring_toutf(par2, 0);
286         
287         if (!data) {
288                 log_text("nativeGetLibName: Error: empty string");
289                 return 0;;
290         }
291         
292         buffer_len = utf_strlen(data) + 6/*lib .so*/ +1 /*0*/;
293         buffer = MNEW(char, buffer_len);
294         sprintf(buffer,"lib");
295         utf_sprint(buffer+3,data);
296         strcat(buffer,".so");
297
298         log_text(buffer);
299         
300         resultString=javastring_new_char(buffer);       
301
302         MFREE(buffer, char, buffer_len);
303
304         return resultString;
305 }
306
307
308 /*
309  * Class:     java_lang_VMRuntime
310  * Method:    insertSystemProperties
311  * Signature: (Ljava/util/Properties;)V
312  */
313 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_insertSystemProperties(JNIEnv *env, jclass clazz, java_util_Properties *p)
314 {
315
316 #define BUFFERSIZE 200
317         u4 i;
318         methodinfo *m;
319         char buffer[BUFFERSIZE];
320         struct utsname utsnamebuf;
321
322         proplist[0][1] = classpath;
323         proplist[1][1] = getenv("JAVA_HOME");
324         proplist[2][1] = getenv("HOME");
325         proplist[3][1] = getenv("USER");
326         proplist[4][1] = getcwd(buffer, BUFFERSIZE);
327
328         /* get properties from system */
329         uname(&utsnamebuf);
330         proplist[5][1] = utsnamebuf.machine;
331         proplist[6][1] = utsnamebuf.sysname;
332         proplist[7][1] = utsnamebuf.release;
333
334         if (!p) {
335                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
336                 return;
337         }
338
339         /* search for method to add properties */
340         m = class_resolvemethod(p->header.vftbl->class,
341                                                         utf_new_char("put"),
342                                                         utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")
343                                                         );
344
345         if (!m) {
346                 *exceptionptr = new_exception_message(string_java_lang_NoSuchMethodError,
347                                                                                           "java.lang.Properties.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;)");
348                 return;
349         }
350
351         /* add the properties */
352         for (i = 0; i < activeprops; i++) {
353
354                 if (proplist[i][1] == NULL) proplist[i][1] = "";
355
356                 asm_calljavafunction(m,
357                                                          p,
358                                                          javastring_new_char(proplist[i][0]),
359                                                          javastring_new_char(proplist[i][1]),
360                                                          NULL
361                                                          );
362         }
363
364         return;
365 }
366
367
368 /*
369  * Class:     java_lang_VMRuntime
370  * Method:    maxMemory
371  * Signature: ()J
372  */
373 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
374 {
375         return gc_get_max_heap_size();
376 }
377
378
379 /*
380  * These are local overrides for various environment variables in Emacs.
381  * Please do not remove this and leave it at the end of the file, where
382  * Emacs will automagically detect them.
383  * ---------------------------------------------------------------------
384  * Local variables:
385  * mode: c
386  * indent-tabs-mode: t
387  * c-basic-offset: 4
388  * tab-width: 4
389  * End:
390  */