00001 /*! 00002 * @file jvm.c 00003 * 00004 * @brief Java Virtual Machine implementation on this real machine. 00005 * 00006 * Main entry point to the JVM and top-level implementation. 00007 * 00008 * @note Notice that the "Main Page" documentation resides in this 00009 * source file. In order for the users of Unix @b man(1) format 00010 * of these documents to see the "Main Page" item that is present 00011 * on the HTML format of these documents, please refer to the 00012 * source code of this file. 00013 * 00014 * @todo Need to verify which web document for the 00015 * Java 5 class file definition is either "official", 00016 * actually correct, or is the <em>de facto</em> standard. 00017 * 00018 * 00019 * @section Control 00020 * 00021 * \$URL: https://svn.apache.org/path/name/jvm.c $ \$Id: jvm.c 0 09/28/2005 dlydick $ 00022 * 00023 * Copyright 2005 The Apache Software Foundation 00024 * or its licensors, as applicable. 00025 * 00026 * Licensed under the Apache License, Version 2.0 ("the License"); 00027 * you may not use this file except in compliance with the License. 00028 * You may obtain a copy of the License at 00029 * 00030 * http://www.apache.org/licenses/LICENSE-2.0 00031 * 00032 * Unless required by applicable law or agreed to in writing, 00033 * software distributed under the License is distributed on an 00034 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 00035 * either express or implied. 00036 * 00037 * See the License for the specific language governing permissions 00038 * and limitations under the License. 00039 * 00040 * @version \$LastChangedRevision: 0 $ 00041 * 00042 * @date \$LastChangedDate: 09/28/2005 $ 00043 * 00044 * @author \$LastChangedBy: dlydick $ 00045 * Original code contributed by Daniel Lydick on 09/28/2005. 00046 * 00047 * @section Reference 00048 * 00049 */ 00050 00051 /*! 00052 * @mainpage 00053 * 00054 * This implementation of the Java Virtual Machine corresponds roughly 00055 * to these various source files for the overall structure. Details 00056 * not found in them are located throughout the body of the source code. 00057 * The following table shows this overall code structure. It is based 00058 * upon the table of contents to the above JVM specification document. 00059 * Where a @b .h C header file name is listed, the corresponding 00060 * @b .c C source file is of less interest to this structure than 00061 * the header that publishes it to the major subsystems, which are 00062 * listed by their @b .c C source file names. Across the top of each 00063 * page of documentation in most formats is is a line containing links 00064 * to key indices across the documentation. Other formats may not have 00065 * the links, but will have the same pages available. These categories 00066 * are: 00067 * 00068 * <ul> 00069 * <li><b>Main Page:</b> This starting point for all 00070 * documentation. 00071 * 00072 * </li> 00073 * <li><b>Namespace List:</b> Not really used since this is not a C++ 00074 * code base. However, it does contain 00075 * Java package name levels for test 00076 * classes and core JDK classes. 00077 * 00078 * </li> 00079 * <li><b>Alphabetical List:</b> Index of data structures, with name and 00080 * definition reference only. 00081 * 00082 * </li> 00083 * <li><b>Data Structures:</b> Index of data structures, with name, 00084 * description, and definition reference. 00085 * 00086 * </li> 00087 * <li><b>Directories:</b> Index of file system directories which 00088 * contain source files for this project. 00089 * 00090 * </li> 00091 * <li><b>File List:</b> Index of source files, by directory, 00092 * containing names, descriptions, and 00093 * references to source code. 00094 * 00095 * </li> 00096 * <li><b>Data Fields:</b> Index of member fields and methods in 00097 * Java classes, 'C' structs, and 'C' 00098 * unions, by member name. 00099 * 00100 * </li> 00101 * <li><b>Globals:</b> Global name space functions, variables, 00102 * type definitions, enumerations, and 00103 * pre-processor definitions, by category 00104 * and by name. (The term "global" does 00105 * @e not apply to symbol scope. Both 00106 * global scope and file scope symbols are 00107 * listed here. The global name space is 00108 * an OO concept typically used by Doxygen 00109 * to document C++ symbols. It is 00110 * meaningful here only in terms of Java 00111 * classes.) The categories are: 00112 * 00113 * <ul> 00114 * <li><b>Functions:</b> Function definitions, by name. 00115 * </li> 00116 * <li><b>Variables:</b> Variable definitions, by name. 00117 * </li> 00118 * <li><b>Typedefs:</b> Type definitions, by name. 00119 * (@b N.B. <em>It is here that the 00120 * convention of using letter @c @b j 00121 * and letter @c @b r for Java and 00122 * real machine domain data types is 00123 * most obvious.</em>) 00124 * </li> 00125 * <li><b>Enumerations:</b> Enumerations, by name. 00126 * </li> 00127 * <li><b>Enumerators:</b> Enumeration components, by name. 00128 * </li> 00129 * <li><b>Defines:</b> C pre-processor definitions, by 00130 * name. 00131 * 00132 * </li> 00133 * </ul> 00134 * </li> 00135 * <li><b>Data Fields:</b> Member fields and methods in Java 00136 * classes, 'C' structs, and 'C' unions, 00137 * by member name. 00138 * 00139 * </li> 00140 * </ul> 00141 * 00142 * The following table shows the JVM specification section number 00143 * in that document and a general location at which to start when 00144 * looking for its functionality. Any sections not listed below 00145 * are likely to @e not have yet been implemented here or are 00146 * more applicable to the class library and/or compiler. 00147 * 00148 * <ul> 00149 * <li><b>1.2 The Java Virtual Machine:</b> The main entry point 00150 * to to this JVM implementation is found in 00151 * @link #jvm() jvm.c@endlink. It sets up an 00152 * @link #rjvm rjvm@endlink structure using a 00153 * pervasive global variable named 00154 * @c @b pjvm to refer to a JVM 00155 * structure. It stands for, "pointer to JVM." 00156 * Variable names beginning with @b p stand for 00157 * "<b>p</b>ointer to...." Data 00158 * structure names beginning with @b r stand for 00159 * "<b>r</b>eal machine data type," 00160 * while data structure names beginning with 00161 * @b j stand for "<b>J</b>ava virtual machine 00162 * data type." 00163 * </li> 00164 * <li><b>2.1 Unicode:</b> Utilities found in 00165 * @link jvm/src/unicode.c unicode.c@endlink 00166 * </li> 00167 * <li><b>2.3 Literals:</b> Definitions found in 00168 * @link jvm/src/jrtypes.c jrtypes.c@endlink 00169 * </li> 00170 * <li><b>2.4.1 Primative Types and Values:</b> Initialized in 00171 * @link #class_load_primative class.c@endlink 00172 * </li> 00173 * <li><b>2.4.7 The class 'Object':</b> Implemented in 00174 * @link jvm/src/jlObject.c jlObject.c@endlink 00175 * </li> 00176 * <li><b>2.4.8 The class 'String':</b> Implemented in 00177 * @link jvm/src/jlString.c jlString.c@endlink 00178 * </li> 00179 * <li><b>2.5 Variables:</b> Implemented by 00180 * @link #jvalue jvalue@endlink members of 00181 * @link #rclass class.h@endlink and 00182 * @link #rclass class.h@endlink. 00183 * </li> 00184 * <li><b>2.6 Conversions and Promotions:</b> All actions on variables 00185 * are performed in the JVM inner loop in 00186 * @link #opcode_run() opcode.c@endlink 00187 * </li> 00188 * <li><b>2.6.6 Value Set Conversion:</b> NOT IMPLEMENTED. It is 00189 * assumed that the platform's native floating 00190 * point hardware implements the IEEE floating 00191 * point used by the JVM and with the same 00192 * constraints, which is not likely to be a 00193 * completely valid presupposition. FP-strict 00194 * expressions from section 2.18 are likewise 00195 * NOT IMPLEMENTED. 00196 * </li> 00197 * <li><b>2.6.7 Assignment Conversion:</b> All actions on variables are 00198 * performed in the JVM inner loop in 00199 * @link #opcode_run() opcode.c@endlink 00200 * </li> 00201 * <li><b>2.8 Classes:</b> Implemented in 00202 * @link jvm/src/class.c class.c@endlink 00203 * </li> 00204 * <li><b>2.9 Fields:</b> Implemented in 00205 * @link jvm/src/class.c class.c@endlink and 00206 * @link jvm/src/field.c field.c@endlink 00207 * </li> 00208 * <li><b>2.10 Methods:</b> Implemented in 00209 * @link jvm/src/class.c class.c@endlink and 00210 * @link jvm/src/method.c method.c@endlink 00211 * </li> 00212 * <li><b>2.11 Static Initializers:</b> Implemented in 00213 * @link #opcode_run() opcode.c@endlink 00214 * </li> 00215 * <li><b>2.12 Constructors:</b> Implemented in 00216 * @link #opcode_run() opcode.c@endlink 00217 * </li> 00218 * <li><b>2.13 Interfaces:</b> Implemented in 00219 * @link jvm/src/class.c class.c@endlink and 00220 * @link jvm/src/method.c method.c@endlink 00221 * </li> 00222 * <li><b>2.15 Arrays:</b> Implemented in 00223 * @link jvm/src/class.c class.c@endlink and 00224 * @link jvm/src/object.c object.c@endlink 00225 * </li> 00226 * <li><b>2.16 Exceptions:</b> Implemented in 00227 * @link jvm/src/exit.c exit.c@endlink and 00228 * @link jvm/src/thread.c thread.c@endlink and 00229 * @link jvm/src/opcode.c opcode.c@endlink and 00230 * @link jvm/src/jvmclass.h jvmclass.h@endlink 00231 * and all source code referencing the classes 00232 * defined in this header. Most code that calls 00233 * @c @b setjmp(3) or @c @b longjmp(3) is 00234 * processing an exception of some type, with 00235 * the single exclusion of the @c @b while() 00236 * loop of the inner JVM execution in 00237 * @link #opcode_run() opcode.c@endlink . 00238 * </li> 00239 * <li><b>2.17 Execution:</b> Implemented in 00240 * @link jvm/src/jvm.c jvm.c@endlink and 00241 * @link jvm/src/opcode.c opcode.c@endlink . 00242 * </li> 00243 * <li><b>2.17.1 Virtual Machine Start-up:</b> Implemented in 00244 * @link jvm/src/jvm.c jvm.c@endlink . 00245 * </li> 00246 * <li><b>2.17.2 Loading:</b> Implemented in 00247 * @link jvm/src/classfile.c classfile.c@endlink and 00248 * @link jvm/src/cfattrib.c cfattrib.c@endlink and 00249 * @link #class_static_new() class.c@endlink. The 00250 * occurrence of a newly loaded Java class is called 00251 * a "class static instance" in this implementation. 00252 * This is over and against the term for an instance 00253 * of an object of this class type, which is known as 00254 * an "object instance". 00255 * </li> 00256 * <li><b>2.17.3 Linking:</b> Implemented in 00257 * @link jvm/src/linkage.c linkage.c@endlink 00258 * </li> 00259 * <li><b>2.17.4,5 Initialization:</b> Implemented in 00260 * @link #opcode_run() opcode.c@endlink 00261 * </li> 00262 * <li><b>2.17.6 Creation of New Class Instances:</b> Implemented in 00263 * @link #object_instance_new() object.c@endlink . 00264 * The occurrence of a newly created Java object 00265 * is called an "object instance" in this 00266 * implementation. This is over and against 00267 * the term for the loading and definition of 00268 * a Java class itself, which is known as a 00269 * "class static instance", of which type this 00270 * object is one specific 00271 * @c @b instanceof among many. 00272 * </li> 00273 * <li><b>2.17.7 Finalization of Class Instances:</b> Implemented in 00274 * @link jvm/src/unicode.c unicode.c@endlink 00275 * </li> 00276 * <li><b>2.17.8 Unloading of Classes and Interfaces:</b> Implemented 00277 * in @link #class_static_delete class.c@endlink 00278 * </li> 00279 * <li><b>2.17.9 Virtural Machine Exit:</b> Implemented in 00280 * @link #jvm_shutdown() jvm.c@endlink as a 00281 * consequence of an exception in 00282 * @link #exit_jvm() exit.c@endlink or of 00283 * completion of execution in 00284 * @link #jvm() jvm.c@endlink as a 00285 * </li> 00286 * <li><b>2.18 FP-strict Expressions:</b> NOT IMPLEMENTED. Value set 00287 * conversions expressions from section 2.6.6 00288 * are likewise NOT IMPLEMENTED. 00289 * </li> 00290 * <li><b>2.19 Threads:</b> Implemented in 00291 * @link jvm/src/threadstate.c 00292 threadstate.c@endlink, as driven by 00293 * @link #jvm_run() jvm.c@endlink and 00294 * the infrastructure of 00295 * @link jvm/src/thread.c thread.c@endlink 00296 * </li> 00297 * <li><b>3.2 Data types:</b> Implemented in 00298 * @link jvm/src/class.c class.c@endlink 00299 * </li> 00300 * <li><b>3.3 Primative Types and Values:</b> Implemented in 00301 * @link #opcode_run() opcode.c@endlink 00302 * </li> 00303 * <li><b>3.4 Reference Types and Values:</b> Implemented in 00304 * @link #opcode_run() opcode.c@endlink as 00305 * supported by the infrastructure of 00306 * @link jvm/src/class.c class.c@endlink 00307 * </li> 00308 * <li><b>3.5.1 The PC Register:</b> Implemented in 00309 * @link #jvm_pc jvmreg.h@endlink 00310 * </li> 00311 * <li><b>3.5.2 Java Virtual Machine stacks:</b> Implemented in 00312 * @link #jvm_sp jvmreg.h@endlink 00313 * </li> 00314 * <li><b>3.5.3 Heap:</b> Interface defined in 00315 * @link jvm/src/heap.h heap.h@endlink and 00316 * implemented twice in 00317 * @link jvm/src/heap_simple.c 00318 heap_simple.c@endlink and in 00319 * @link jvm/src/heap_bimodal.c 00320 heap_bimodal.c@endlink . The choice of 00321 * implementation is done at configuration time 00322 * using @link config.sh config.sh@endlink . 00323 * A generic "roll your own" option is available 00324 * for those who are implementing heap modules. 00325 * Three heap regions are defined, one for 00326 * class file and method storage, one for 00327 * JVM stack areas, and one for general-purpose 00328 * data areas. 00329 * </li> 00330 * <li><b>3.5.4 Method Area:</b> One of the heap storage areas defined 00331 * in @link jvm/src/heap.h heap.h@endlink, 00332 * where @e all class file related structures 00333 * are stored. 00334 * </li> 00335 * <li><b>3.5.5 Runtime Constant Pool:</b> Implemented as a part of 00336 * the method area storage (section 3.5.4) 00337 * in the heap (section 3.5.3). 00338 * </li> 00339 * <li><b>3.5.6 Native Method Stacks:</b> Since all JVM activities 00340 * except the millisecond time slice (see 00341 * @link jvm/src/timeslice.c 00342 timeslice.c@endlink) operate on the same 00343 * POSIX thread, native methods use the same 00344 * real machine stack as the main JVM code's 00345 * POSIX thread. See also native method 00346 * invocation in @link #native_run_method() 00347 native.c@endlink 00348 * </li> 00349 * <li><b>3.6 Frames:</b> Implemented in 00350 * @link jvm/src/jvmreg.h jvmreg.h@endlink 00351 * </li> 00352 * <li><b>3.6.1 Local Variables:</b> Implemented inside the JVM stack 00353 * frame (per section 3.6), found in 00354 * @link jvm/src/jvmreg.h jvmreg.h@endlink 00355 * </li> 00356 * <li><b>3.6.2 Operand Stacks:</b> Implemented on the top of the JVM 00357 * stack frame (per section 3.6), found in 00358 * @link jvm/src/jvmreg.h jvmreg.h@endlink 00359 * </li> 00360 * <li><b>3.6.3 Dynamic Linking:</b> Implemented in 00361 * @link #opcode_run() opcode.c@endlink and 00362 * @link #linkage_resolve_class() 00363 linkage.c@endlink 00364 * </li> 00365 * <li><b>3.6.4 Normal Method Invocation Completion:</b> Implemented in 00366 * @link #opcode_run opcode.c@endlink 00367 * </li> 00368 * <li><b>3.6.5 Abrupt Method Invocation Completion:</b> Implemented in 00369 * @link #opcode_run opcode.c@endlink 00370 * </li> 00371 * <li><b>3.7 Representation of Objects:</b> Implemented in 00372 * @link jvm/src/object.c object.c@endlink and 00373 * @link jvm/src/object.h object.h@endlink and 00374 * @link jvm/src/jlObject.c jlObject.c@endlink 00375 * </li> 00376 * <li><b>3.8 Floating-Point Arithmetic:</b> See comments above on 00377 * section 2.6.6 about how floating point 00378 * arithmetic is implemented. 00379 * </li> 00380 * <li><b>3.9 Specially Named Initialization Methods:</b> Implemented 00381 * in @link #opcode_run() opcode.c@endlink 00382 * </li> 00383 * <li><b>2.16 Exceptions:</b> See comments above on section 2.16. 00384 * </li> 00385 * <li><b>3.11 Instruction Set Summary:</b> The JVM outer loop is 00386 * implemented in 00387 * @link #jvm_run() jvm.c@endlink , while the 00388 * inner look is implemented in 00389 * @link #opcode_run() opcode.c@endlink . 00390 * All of the <b>section 3.11.x</b> headings 00391 * fall under the category of the inner loop. 00392 * </li> 00393 * <li><b>3.12 Class Libraries:</b> Only minimal support is provied 00394 * for class libraries, and that only enough 00395 * to start the machine. See especially support 00396 * for the environment variable @b BOOTCLASSPATH 00397 * and its command line override equivalent as 00398 * implemented in 00399 * @link #classpath_get_from_prchar() 00400 classpath.c@endlink 00401 * </li> 00402 * <li><b>4 The ClassFile Structure:</b> Implemented in 00403 * @link jvm/src/classfile.c classfile.c@endlink and 00404 * @link jvm/src/cfattrib.c cfattrib.c@endlink and 00405 * extensively referenced throughout the code in 00406 * @link jvm/src/classfile.h classfile.h@endlink . 00407 * A pervasive local variable named 00408 * @c @b pcfs (or prefixed this way) 00409 * is found <em>all over</em> the code and refers to 00410 * a ClassFile data structure. It stands for, "pointer 00411 * to ClassFile structure." 00412 * </li> 00413 * <li><b>5 Linking, Loading, and Initializing:</b> Implemented in 00414 * structures of 00415 * @link jvm/src/classfile.h classfile.h@endlink 00416 * by the late binding logic of 00417 * @link jvm/src/linkage.c linkage.c@endlink 00418 * that is typically initiated by 00419 * @link #opcode_run opcode.c@endlink . 00420 * Classes are dynamically loaded by 00421 * @link #class_static_new() class.c@endlink 00422 * objects are dynamically created by 00423 * @link #object_instance_new() object.c@endlink 00424 * </li> 00425 * <li><b>5.3.1 Loading Using the Bootstrap Class Loader:</b> Implemented 00426 * in @link #class_load_from_cp_entry_utf class.c@endlink 00427 * </li> 00428 * <li><b>5.3.3 Creating Array Classes:</b> are part and parcel of all 00429 * other class creations, with support built in 00430 * to its implementation in 00431 * @link #class_static_new() class.c@endlink 00432 * </li> 00433 * <li><b>5.6 Binding Native Method Implementations:</b> Implemented in 00434 * @link #native_locate_local_method() native.c@endlink 00435 * </li> 00436 * <li><b>6 The Java Virtual Machine Instruction Set:</b> Implemented 00437 * in @link #opcode_run() opcode.c@endlink with 00438 * opcode definitions (per section 9) in 00439 * @link jvm/src/opcode.h opcode.h@endlink 00440 * </li> 00441 * <li><b>8 Threads and Locks:</b> See comments above on section 2.19. 00442 * See also the native implementation of a 00443 * part of @c @b java.lang.Thread in 00444 * @link jvm/src/jlThread.c jlThread.c@endlink 00445 * </li> 00446 * <li><b>9 Opcode Mnemonics By Opcode:</b> Implemented in 00447 * @link jvm/src/opcode.h opcode.h@endlink 00448 * </li> 00449 * </ul> 00450 * 00451 * The garbage collection system is designed to be configurable like 00452 * the heap is (see comments above on section 3.5.3). Its interface 00453 * is defined in @link jvm/src/gc.h gc.h@endlink and a sample stub 00454 * implementation is found in @link jvm/src/gc_stub.c 00455 gc_stub.c@endlink . The choice of implementation is done at 00456 * configuration time using @link config.sh config.sh@endlink . 00457 * A generic "roll your own" option is available for those who are 00458 * implementing garbage collection modules. 00459 * 00460 * (The following description of source code directories is also found 00461 * in @link ./README README@endlink for display as a simple text file.) 00462 * 00463 * Several directories are provided within the source tree: 00464 * 00465 * <ul> 00466 * <li><b>jvm:</b></li> Source code for JVM, including a main() 00467 * wrapper. Builds binary file 00468 * @c @b jvm/bin/bootjvm . 00469 * 00470 * </li> 00471 * <li><b>libjvm:</b></li> For building @c @b jvm as a statically 00472 * linked library archive, less main() 00473 * wrapper. Builds library archive 00474 * @c @b libjvm/lib/libjvm.a . Source 00475 * code comes from the @c @b jvm 00476 * directory. 00477 * 00478 * </li> 00479 * <li><b>main:</b></li> A simple main() wrapper that links 00480 * @c @b libjvm/lib/libjvm.a and builds 00481 * binary file @c @b main/bin/bootjvm . 00482 * Source code comes from the @c @b jvm 00483 * directory. 00484 * 00485 * </li> 00486 * <li><b>jni:</b></li> Source code for a sample JNI shared 00487 * library 00488 * <code><b>jni/harmony/generic/0.0/lib/bootjni.so</b></code> 00489 * for linking with JNI code, but needs the 00490 * build directives to be functional, as it 00491 * currently links statically with a main() 00492 * into a binary just like @c @b jvm . 00493 * This directory contains a tree for JNI 00494 * implementations from any supplier that 00495 * wants to support the Harmony project. 00496 * Currently, there is one JNI implementation 00497 * here, found in 00498 * @c @b jni/src/harmony/generic/0.0 . 00499 * 00500 * </li> 00501 * <li><b>test:</b></li> Builds numerous Java test classes in 00502 * @c @b test/bin for driving 00503 * development work. 00504 * 00505 * </li> 00506 * </ul> 00507 * 00508 * With the exception of the Java test classes in @c @b test/src 00509 * all source code is found in @c @b jvm/src and in the directory 00510 * tree @c @b jni/src/vendor/product/version . The purpose of 00511 * @C @b libjvm and @c @b main is for demonstrating various 00512 * possible organizations for the source code, namely for building 00513 * a static library archive and for linking it. 00514 * 00515 * There are a few references to JNI (Java Native Interface) in the 00516 * outline above. The following subset of @c @b java.lang 00517 * classes are directly implemented in the interior of this JVM: 00518 * 00519 * <ul> 00520 * <li>@c @b java.lang.Object 00521 * </li> 00522 * <li>@c @b java.lang.Class 00523 * </li> 00524 * <li>@c @b java.lang.String 00525 * </li> 00526 * <li>@c @b java.lang.Thread 00527 * </li> 00528 * </ul> 00529 * 00530 * This JNI subset is implemented here in the following groups 00531 * of source files: 00532 * 00533 * <ul> 00534 * <li> 00535 * Java source code for the four classes: 00536 * 00537 * <ul> 00538 * <li>@link jni/src/harmony/generic/0.0/src/java/lang/Object.java 00539 jni/src/harmony/generic/0.0/src/java/lang/Object.java@endlink 00540 * </li> 00541 * <li>@link jni/src/harmony/generic/0.0/src/java/lang/Class.java 00542 jni/src/harmony/generic/0.0/src/java/lang/Class.java@endlink 00543 * </li> 00544 * <li>@link jni/src/harmony/generic/0.0/src/java/lang/String.java 00545 jni/src/harmony/generic/0.0/src/java/lang/String.java@endlink 00546 * </li> 00547 * <li>@link jni/src/harmony/generic/0.0/src/java/lang/Thread.java 00548 jni/src/harmony/generic/0.0/src/java/lang/Thread.java@endlink 00549 * </li> 00550 * </ul> 00551 * </li> 00552 * 00553 * <li> 00554 * JNI headers derived from Java source code (typically via @b javah): 00555 * 00556 * <ul> 00557 * <li>@link jni/src/harmony/generic/0.0/include/java_lang_Object.h 00558 jni/src/harmony/generic/0.0/include/java_lang_Object.h@endlink 00559 * </li> 00560 * <li>@link jni/src/harmony/generic/0.0/include/java_lang_Class.h 00561 jni/src/harmony/generic/0.0/include/java_lang_Class.h@endlink 00562 * </li> 00563 * <li>@link jni/src/harmony/generic/0.0/include/java_lang_String.h 00564 jni/src/harmony/generic/0.0/include/java_lang_String.h@endlink 00565 * </li> 00566 * <li>@link jni/src/harmony/generic/0.0/include/java_lang_Thread.h 00567 jni/src/harmony/generic/0.0/include/java_lang_Thread.h@endlink 00568 * </li> 00569 * </ul> 00570 * </li> 00571 * 00572 * <li> 00573 * C source implementation of native methods defined by JNI headers: 00574 * 00575 * <ul> 00576 * <li>@link jni/src/harmony/generic/0.0/src/java_lang_Object.c 00577 jni/src/harmony/generic/0.0/src/java_lang_Object.c@endlink 00578 * </li> 00579 * <li>@link jni/src/harmony/generic/0.0/src/java_lang_Class.c 00580 jni/src/harmony/generic/0.0/src/java_lang_Class.c@endlink 00581 * </li> 00582 * <li>@link jni/src/harmony/generic/0.0/src/java_lang_String.c 00583 jni/src/harmony/generic/0.0/src/java_lang_String.c@endlink 00584 * </li> 00585 * <li>@link jni/src/harmony/generic/0.0/src/java_lang_Thread.c 00586 jni/src/harmony/generic/0.0/src/java_lang_Thread.c@endlink 00587 * </li> 00588 * </ul> 00589 * </li> 00590 * 00591 * <li> 00592 * JVM core implementation of native methods "local native methods" 00593 * of these classes: 00594 * 00595 * <ul> 00596 * <li>@link jvm/src/jlObject.c jvm/src/jlObject.c@endlink 00597 * </li> 00598 * <li>@link jvm/src/jlClass.c jvm/src/jlClass.c@endlink 00599 * </li> 00600 * <li>@link jvm/src/jlString.c jvm/src/jlString.c@endlink 00601 * </li> 00602 * <li>@link jvm/src/jlThread.c jvm/src/jlThread.c@endlink 00603 * </li> 00604 * </ul> 00605 * </li> 00606 * 00607 * <li> 00608 * Headers for JVM core implementation code of "local native methods", 00609 * including native method ordinals used by tables in 00610 * @link jvm/src/native.c native.c@endlink: 00611 * 00612 * <ul> 00613 * <li>@link jvm/include/jlObject.h 00614 jvm/include/jlObject.h@endlink 00615 * </li> 00616 * <li>@link jvm/include/jlClass.h 00617 jvm/include/jlClass.h@endlink 00618 * </li> 00619 * <li>@link jvm/include/jlString.h 00620 jvm/include/jlString.h@endlink 00621 * </li> 00622 * <li>@link jvm/include/jlThread.h 00623 jvm/include/jlThread.h@endlink 00624 * </li> 00625 * </ul> 00626 * </li> 00627 * 00628 * <li> 00629 * JVM connection to JNI and implementation and coordination of 00630 * support for "local native methods": 00631 * 00632 * <ul> 00633 * <li>@link jvm/src/native.c jvm/src/native.c@endlink 00634 * </li> 00635 * <li>@link jvm/src/native.h jvm/src/native.h@endlink 00636 * </li> 00637 * </ul> 00638 * </li> 00639 * </ul> 00640 * 00641 * The JVM specification is available from Sun Microsystems' web site 00642 * at http://java.sun.com/docs/books/vmspec/index.html and 00643 * may be read online at 00644 http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html 00645 * 00646 * The Java 5 class file format is available as a PDF file separately at 00647 http://java.sun.com/docs/books/vmspec/2nd-edition/ClassFileFormat-final-draft.pdf 00648 * and was the basis for the ClassFile structure of this implementation. 00649 * 00650 * 00651 * @attention For those who want to get started immediately and 00652 * without benefit of seeing the overall structure 00653 * of the system, please at least take a look at the 00654 * @link ./INSTALL INSTALL@endlink file at the top of 00655 * the installation tree. Between this file and the 00656 * @link ./README README@endlink file, a quick startup 00657 * is possible. 00658 * 00659 * @todo An enhanced startup narrative on the main page might be useful. 00660 * 00661 * @attention There are @e many to-do items in the 00662 * @link ./README README@endlink file at the top of 00663 * the installation tree. These items has been 00664 * specifically reserved for the project team to 00665 * work on in order to gain experience with this 00666 * code and provide a forum for JVM architectural 00667 * discussions as well as to implement in their own 00668 * right as a part of a working JVM. 00669 * 00670 * 00671 * @todo Section 2.6.6, value set conversions of floating point 00672 * numbers are not implemented. See note in table in this 00673 * section. Likewise for section 2.18, FP-strict expressions, 00674 * and section 3.8, floating point arithmetic. 00675 * 00676 * @attention The virtual execution engine is still under development 00677 * as this initial contribution is being made. While the 00678 * project team is working on learning what is inside the 00679 * code, this final module will be completed. The relevant 00680 * code is found in @link #opcode_run() opcode_run@endlink 00681 * in source file @link jvm/src/opcode.c opcode.c@endlink 00682 * 00683 * @todo The virtual execution engine is still under development 00684 * as this initial contribution is being made. While the 00685 * project team is working on learning what is inside the 00686 * code, this final module will be completed. The relevant 00687 * code is found in @link #opcode_run() opcode_run@endlink 00688 * in source file @link jvm/src/opcode.c opcode.c@endlink 00689 * 00690 * @bug The virtual execution engine is still under development 00691 * as this initial contribution is being made. While the 00692 * project team is working on learning what is inside the 00693 * code, this final module will be completed. The relevant 00694 * code is found in @link #opcode_run() opcode_run@endlink 00695 * in source file @link jvm/src/opcode.c opcode.c@endlink 00696 * 00697 */ 00698 00699 #include "arch.h" 00700 ARCH_COPYRIGHT_APACHE(jvm, c, "$URL: https://svn.apache.org/path/name/jvm.c $ $Id: jvm.c 0 09/28/2005 dlydick $"); 00701 00702 00703 #include <signal.h> 00704 #include <strings.h> 00705 #include <unistd.h> 00706 00707 #include "jvmcfg.h" 00708 #include "cfmacros.h" 00709 #include "classfile.h" 00710 #include "classpath.h" 00711 #include "exit.h" 00712 #include "gc.h" 00713 #include "jvm.h" 00714 #include "jvmclass.h" 00715 #include "linkage.h" 00716 #include "method.h" 00717 #include "nts.h" 00718 #include "opcode.h" 00719 #include "utf.h" 00720 #include "util.h" 00721 00722 00723 /*! 00724 * @brief JVM main operational structure. 00725 * 00726 * This pointer is initialized by jvm_model_init() and is 00727 * used @e extensivel throughout the code, both directly 00728 * and through macros like @link #CLASS() CLASS@endlink and 00729 * @link #OBJECT() OBJECT()@endlink. 00730 * 00731 */ 00732 rjvm *pjvm = CHEAT_AND_USE_NULL_TO_INITIALIZE; 00733 00734 00735 /*! 00736 * @name Roll call globals for JVM initialization and shutdown. 00737 * 00738 * @brief Determine if a portion of the JVM has been initialized or not. 00739 * 00740 * At the very end of initializing a part of the JVM, if everything 00741 * was set up properly, then the associated flag is set to 00742 * @link #rtrue rtrue@endlink. If an error occurs such that 00743 * jvm_shutdown() is initiated via exit_init(), then only those 00744 * components that were fully and properly initialized will be 00745 * cleaned up. This helps to avoid unnecessary checks for null pointers 00746 * and invalid data values in uninitialized memory areas. 00747 * 00748 */ 00749 00750 /*@{ */ /* Begin grouped definitions */ 00751 00752 rboolean jvm_timeslice_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00753 rboolean jvm_class_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00754 rboolean jvm_object_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00755 rboolean jvm_thread_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00756 rboolean jvm_argv_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00757 rboolean jvm_classpath_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00758 rboolean jvm_tmparea_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00759 rboolean jvm_model_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00760 rboolean jvm_heap_initialized = CHEAT_AND_USE_FALSE_TO_INITIALIZE; 00761 00762 /*@} */ /* End of grouped definitions */ 00763 00764 00765 /*! 00766 * @brief Initialize JVM internal structures. 00767 * 00768 * Wipe structure, set to all zeroes. Certain of the @b xxx_init() 00769 * functions depend on a zeroed structure at initialization time. 00770 * Once cleared, store off command line parameters from main() 00771 * as passed into jvm_init(). 00772 * 00773 * Must run HEAP_INIT() before calling this function. 00774 * 00775 * DO NOT use sysDbgMsg() here as message level cannot be set 00776 * until pjvm is initialized. 00777 * 00778 * 00779 * @b Parameters: @link #rvoid rvoid@endlink 00780 * 00781 * 00782 * @returns @link #rvoid rvoid@endlink 00783 * 00784 */ 00785 rvoid jvm_model_init() 00786 { 00787 /* 00788 * Allocate AND INITIALIZE TO ZERO the main JVM storage area. 00789 * When allocated, the pointer gets stored in the global 00790 * area pjvm. This will be used @e everywhere in the code. 00791 */ 00792 pjvm = HEAP_GET_DATA(sizeof(rjvm), rtrue); 00793 00794 /* Declare this module initialized */ 00795 jvm_model_initialized = rtrue; 00796 00797 return; 00798 } /* END of jvm_model_init() */ 00799 00800 00801 /*! 00802 * @brief Shut down the JVM model after JVM execution is finished. 00803 * 00804 * 00805 * @b Parameters: @link #rvoid rvoid@endlink 00806 * 00807 * 00808 * @returns @link #rvoid rvoid@endlink 00809 * 00810 */ 00811 rvoid jvm_model_shutdown() 00812 { 00813 HEAP_FREE_DATA(pjvm); 00814 00815 pjvm = (rjvm *) rnull; 00816 00817 /* Declare this module uninitialized */ 00818 jvm_model_initialized = rfalse; 00819 00820 return; 00821 00822 } /* END of jvm_model_shutdown() */ 00823 00824 00825 /*! 00826 * @def MANUAL_THREAD_STARTUP() 00827 * 00828 * @brief Bring a thread up from the @b NEW condition all 00829 * the way to @b RUNNING. 00830 * 00831 * The JVM thread state machine normally takes @b NEW threads 00832 * and moves them along through the states as requested by 00833 * Java code, in particular methods in @c @b java.lang.Thread . 00834 * However, when starting up the JVM, methods like @c @b <clinit> and 00835 * @c @b <init> are run from within the initialization. As such, 00836 * there must be a mechanism to drive the thread machine into the 00837 * @b RUNNING state for these special methods. This macro implements 00838 * such a requirement and is used in several places in 00839 * @link #jvm_manual_thread_run() jvm_manual_thread_run()@endlink and 00840 * @link #jvm_init() jvm_init()@endlink. 00841 * 00842 * Notice that all functions run if predecessor returns 00843 * @link #rtrue rtrue@endlink. Notice also that 00844 * threadstate_request_runnable() is a part 00845 * of the processing of threadstate_process_start() and 00846 * so is not needed here. 00847 * 00848 * 00849 * @param thridx Thread table index of thread containing code to run. 00850 * 00851 * 00852 * @returns @link #rtrue rtrue@endlink when startup proceeded all 00853 * the way from the @b NEW state through to @b RUNNING, 00854 * @link #rfalse rfalse@endlink otherwise. 00855 * 00856 */ 00857 #define MANUAL_THREAD_STARTUP(thridx) \ 00858 ((rtrue == threadstate_request_start(thridx)) && \ 00859 (rtrue == threadstate_activate_start(thridx)) && \ 00860 (rtrue == threadstate_process_start(thridx)) && \ 00861 (rtrue == threadstate_activate_runnable(thridx)) && \ 00862 (rtrue == threadstate_process_runnable(thridx)) && \ 00863 (rtrue == threadstate_request_running(thridx)) && \ 00864 (rtrue == threadstate_activate_running(thridx))) 00865 00866 00867 00868 /*! 00869 * @def MANUAL_THREAD_SHUTDOWN() 00870 * 00871 * @brief Bring a thread down from the @B RUNNING state all the 00872 * way through @B DEAD to an empty thread table slot. 00873 * 00874 * See rationale above for 00875 * @link #MANUAL_THREAD_STARTUP MANUAL_THREAD_STARTUP@endlink. 00876 * Notice that all functions run if predecessor returns 00877 * @link #rtrue rtrue@endlink. Notice also that 00878 * threadstate_request_dead() is a part of the processing of 00879 * threadstate_process_complete() and so is not needed here. 00880 * 00881 * 00882 * 00883 * @param thridx Thread table index of thread to be killed. 00884 * 00885 * 00886 * @returns @link #rtrue rtrue@endlink when shutdown proceeded all 00887 * the way from the @b RUNNING state through to an empty slot, 00888 * @link #rfalse rfalse@endlink otherwise. 00889 * 00890 */ 00891 #define MANUAL_THREAD_SHUTDOWN(thridx) \ 00892 ((rtrue == threadstate_request_complete(thridx)) && \ 00893 (rtrue == threadstate_activate_complete(thridx)) && \ 00894 (rtrue == threadstate_process_complete(thridx)) && \ 00895 (rtrue == threadstate_activate_dead(thridx)) && \ 00896 (rtrue == thread_die(thridx))) 00897 00898 00899 00900 /*! 00901 * @brief Manually start a thread in the JVM execution engine, but 00902 * outside of the normal runtime loop. 00903 * 00904 * This is used typically by initialization of the main JVM engine. 00905 * All parameters except thridx are for the purpose of reporting 00906 * errors. The thread must have its code loaded and ready to run, 00907 * and must be in the @b NEW state. It will be moved into the 00908 * @b RUNNING state, allowed to run to completion, and then 00909 * optionally taken through the @b COMPLETE state into @b DEAD, 00910 * shut down, and the thread terminated. 00911 * 00912 * The thread is typically set up via thread_class_load() in 00913 * preparation to call this function. 00914 * 00915 * 00916 * @param thridx Thread index of thread containing an executable 00917 * Java program. 00918 * 00919 * @param shutdown @link #rtrue rtrue@endlink if thread should be 00920 * shut down after it finishes running, otherwise 00921 * @link #rfalse rfalse@endlink. 00922 * 00923 * @param clsname Null-terminated string of name of class 00924 * 00925 * @param mthname Null-terminated string of method to run in class 00926 * 00927 * @param mthdesc Null-terminated string of method signature 00928 * 00929 * 00930 * @returns @link #rvoid rvoid@endlink 00931 * 00932 */ 00933 rvoid jvm_manual_thread_run(jvm_thread_index thridx, 00934 rboolean shutdown, 00935 rchar *clsname, 00936 rchar *mthname, 00937 rchar *mthdesc) 00938 { 00939 /* 00940 * If thread is not @b RUNNING, then it must @b NEW. 00941 * Move it to @b RUNNING so that Java byte codes may 00942 * be run. 00943 */ 00944 if (THREAD_STATE_RUNNING != THIS_STATE(thridx)) 00945 { 00946 if (MANUAL_THREAD_STARTUP(thridx)) 00947 { 00948 /* Used in place of threadstat_activate_running(): */ 00949 /* (Extracted from STATE_DEFINITION() macro) */ 00950 if (THREAD_STATE_RUNNING == NEXT_STATE(thridx)) 00951 { 00952 PREV_STATE(thridx) = THIS_STATE(thridx); 00953 THIS_STATE(thridx) = NEXT_STATE(thridx); 00954 } 00955 } 00956 else 00957 { 00958 /* Something went wrong starting method, so quit */ 00959 sysErrMsg("jvm_manual_thread_run", 00960 "Cannot manually start %s %s%s", 00961 clsname, 00962 mthname, 00963 mthdesc); 00964 exit_jvm(EXIT_JVM_THREAD); 00965 /*NOTREACHED*/ 00966 } 00967 } 00968 00969 /* 00970 * The above step should have thread @b RUNNING now. 00971 * 00972 * Therefore, this is not necessary: 00973 * 00974 * if (THREAD_STATE_RUNNING == THIS_STATE(thridx))... 00975 */ 00976 00977 if (rfalse == opcode_run(thridx, rfalse)) 00978 { 00979 /* Problem running method, so quit */ 00980 sysErrMsg("jvm_manual_thread_run", 00981 "Cannot manually start %s %s%s", 00982 clsname, 00983 mthname, 00984 mthdesc); 00985 exit_jvm(EXIT_JVM_THREAD); 00986 /*NOTREACHED*/ 00987 } 00988 00989 /* 00990 * Leave thread in RUNNING state or take it to thread_die(), 00991 * that is, through COMPLETE, through DEAD, to deallocation 00992 */ 00993 if (rfalse == shutdown) 00994 { 00995 return; /* Leave it in RUNNING state */ 00996 } 00997 00998 /* Shut it down */ 00999 if (MANUAL_THREAD_SHUTDOWN(thridx)) 01000 { 01001 ; /* Everything stopped correctly */ 01002 } 01003 else 01004 { 01005 /* Problem stopping method, so quit */ 01006 sysErrMsg("jvm_manual_thread_run", 01007 "Cannot stop manually stop %s %s%s", 01008 clsname, 01009 mthname, 01010 mthdesc); 01011 exit_jvm(EXIT_JVM_THREAD); 01012 /*NOTREACHED*/ 01013 } 01014 01015 } /* END of jvm_manual_thread_run() */ 01016 01017 01018 /*! 01019 * @def STATE_MODEL_SWITCH() 01020 * 01021 * @brief State model switch statement macro, less the default case. 01022 * 01023 * This macro is used in @link #jvm_run() jvm_run()@endlink to 01024 * implement all three phases of the JVM thread state model for 01025 * requesting, activating, and processing a thread state. 01026 * The three phases, @b REQUEST, @b ACTIVATE, and @b PROCESS, 01027 * are instantiated by passing different parameters to the macro. 01028 * 01029 * @param somestate_rc Name of return code variable from @b casebody 01030 * 01031 * @param casebody Macro name of code to process as the body of 01032 * each case, not including @c @b break 01033 * statement. 01034 * 01035 * 01036 * @returns Each @b casebody returns @link #rtrue rtrue@endlink or 01037 * @link #rfalse rfalse@endlink to @b somestate_rc, 01038 * which is passed out of the switch() statement. 01039 * 01040 * The final case @e does include a @c @b break statement for 01041 * completeness, even though each invocation of this macro is also 01042 * followed by a @c @b break statement in its @c @b switch(). 01043 * 01044 */ 01045 #define STATE_MODEL_SWITCH(somestate_rc, casebody) \ 01046 case THREAD_STATE_NEW: somestate_rc = casebody(new); break; \ 01047 case THREAD_STATE_START: somestate_rc = casebody(start); break; \ 01048 case THREAD_STATE_RUNNABLE:somestate_rc = casebody(runnable);break;\ 01049 case THREAD_STATE_RUNNING: somestate_rc = casebody(running); break;\ 01050 case THREAD_STATE_COMPLETE:somestate_rc = casebody(complete);break;\ 01051 case THREAD_STATE_BLOCKINGEVENT: \ 01052 somestate_rc = casebody(blockingevent); \ 01053 break; \ 01054 case THREAD_STATE_BLOCKED: somestate_rc = casebody(blocked); break;\ 01055 case THREAD_STATE_UNBLOCKED:somestate_rc=casebody(unblocked);break;\ 01056 case THREAD_STATE_SYNCHRONIZED: \ 01057 somestate_rc = casebody(synchronized); \ 01058 break; \ 01059 case THREAD_STATE_RELEASE: somestate_rc = casebody(release); break;\ 01060 case THREAD_STATE_WAIT: somestate_rc = casebody(wait); break; \ 01061 case THREAD_STATE_NOTIFY: somestate_rc = casebody(notify); break; \ 01062 case THREAD_STATE_LOCK: somestate_rc = casebody(lock); break; \ 01063 case THREAD_STATE_ACQUIRE: somestate_rc = casebody(acquire); break;\ 01064 case THREAD_STATE_DEAD: somestate_rc = casebody(dead); break; \ 01065 case THREAD_STATE_BADLOGIC:somestate_rc = casebody(badlogic); break; 01066 01067 01068 /*! 01069 * @brief Initialize the Java Virtual Machine. 01070 * 01071 * Set up the pieces necessary to start the JVM running, then 01072 * load up @c @b java.lang.Object and the basic classes 01073 * that it references, all in the class table. These include: 01074 * 01075 * @verbatim 01076 01077 java.lang.Object 01078 <pseudo-class> (byte) 01079 <pseudo-class> (character) 01080 <pseudo-class> (double) 01081 <pseudo-class> (float) 01082 <pseudo-class> (int) 01083 <pseudo-class> (long) 01084 <pseudo-class> (short) 01085 <pseudo-class> (boolean) 01086 java.lang.Class 01087 java.lang.String 01088 java.lang.Thread 01089 <startup class from command line> 01090 01091 @endverbatim 01092 * 01093 * All of these will have their @c @b <clinit> class initialization 01094 * methods invoked, if any. The following objects will be created 01095 * (where @c @b pjvm->argcj is the number of command line 01096 * arguments passed into the program which get passed through to 01097 * the JVM main() method): 01098 * 01099 * <ul> 01100 * <li> 1 instance of @c @b java.lang.String[] with a size 01101 * of @c @b pjvm->argcj array elements, plus one 01102 * @c @b java.lang.Object superclass object. 01103 * </li> 01104 * 01105 * <li> @c @b pjvm->argc instances of 01106 * @c @b java.lang.String plus one 01107 * @c @b java.lang.Object superclass 01108 * object per String instance. 01109 * </li> 01110 * </ul> 01111 * 01112 * 01113 * @param argc Number of entries in @c @b argv[] 01114 * (per @c @b main() entry) 01115 * @param argv Command line parameters from main() 01116 * @param envp Environment pointer from main() 01117 * 01118 * @returns @link #rvoid rvoid@endlink 01119 * 01120 * 01121 */ 01122 01123 static rvoid jvm_init(int argc, char **argv, char **envp) 01124 { 01125 /* Clear all initialization roll call globals */ 01126 jvm_timeslice_initialized = rfalse; 01127 jvm_class_initialized = rfalse; 01128 jvm_object_initialized = rfalse; 01129 jvm_thread_initialized = rfalse; 01130 jvm_argv_initialized = rfalse; 01131 jvm_classpath_initialized = rfalse; 01132 jvm_tmparea_initialized = rfalse; 01133 jvm_model_initialized = rfalse; 01134 jvm_heap_initialized = rfalse; 01135 01136 /********** Arm java.lang.LinkageError handler ***/ 01137 01138 int nonlocal_rc = exit_exception_setup(); 01139 01140 if (EXIT_MAIN_OKAY == nonlocal_rc) 01141 { 01142 opcode_calling_java_lang_linkageerror = rfalse; 01143 } 01144 else 01145 { 01146 /* 01147 * Should always be false after exit_throw_exception() 01148 * unless someone called it with a null pointer 01149 */ 01150 if (rnull == exit_LinkageError_subclass) 01151 { 01152 exit_LinkageError_subclass = "unknown"; 01153 } 01154 01155 fprintfLocalStderr("jvm_init: Error %d (%s): %s\n", 01156 nonlocal_rc, 01157 exit_get_name(nonlocal_rc), 01158 exit_LinkageError_subclass); 01159 01160 exit_jvm(nonlocal_rc); 01161 } 01162 01163 01164 /********** Initialize heap management ***********/ 01165 01166 HEAP_INIT(); 01167 01168 01169 /********** Initialize entire JVM area ***********/ 01170 01171 jvm_model_init(argc, argv, envp); 01172 01173 /********** Initialize message verbosity *********/ 01174 01175 jvmutil_set_dml(DMLDEFAULT); 01176 01177 /********** Initialize temp area *****************/ 01178 01179 tmparea_init(argv); 01180 01181 01182 /********** Parse command line, environment,etc. */ 01183 01184 argv_init(argc, argv, envp); 01185 01186 01187 /********** Initialize the @b CLASSPATH **********/ 01188 01189 classpath_init(); 01190 01191 01192 /********** Initialize the thread area ***********/ 01193 01194 thread_init(); 01195 01196 01197 /********** Initialize the object area ***********/ 01198 01199 /* Need this first because class_init() allocates object slots */ 01200 object_init(); 01201 01202 01203 /********** Initialize the class area ************/ 01204 01205 class_init(); 01206 01207 01208 /********** Initialize the time slice area *******/ 01209 01210 timeslice_init(); 01211 01212 01213 /********** Load java.lang.Object ****************/ 01214 01215 jvm_class_index clsidx; 01216 01217 clsidx = class_load_from_prchar( 01218 JVMCLASS_JAVA_LANG_OBJECT, 01219 rtrue, /* The startup classes have local bindings */ 01220 (jint *) rnull); 01221 01222 01223 /********** Load primatives of all types *********/ 01224 01225 /* Loaded on system thread */ 01226 if((jvm_class_index_null == class_load_primative(BASETYPE_CHAR_B))|| 01227 (jvm_class_index_null == class_load_primative(BASETYPE_CHAR_C))|| 01228 (jvm_class_index_null == class_load_primative(BASETYPE_CHAR_D))|| 01229 (jvm_class_index_null == class_load_primative(BASETYPE_CHAR_F))|| 01230 (jvm_class_index_null == class_load_primative(BASETYPE_CHAR_I))|| 01231 (jvm_class_index_null == class_load_primative(BASETYPE_CHAR_J))|| 01232 (jvm_class_index_null == class_load_primative(BASETYPE_CHAR_S))|| 01233 (jvm_class_index_null == class_load_primative(BASETYPE_CHAR_Z))) 01234 { 01235 sysErrMsg("jvm_init", 01236 "Cannot load primative classes for java.lang.Class"); 01237 exit_jvm(EXIT_JVM_CLASS); 01238 /*NOTREACHED*/ 01239 } 01240 01241 01242 /********** Load java.lang.Class *****************/ 01243 01244 clsidx = class_load_from_prchar( 01245 JVMCLASS_JAVA_LANG_CLASS, 01246 rtrue, 01247 (jint *) rnull); 01248 01249 01250 /********** Load java.lang.String ****************/ 01251 01252 clsidx = class_load_from_prchar( 01253 JVMCLASS_JAVA_LANG_STRING, 01254 rtrue, 01255 (jint *) rnull); 01256 01257 01258 /********** Resolve and @c @b <clinit> all classes *****/ 01259 01260 /* 01261 * Loading has been performed, but not resolve or run the 01262 * JVM manually to process the @c @b <clinit> method, so go ahead 01263 * and invoke using the normal multi-stage entry point here. 01264 * It is designed to only process those stages that remain 01265 * unprocessed from earlier activity. 01266 */ 01267 jvm_class_index clsidxOBJECT = 01268 class_load_resolve_clinit(JVMCLASS_JAVA_LANG_OBJECT, 01269 jvm_thread_index_null, 01270 rtrue, 01271 rtrue); 01272 cfmsgs_show_constant_pool(CLASS_OBJECT_LINKAGE(clsidxOBJECT)->pcfs); 01273 01274 jvm_class_index clsidxCLASS = 01275 class_load_resolve_clinit(JVMCLASS_JAVA_LANG_CLASS, 01276 jvm_thread_index_null, 01277 rtrue, 01278 rtrue); 01279 cfmsgs_show_constant_pool(CLASS_OBJECT_LINKAGE(clsidxCLASS)->pcfs); 01280 01281 jvm_class_index clsidxSTRING = 01282 class_load_resolve_clinit(JVMCLASS_JAVA_LANG_STRING, 01283 jvm_thread_index_null, 01284 rtrue, 01285 rtrue); 01286 cfmsgs_show_constant_pool(CLASS_OBJECT_LINKAGE(clsidxSTRING)->pcfs); 01287 01288 01289 /********** Load java.lang.String[] (1 dim array) */ 01290 01291 jint *string1 = HEAP_GET_DATA( 1 * sizeof(jint), rfalse); 01292 01293 string1[0] = pjvm->argcj; /* Number of java command line parms */ 01294 01295 cp_info_dup *pcpclsname = 01296 nts_prchar2utf_classname(JVMCLASS_JAVA_LANG_STRING, 1); 01297 01298 rchar *pclsname = utf_utf2prchar(PTR_THIS_CP_Utf8(pcpclsname)); 01299 01300 clsidx = class_load_from_prchar(pclsname, 01301 rtrue, 01302 string1); 01303 01304 HEAP_FREE_DATA(pcpclsname); 01305 01306 HEAP_FREE_DATA(pclsname); 01307 01308 /********** Load misc java.lang.* for runtime ******/ 01309 /* (with manual linkage error checking) */ 01310 01311 (rvoid) class_load_resolve_clinit( 01312 JVMCLASS_JAVA_LANG_STACKTRACEELEMENT, 01313 jvm_thread_index_null, 01314 rtrue, 01315 rfalse); 01316 01317 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_THROWABLE, 01318 jvm_thread_index_null, 01319 rtrue, 01320 rfalse); 01321 01322 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_ERROR, 01323 jvm_thread_index_null, 01324 rtrue, 01325 rfalse); 01326 01327 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_LINKAGEERROR, 01328 jvm_thread_index_null, 01329 rtrue, 01330 rfalse); 01331 01332 01333 /******* Re-arm java.lang.LinkageError handler ***/ 01334 01335 nonlocal_rc = exit_exception_setup(); 01336 01337 if (EXIT_MAIN_OKAY == nonlocal_rc) 01338 { 01339 opcode_calling_java_lang_linkageerror = rfalse; 01340 } 01341 else 01342 { 01343 /* 01344 * This handler invokes opcode_load_run_throwable(), 01345 * so exit_exception_setup() @e must be rearmed 01346 * @e again when it enters that function!!! 01347 */ 01348 01349 /* Should always be true via exit_throw_exception() */ 01350 if (rnull == exit_LinkageError_subclass) 01351 { 01352 exit_LinkageError_subclass = "unknown"; 01353 } 01354 01355 fprintfLocalStderr("jvm_init: Error %d (%s): %s\n", 01356 nonlocal_rc, 01357 exit_get_name(nonlocal_rc), 01358 exit_LinkageError_subclass); 01359 01360 opcode_load_run_throwable(exit_LinkageError_subclass, 01361 exit_LinkageError_thridx); 01362 01363 exit_jvm(nonlocal_rc); 01364 } 01365 01366 01367 /********** Load misc java.lang.* for runtime ******/ 01368 /* (with NORMAL linkage error checking) */ 01369 01370 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_EXCEPTION, 01371 jvm_thread_index_null, 01372 rtrue, 01373 rfalse); 01374 01375 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_SYSTEM, 01376 jvm_thread_index_null, 01377 rtrue, 01378 rfalse); 01379 01380 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_RUNTIME, 01381 jvm_thread_index_null, 01382 rtrue, 01383 rfalse); 01384 01385 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_THREADGROUP, 01386 jvm_thread_index_null, 01387 rtrue, 01388 rfalse); 01389 01390 /********** Load java.lang.Thread ****************/ 01391 01392 (rvoid) class_load_resolve_clinit(JVMCLASS_JAVA_LANG_THREAD, 01393 jvm_thread_index_null, 01394 rtrue, 01395 rtrue); 01396 01397 01398 /********** Load startup class @c @b <clinit> **********/ 01399 01400 rchar *startup = (rnull != pjvm->startjar) 01401 ? pjvm->startjar 01402 : pjvm->startclass; 01403 01404 /* Chk missing entry point */ 01405 if (rnull == startup) 01406 { 01407 sysErrMsg("jvm_init", "Missing startup class name"); 01408 exit_jvm(EXIT_JVM_CLASS); 01409 /*NOTREACHED*/ 01410 } 01411 01412 /* 01413 * Keep JAR file as-is, but convert regular class definition to 01414 * internal form. Why? So all references in the JVM are to 01415 * internal form, not just those coming from class files. 01416 * 01417 * Do @e not modify @b startup in place since it may come ultimately 01418 * from the @c @b argv[] list (Translation: "Be nice to 01419 * the runtime environment!") 01420 */ 01421 if (rnull == pjvm->startjar) 01422 { 01423 startup = classpath_external2internal_classname(startup); 01424 } 01425 01426 jvm_class_index clsidxSTARTUP = 01427 class_load_resolve_clinit(startup, 01428 jvm_thread_index_null, 01429 rtrue, 01430 rfalse); 01431 01432 if (jvm_class_index_null == clsidxSTARTUP) 01433 { 01434 sysErrMsg("jvm_init", "Cannot load class %s", startup); 01435 exit_jvm(EXIT_JVM_CLASS); 01436 /*NOTREACHED*/ 01437 } 01438 01439 01440 /********** Load java.lang.String[] args data *****/ 01441 01442 clsidx = class_find_by_prchar(JVMCLASS_JAVA_LANG_STRING); 01443 01444 jint *pjargc = HEAP_GET_DATA(1 * sizeof(jint), rfalse); 01445 01446 pjargc[0] = pjvm->argcj; 01447 01448 jvm_object_hash objhashjargs = 01449 object_instance_new(OBJECT_STATUS_ARRAY, 01450 CLASS_OBJECT_LINKAGE(clsidx)->pcfs, 01451 clsidx, 01452 1, 01453 pjargc, 01454 rfalse, 01455 jvm_thread_index_null); 01456 01457 /* 01458 * Explicitly cast the untyped 01459 * @link robject#arraydata arraydata@endlink 01460 * member for object hash 01461 */ 01462 jvm_object_hash *pjargv = 01463 (jvm_object_hash *) OBJECT(objhashjargs).arraydata; 01464 01465 01466 if (0 < pjvm->argcj) 01467 { 01468 rint pcharlen; 01469 01470 rint i; 01471 for (i = 0; i < pjvm->argcj; i++) 01472 { 01473 pcharlen = strlen(pjvm->argv[i]); 01474 01475 /*! 01476 * @todo Create a @c @b java.lang.String as 01477 * <b><code>java.lang.String(byte[], int, int)</code></b> 01478 * where the call is made, as it were, to 01479 * <b><code> 01480 java.lang.String.<init>(pjvm->argv[i], 01481 0, 01482 strlen(pjvm->argv[i])); 01483 </code></b> 01484 * 01485 * The following @link #jvm_object_hash_null 01486 * jvm_object_hash_null@endlink will get replaced 01487 * by the actual object hash from this operation. 01488 * What really needs to happen is a function should 01489 * be written that pushes these arguments onto the 01490 * JVM stack for this thread and then loads this 01491 * constructor and runs it in a manner similar to 01492 * how jvm_manual_thread_run() does it. In fact, 01493 * this function might be @e exactly what is 01494 * needed for this purpose. Simply add some 01495 * parameters that represent the first and third 01496 * parameters to the @c @b java.lang.String.<init> 01497 * method and build up a stack frame accordingly. 01498 * 01499 * @note This same requirement may be found in 01500 * @link #class_get_constant_field_attribute() 01501 * class_get_constant_field_attribute()@endlink 01502 * where CONSTANT_String_info needs to get loaded 01503 * from the class file into an object. 01504 * 01505 */ 01506 pjargv[i] = jvm_object_hash_null; 01507 01508 /* Uncomment for error checking when ready... 01509 if (jvm_object_hash_null == pjargv[i]) 01510 { 01511 sysErrMsg("jvm_init", 01512 "Cannot allocate String[] objects"); 01513 exit_jvm(EXIT_JVM_OBJECT); 01514 **NOTREACHED** ... RE-comment at this same time! 01515 } 01516 */ 01517 (rvoid) GC_OBJECT_MKREF_FROM_OBJECT(jvm_object_hash_null, 01518 pjargv[i]); 01519 } 01520 } 01521 01522 /********** POP_FRAME()/-mod PC-/PUSH_FRAME() ****/ 01523 01524 /*! @todo POP_FRAME() and do new PUSH_FRAME() with startup class PC 01525 * (Do <b><code>new Thread()</code></b> and hack the PC with startup 01526 * class @c @b main() entry.) 01527 */ 01528 01529 01530 /********** Load startup class main() ************/ 01531 01532 /* Loaded on arbitrary user thread, but NOT on system thread */ 01533 01534 if (jvm_method_index_bad == 01535 method_find_by_prchar(clsidxSTARTUP, 01536 JVMCFG_MAIN_METHOD, 01537 JVMCFG_MAIN_PARMS)) 01538 { 01539 sysErrMsg("jvm_init", 01540 "Cannot load main method %s %s%s", 01541 startup, 01542 JVMCFG_MAIN_METHOD, 01543 JVMCFG_MAIN_PARMS); 01544 exit_jvm(EXIT_JVM_METHOD); 01545 /*NOTREACHED*/ 01546 } 01547 01548 /* 01549 * Mark startup class as having a reference, namely, 01550 * the reference from the command line invocation. 01551 * This way it cannot get marked for garbage collection. 01552 */ 01553 (rvoid) GC_CLASS_MKREF_FROM_CLASS(jvm_class_index_null, 01554 clsidxSTARTUP); 01555 01556 jvm_thread_index thridx = thread_class_load(startup, 01557 JVMCFG_MAIN_METHOD, 01558 JVMCFG_MAIN_PARMS, 01559 THREAD_PRIORITY_NORM, 01560 rfalse, 01561 rfalse, 01562 rfalse); 01563 01564 /********** Insert (String[] args) for main() ****/ 01565 01566 PUT_LOCAL_VAR(thridx, JVMCFG_MAIN_PARM_ARGV_INDEX, objhashjargs); 01567 01568 01569 /********** Request startup of main() ************/ 01570 01571 if (MANUAL_THREAD_STARTUP(thridx)) 01572 { 01573 ; /* Nothing to do except go run main() in main JVM loop */ 01574 } 01575 else 01576 { 01577 /* Something went wrong, so quit */ 01578 sysErrMsg("jvm_init", 01579 "Cannot start %s %s%s", 01580 startup, 01581 JVMCFG_MAIN_METHOD, 01582 JVMCFG_MAIN_PARMS); 01583 exit_jvm(EXIT_JVM_THREAD); 01584 /*NOTREACHED*/ 01585 } 01586 01587 if (rnull == pjvm->startjar) 01588 { 01589 HEAP_FREE_DATA(startup); 01590 } 01591 01592 /********** main() is in the RUNNING state *******/ 01593 /********** and its PC is at 1st instruction... **/ 01594 01595 return; 01596 01597 } /* END of jvm_init() */ 01598 01599 01600 /*! 01601 * @brief Start up JVM execution engine and let Java program code 01602 * take over. 01603 * 01604 * At this point, the class containing main() has been loaded and its 01605 * class initialization has been performed. The program counter is 01606 * at the very first instruction of main() and the thread is in the 01607 * @b RUNNING state. 01608 * 01609 * 01610 * @b Parameters: @link #rvoid rvoid@endlink 01611 * 01612 * 01613 * @returns @link #rvoid rvoid@endlink 01614 * 01615 */ 01616 static rvoid jvm_run() 01617 { 01618 sysDbgMsg(DMLMIN, "jvm_run", "started"); 01619 01620 /* 01621 * Run the virtual machine as long as there are user threads, 01622 * that is, as long as the ISDAEMON bit is clear on at least 01623 * one thread table entry. 01624 */ 01625 rint no_user_threads = rtrue; 01626 while (rtrue == no_user_threads) 01627 { 01628 /* Tested once per whole pass: 01629 * thread1 ISDAEMON 01630 * AND thread 2 ISDAEMON 01631 * AND thread 3 ISDAEMON 01632 * AND ... 01633 * 01634 * If next while() iteration starts, at least ONE thread had 01635 * the ISDAEMON bit off, meaning there was at least one user 01636 * thread in the JVM, so keep running unto expression is 01637 * @link #rtrue rtrue@endlink. 01638 */ 01639 rint no_user_threads = rtrue; 01640 01641 /* JVMCFG_NULL_THREAD--not activated */ 01642 for (CURRENT_THREAD = JVMCFG_SYSTEM_THREAD; 01643 CURRENT_THREAD < JVMCFG_MAX_THREADS; 01644 CURRENT_THREAD++) 01645 { 01646 /* Check if this thread is alive */ 01647 if (!(THREAD_STATUS_INUSE & THREAD(CURRENT_THREAD).status)) 01648 { 01649 continue; 01650 } 01651 01652 switch(CURRENT_THREAD) 01653 { 01654 case CHEAT_AND_ALLOW_NULL_THREAD_INDEX: 01655 /* Never activated */ 01656 continue; 01657 01658 case JVMCFG_SYSTEM_THREAD: 01659 /* 01660 * Reserved for use by internal logic that 01661 * invokes thread_new_system() 01662 */ 01663 continue; 01664 01665 case JVMCFG_GC_THREAD: 01666 /* Default garbage collector is a native method */ 01667 GC_RUN(rtrue); 01668 continue; 01669 } 01670 01671 /* Check if any user threads are alive (loop test) */ 01672 if (!(THREAD_STATUS_ISDAEMON & 01673 THREAD(CURRENT_THREAD).status)) 01674 { 01675 no_user_threads = rfalse; 01676 } 01677 01678 /*! 01679 * @verbatim 01680 01681 State transition and processing table 01682 ===================================== 01683 01684 01685 STATE MODEL PHASE 1: VERIFY CHANGE 01686 Verify whether or not a requested state transition 01687 is valid. Return rtrue if valid, otherwise rfalse. 01688 01689 STATE MODEL PHASE 2: PERFORM CHANGE 01690 Perform known-valid requested state transition. 01691 Return rtrue if transition occurred, otherwise rfalse. 01692 01693 STATE MODEL PHASE 3: PROCESS STATE 01694 Perform activities in all states, as long as the 01695 state is valid. Return rtrue if processing occurred, 01696 otherwise rfalse. 01697 01698 This logic is the essence of what each of 01699 the pieces for each state in 01700 @link src/threadstate.c threadstate.c@endlink 01701 is all about. See further comments there. 01702 @endverbatim 01703 */ 01704 01705 /* STATE MODEL PHASE 1 (see definition above) */ 01706 rint nextstate_rc; 01707 01708 if (THIS_STATE(CURRENT_THREAD) != 01709 NEXT_STATE(CURRENT_THREAD)) 01710 { 01711 switch (NEXT_STATE(CURRENT_THREAD)) 01712 { 01713 STATE_MODEL_SWITCH(nextstate_rc, 01714 CURRENT_THREAD_REQUEST_NEXT_STATE); 01715 break; 01716 01717 default: 01718 /* Complain and go to BADLOGIC state forever */ 01719 sysErrMsg("jvm_run", 01720 "illegal next state %d this=%d prev=$d", 01721 NEXT_STATE(CURRENT_THREAD), 01722 THIS_STATE(CURRENT_THREAD), 01723 PREV_STATE(CURRENT_THREAD)); 01724 nextstate_rc = 01725 CURRENT_THREAD_REQUEST_NEXT_STATE(badlogic); 01726 break; 01727 01728 } /* switch (NEXT_STATE(CURRENT_THREAD)) */ 01729 01730 } /* if this_state != next_state */ 01731 01732 if (rfalse == nextstate_rc) 01733 { 01734 sysErrMsg("jvm_run", 01735 "Unable to move thread %d to '%s' state", 01736 CURRENT_THREAD, 01737 thread_state_get_name( 01738 NEXT_STATE(CURRENT_THREAD))); 01739 CURRENT_THREAD_REQUEST_NEXT_STATE(badlogic); 01740 } 01741 01742 01743 /* STATE MODEL PHASE 2 (see definition above) */ 01744 01745 if (THIS_STATE(CURRENT_THREAD) != 01746 NEXT_STATE(CURRENT_THREAD)) 01747 { 01748 switch (THIS_STATE(CURRENT_THREAD)) 01749 { 01750 STATE_MODEL_SWITCH(nextstate_rc, 01751 CURRENT_THREAD_ACTIVATE_THIS_STATE); 01752 break; 01753 01754 default: 01755 /* 01756 * Should @e never happen, the switch() default 01757 * above should have thrown this thread into 01758 * the BADLOGIC state. 01759 */ 01760 sysErrMsg("jvm_run", 01761 "illegal thread state %d", 01762 NEXT_STATE(CURRENT_THREAD)); 01763 exit_jvm(EXIT_JVM_THREAD); 01764 /*NOTREACHED*/ 01765 } 01766 01767 if (rfalse == nextstate_rc) 01768 { 01769 sysErrMsg("jvm_run", 01770 "Unable to activate thread %d in '%s' state", 01771 CURRENT_THREAD, 01772 thread_state_get_name( 01773 NEXT_STATE(CURRENT_THREAD))); 01774 01775 /* 01776 * This will cause a @c @b break in the 01777 * @c @b while() loop 01778 */ 01779 CURRENT_THREAD_REQUEST_NEXT_STATE(badlogic); 01780 } 01781 01782 } /* if this_state != next_state */ 01783 01784 /* 01785 * STATE MODEL PHASE 3 (see definition above) 01786 */ 01787 rint thisstate_rc; 01788 01789 if (THIS_STATE(CURRENT_THREAD) == 01790 NEXT_STATE(CURRENT_THREAD)) 01791 { 01792 switch (THIS_STATE(CURRENT_THREAD)) 01793 { 01794 STATE_MODEL_SWITCH(thisstate_rc, 01795 CURRENT_THREAD_PROCESS_THIS_STATE); 01796 break; 01797 01798 default: 01799 /* 01800 * Should @e never happen, the switch() default 01801 * above should have thrown this thread into 01802 * the BADLOGIC state. 01803 */ 01804 sysErrMsg("jvm_run", 01805 "illegal thread state %d", 01806 NEXT_STATE(CURRENT_THREAD)); 01807 exit_jvm(EXIT_JVM_THREAD); 01808 /*NOTREACHED*/ 01809 } 01810 01811 01812 if (rfalse == nextstate_rc) 01813 { 01814 sysErrMsg("jvm_run", 01815 "Unable to process thread %d to '%s' state", 01816 CURRENT_THREAD, 01817 thread_state_get_name( 01818 THIS_STATE(CURRENT_THREAD))); 01819 CURRENT_THREAD_REQUEST_NEXT_STATE(badlogic); 01820 } 01821 01822 } /* if this_state == next_state */ 01823 01824 } /* for current_thread */ 01825 01826 } /* while no_user_threads */ 01827 01828 sysDbgMsg(DMLMIN, "jvm_run", "finished"); 01829 01830 } /* END of jvm_run() */ 01831 01832 01833 /*! 01834 * @brief Shut down the Java Virtual Machine. 01835 * 01836 * Use a global for roll call of initialization 01837 * to determine whether each area has been set 01838 * up properly in case of abort during initialization. 01839 * 01840 * 01841 * @b Parameters: @link #rvoid rvoid@endlink 01842 * 01843 * 01844 * @returns @link #rvoid rvoid@endlink 01845 * 01846 */ 01847 01848 rvoid jvm_shutdown() 01849 { 01850 /* 01851 * Re-arm @c @b java.lang.LinkageError handler for 01852 * the final time. 01853 */ 01854 01855 int nonlocal_rc = exit_exception_setup(); 01856 01857 if (EXIT_MAIN_OKAY == nonlocal_rc) 01858 { 01859 opcode_calling_java_lang_linkageerror = rfalse; 01860 } 01861 else 01862 { 01863 /* 01864 * Should always be false after exit_throw_exception() 01865 * unless someone called it with a null pointer 01866 */ 01867 if (rnull == exit_LinkageError_subclass) 01868 { 01869 exit_LinkageError_subclass = "unknown"; 01870 } 01871 01872 fprintfLocalStderr("jvm_shutdown: Error %d (%s): %s\n", 01873 nonlocal_rc, 01874 exit_get_name(nonlocal_rc), 01875 exit_LinkageError_subclass); 01876 01877 return; /* Give up, don't run any error handlers */ 01878 } 01879 01880 01881 /* 01882 * Clean up thread stack areas, ClassFile storage, etc. 01883 * This process is effectively the reverse of jvm_init(). 01884 */ 01885 01886 if (rtrue == jvm_timeslice_initialized) 01887 { 01888 timeslice_shutdown(); 01889 } 01890 01891 if (rtrue == jvm_class_initialized) 01892 { 01893 class_shutdown_1(); 01894 } 01895 01896 if (rtrue == jvm_object_initialized) 01897 { 01898 object_shutdown(); 01899 } 01900 01901 if (rtrue == jvm_class_initialized) 01902 { 01903 class_shutdown_2(); 01904 } 01905 01906 if (rtrue == jvm_thread_initialized) 01907 { 01908 thread_shutdown(); 01909 } 01910 01911 if (rtrue == jvm_argv_initialized) 01912 { 01913 argv_shutdown(); 01914 } 01915 01916 if (rtrue == jvm_classpath_initialized) 01917 { 01918 classpath_shutdown(); 01919 } 01920 01921 if (rtrue == jvm_tmparea_initialized) 01922 { 01923 tmparea_shutdown(); 01924 } 01925 01926 if (rtrue == jvm_model_initialized) 01927 { 01928 jvm_model_shutdown(); 01929 } 01930 01931 if (rtrue == jvm_heap_initialized) 01932 { 01933 HEAP_SHUTDOWN(); 01934 } 01935 01936 return; 01937 01938 } /* END of jvm_shutdown() */ 01939 01940 01941 /*! 01942 * @brief Common signal handler to shut down JVM upon receipt of 01943 * common signals. 01944 * 01945 * 01946 * @param sig Signal number 01947 * 01948 * 01949 * @returns non-local return via exit_jvm() 01950 * 01951 */ 01952 rvoid jvm_signal(int sig) 01953 { 01954 sysErrMsg("jvm_signal", "received signal %d", sig); 01955 01956 exit_jvm(EXIT_JVM_SIGNAL); 01957 /*NOTREACHED*/ 01958 } /* END of jvm_signal() */ 01959 01960 01961 /*! 01962 * @brief Main entry point for this library implementing the 01963 * Java Virtural Machine. 01964 * 01965 * 01966 * @b Parameters: @link #rvoid rvoid@endlink 01967 * 01968 * 01969 * @returns @link #rvoid rvoid@endlink 01970 * 01971 */ 01972 01973 rint jvm(int argc, char **argv, char **envp) 01974 { 01975 int exit_rc; 01976 01977 /* 01978 * Protect JVM shutdown and heap free mechanism 01979 * with non-local error return. (When setting 01980 * it up, @link #exit_init() exit_init()@endlink returns @link 01981 #EXIT_MAIN_OKAY exit code enumeration EXIT_MAIN_OKAY@endlink, 01982 * but when invoking @link #exit_jvm() exit_jvm(EXIT_xxx)@endlink, 01983 * return code @link #EXIT_MAIN_OKAY EXIT_xxx@endlink is returned, 01984 * see @link src/exit.h exit.h@endlink for particulars. 01985 */ 01986 exit_rc = exit_init(); 01987 01988 if (EXIT_MAIN_OKAY != exit_rc) 01989 { 01990 /* Re-arm handler to simply exit */ 01991 int rearm_exit_rc = exit_init(); 01992 01993 if (EXIT_MAIN_OKAY != rearm_exit_rc) 01994 { 01995 /*Don't attempt other processing-- potential infinite loop*/ 01996 01997 /* Just minimal cleanup and quit */ 01998 JVMCFG_DEBUG_ECLIPSE_FLUSH_STDIO_BETTER_EXIT; 01999 return(rearm_exit_rc); 02000 } 02001 02002 jvm_shutdown(); 02003 02004 JVMCFG_DEBUG_ECLIPSE_FLUSH_STDIO_BETTER_EXIT; 02005 02006 /* Exit code from JVM */ 02007 return(exit_rc); 02008 } 02009 02010 /* 02011 * Trap various standard signals to stop JVM 02012 * (must call exit_init() first) 02013 */ 02014 signal(SIGHUP, jvm_signal); 02015 signal(SIGINT, jvm_signal); 02016 signal(SIGTERM, jvm_signal); 02017 02018 /* 02019 * Normal path from exit_init(): 02020 * 02021 * Initialize JVM model, init all structures, load prequisite 02022 * classes (Object, String[]), including @c @b <clinit>, 02023 * load requested user class, run its @c @b <clinit> . 02024 */ 02025 jvm_init(argc, argv, envp); 02026 02027 /* Now that JVM is initialized and user class loaded, go run it*/ 02028 jvm_run(); 02029 02030 jvm_shutdown(); 02031 02032 JVMCFG_DEBUG_ECLIPSE_FLUSH_STDIO_BETTER_EXIT; 02033 02034 /* Exit code from JVM */ 02035 return(EXIT_MAIN_OKAY); 02036 02037 } /* END of jvm() */ 02038 02039 02040 /* EOF */ 02041