* src/native/vm/gnu_java_lang_management_VMThreadMXBeanImpl.c: New file.
[cacao.git] / src / cacao / cacao.c
1 /* src/cacao/cacao.c - contains main() of cacao
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, 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: Reinhard Grafl
28
29    Changes: Andi Krall
30             Mark Probst
31             Philipp Tomsich
32             Christian Thalinger
33
34    $Id: cacao.c 5195 2006-07-31 15:26:10Z twisti $
35
36 */
37
38
39 #include "config.h"
40
41 #include <assert.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "vm/types.h"
46
47 #include "native/jni.h"
48 #include "native/include/java_lang_String.h"
49
50 #if defined(ENABLE_JVMTI)
51 #include "native/jvmti/jvmti.h"
52 #include "native/jvmti/cacaodbg.h"
53
54 #if defined(ENABLE_THREADS)
55 #include <pthread.h>
56 #endif
57 #endif
58
59 #include "toolbox/logging.h"
60 #include "vm/classcache.h"
61 #include "vm/exceptions.h"
62 #include "vm/global.h"
63 #include "vm/loader.h"
64 #include "vm/options.h"
65 #include "vm/statistics.h"
66 #include "vm/stringlocal.h"
67 #include "vm/suck.h"
68 #include "vm/vm.h"
69 #include "vm/jit/asmpart.h"
70 #include "vm/jit/jit.h"
71
72 #ifdef TYPEINFO_DEBUG_TEST
73 #include "vm/jit/verify/typeinfo.h"
74 #endif
75
76 #ifdef TYPECHECK_STATISTICS
77 void typecheck_print_statistics(FILE *file);
78 #endif
79
80 /* getmainclassfromjar *********************************************************
81
82    Gets the name of the main class form a JAR's manifest file.
83
84 *******************************************************************************/
85
86 static char *getmainclassnamefromjar(char *mainstring)
87 {
88         classinfo         *c;
89         java_objectheader *o;
90         methodinfo        *m;
91         java_lang_String  *s;
92
93         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
94
95         if (!c)
96                 throw_main_exception_exit();
97         
98         /* create JarFile object */
99
100         o = builtin_new(c);
101
102         if (!o)
103                 throw_main_exception_exit();
104
105
106         m = class_resolveclassmethod(c,
107                                                                  utf_init, 
108                                                                  utf_java_lang_String__void,
109                                                                  class_java_lang_Object,
110                                                                  true);
111
112         if (!m)
113                 throw_main_exception_exit();
114
115         s = javastring_new_from_ascii(mainstring);
116
117         (void) vm_call_method(m, o, s);
118
119         if (*exceptionptr)
120                 throw_main_exception_exit();
121
122         /* get manifest object */
123
124         m = class_resolveclassmethod(c,
125                                                                  utf_new_char("getManifest"), 
126                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
127                                                                  class_java_lang_Object,
128                                                                  true);
129
130         if (!m)
131                 throw_main_exception_exit();
132
133         o = vm_call_method(m, o);
134
135         if (o == NULL) {
136                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
137                 vm_exit(1);
138         }
139
140
141         /* get Main Attributes */
142
143         m = class_resolveclassmethod(o->vftbl->class,
144                                                                  utf_new_char("getMainAttributes"), 
145                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
146                                                                  class_java_lang_Object,
147                                                                  true);
148
149         if (!m)
150                 throw_main_exception_exit();
151
152         o = vm_call_method(m, o);
153
154         if (o == NULL) {
155                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
156                 vm_exit(1);
157         }
158
159
160         /* get property Main-Class */
161
162         m = class_resolveclassmethod(o->vftbl->class,
163                                                                  utf_new_char("getValue"), 
164                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
165                                                                  class_java_lang_Object,
166                                                                  true);
167
168         if (!m)
169                 throw_main_exception_exit();
170
171         s = javastring_new_from_ascii("Main-Class");
172
173         o = vm_call_method(m, o, s);
174
175         if (!o)
176                 throw_main_exception_exit();
177
178         return javastring_tochar(o);
179 }
180
181 void exit_handler(void);
182
183
184
185 /* main ************************************************************************
186
187    The main program.
188    
189 *******************************************************************************/
190
191 int main(int argc, char **argv)
192 {
193         s4 i;
194         
195         /* local variables ********************************************************/
196
197         JavaVMInitArgs *vm_args;
198         JavaVM         *jvm;                /* denotes a Java VM                  */
199
200         if (atexit(vm_exit_handler))
201                 throw_cacao_exception_exit(string_java_lang_InternalError,
202                                                                    "Unable to register exit_handler");
203
204
205         /**************************** Program start *****************************/
206
207         if (opt_verbose)
208                 log_text("CACAO started -------------------------------------------------------");
209
210         /* prepare the options */
211
212         vm_args = options_prepare(argc, argv);
213         
214         /* load and initialize a Java VM, return a JNI interface pointer in env */
215
216         JNI_CreateJavaVM(&jvm, (void *) &_Jv_env, vm_args);
217
218 #if defined(ENABLE_JVMTI)
219         pthread_mutex_init(&dbgcomlock,NULL);
220         if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
221 #endif
222
223         /* do we have a main class? */
224
225         if (mainstring == NULL)
226                 usage();
227
228
229         /* start worker routines **************************************************/
230
231         if (opt_run == true) {
232                 utf              *mainutf;
233                 classinfo        *mainclass;
234                 methodinfo       *m;
235                 java_objectarray *oa; 
236                 s4                oalength;
237                 java_lang_String *s;
238                 s4                status;
239
240                 /* set return value to OK */
241
242                 status = 0;
243
244                 if (opt_jar == true) {
245                         /* open jar file with java.util.jar.JarFile */
246                         mainstring = getmainclassnamefromjar(mainstring);
247                 }
248
249                 /* load the main class */
250
251                 mainutf = utf_new_char(mainstring);
252
253                 if (!(mainclass = load_class_from_sysloader(mainutf)))
254                         throw_main_exception_exit();
255
256                 /* error loading class, clear exceptionptr for new exception */
257
258                 if (*exceptionptr || !mainclass) {
259 /*                      *exceptionptr = NULL; */
260
261 /*                      *exceptionptr = */
262 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
263 /*                                                                        mainstring); */
264                         throw_main_exception_exit();
265                 }
266
267                 if (!link_class(mainclass))
268                         throw_main_exception_exit();
269                         
270                 /* find the `main' method of the main class */
271
272                 m = class_resolveclassmethod(mainclass,
273                                                                          utf_new_char("main"), 
274                                                                          utf_new_char("([Ljava/lang/String;)V"),
275                                                                          class_java_lang_Object,
276                                                                          false);
277
278                 if (*exceptionptr) {
279                         throw_main_exception_exit();
280                 }
281
282                 /* there is no main method or it isn't static */
283
284                 if (!m || !(m->flags & ACC_STATIC)) {
285                         *exceptionptr = NULL;
286
287                         *exceptionptr =
288                                 new_exception_message(string_java_lang_NoSuchMethodError,
289                                                                           "main");
290                         throw_main_exception_exit();
291                 }
292
293                 /* build argument array */
294
295                 oalength = vm_args->nOptions - opt_index;
296
297                 oa = builtin_anewarray(oalength, class_java_lang_String);
298
299                 for (i = 0; i < oalength; i++) {
300                         s = javastring_new(utf_new_char(vm_args->options[opt_index + i].optionString));
301                         oa->data[i] = (java_objectheader *) s;
302                 }
303
304 #ifdef TYPEINFO_DEBUG_TEST
305                 /* test the typeinfo system */
306                 typeinfo_test();
307 #endif
308                 /*class_showmethods(currentThread->group->header.vftbl->class); */
309
310 #if defined(ENABLE_JVMTI)
311                 jvmti_set_phase(JVMTI_PHASE_LIVE);
312 #endif
313
314                 /* increase total started thread count */
315
316                 _Jv_jvm->total_started_thread_count++;
317
318                 /* start the main thread */
319
320                 (void) vm_call_method(m, NULL, oa);
321
322                 /* exception occurred? */
323
324                 if (*exceptionptr) {
325                         throw_main_exception();
326                         status = 1;
327                 }
328
329                 /* unload the JavaVM */
330
331                 vm_destroy(jvm);
332
333                 /* and exit */
334
335                 vm_exit(status);
336         }
337
338
339         /* If requested, compile all methods. *************************************/
340
341 #if !defined(NDEBUG)
342         if (compileall) {
343                 classinfo *c;
344                 methodinfo *m;
345                 u4 slot;
346                 s4 i;
347                 classcache_name_entry *nmen;
348                 classcache_class_entry *clsen;
349
350                 /* create all classes found in the bootclasspath */
351                 /* XXX currently only works with zip/jar's */
352
353                 loader_load_all_classes();
354
355                 /* link all classes */
356
357                 for (slot = 0; slot < hashtable_classcache.size; slot++) {
358                         nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
359
360                         for (; nmen; nmen = nmen->hashlink) {
361                                 /* iterate over all class entries */
362
363                                 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
364                                         c = clsen->classobj;
365
366                                         if (!c)
367                                                 continue;
368
369                                         if (!(c->state & CLASS_LINKED)) {
370                                                 if (!link_class(c)) {
371                                                         fprintf(stderr, "Error linking: ");
372                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
373                                                         fprintf(stderr, "\n");
374
375                                                         /* print out exception and cause */
376
377                                                         exceptions_print_exception(*exceptionptr);
378
379                                                         /* goto next class */
380
381                                                         continue;
382                                                 }
383                                         }
384
385                                         /* compile all class methods */
386
387                                         for (i = 0; i < c->methodscount; i++) {
388                                                 m = &(c->methods[i]);
389
390                                                 if (m->jcode) {
391                                                         if (!jit_compile(m)) {
392                                                                 fprintf(stderr, "Error compiling: ");
393                                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
394                                                                 fprintf(stderr, ".");
395                                                                 utf_fprint_printable_ascii(stderr, m->name);
396                                                                 utf_fprint_printable_ascii(stderr, m->descriptor);
397                                                                 fprintf(stderr, "\n");
398
399                                                                 /* print out exception and cause */
400
401                                                                 exceptions_print_exception(*exceptionptr);
402                                                         }
403                                                 }
404                                         }
405                                 }
406                         }
407                 }
408         }
409 #endif /* !defined(NDEBUG) */
410
411
412         /* If requested, compile a specific method. *******************************/
413
414 #if !defined(NDEBUG)
415         if (opt_method != NULL) {
416                 methodinfo *m;
417
418                 /* create, load and link the main class */
419
420                 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
421                         throw_main_exception_exit();
422
423                 if (!link_class(mainclass))
424                         throw_main_exception_exit();
425
426                 if (opt_signature != NULL) {
427                         m = class_resolveclassmethod(mainclass,
428                                                                                  utf_new_char(opt_method),
429                                                                                  utf_new_char(opt_signature),
430                                                                                  mainclass,
431                                                                                  false);
432                 } else {
433                         m = class_resolveclassmethod(mainclass,
434                                                                                  utf_new_char(opt_method),
435                                                                                  NULL,
436                                                                                  mainclass,
437                                                                                  false);
438                 }
439
440                 if (!m) {
441                         char message[MAXLOGTEXT];
442                         sprintf(message, "%s%s", opt_method,
443                                         opt_signature ? opt_signature : "");
444
445                         *exceptionptr =
446                                 new_exception_message(string_java_lang_NoSuchMethodException,
447                                                                           message);
448                                                                                  
449                         throw_main_exception_exit();
450                 }
451                 
452                 jit_compile(m);
453         }
454
455         vm_shutdown(0);
456 #endif /* !defined(NDEBUG) */
457
458         /* keep compiler happy */
459
460         return 0;
461 }
462
463
464 /*
465  * These are local overrides for various environment variables in Emacs.
466  * Please do not remove this and leave it at the end of the file, where
467  * Emacs will automagically detect them.
468  * ---------------------------------------------------------------------
469  * Local variables:
470  * mode: c
471  * indent-tabs-mode: t
472  * c-basic-offset: 4
473  * tab-width: 4
474  * End:
475  */