/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "classfile/classFileParser.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/oopMapCache.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/generation.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.inline.hpp"
#include "oops/constantPoolKlass.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceRefKlass.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/fprofiler.hpp"
#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/threadCritical.hpp"
#include "services/management.hpp"
#include "services/threadService.hpp"
#include "utilities/events.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/hashtable.inline.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "os_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "os_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "os_bsd.inline.hpp"
#endif
typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
// Globals
// helper routines
if (str_to_find_len > str_len) {
return false;
}
}
if (str_to_find_len > str_len) {
return false;
}
}
if (num_meta_package_names == 0) {
} else {
}
}
}
if ( _num_meta_package_names == 0) {
return false;
}
for (int i = 0; i < _num_meta_package_names; i++) {
return true;
}
}
return false;
}
}
return false;
}
}
// construct full path name
return NULL;
}
// check if file exists
// found file, open it
if (file_handle != -1) {
// read contents into resource array
// close file
// construct ClassFileStream
if (UsePerfData) {
}
}
}
}
return NULL;
}
}
}
}
// enable call to C land
// check whether zip archive contains name
char* filename;
if (name_len < 128) {
} else {
}
// file found, get pointer to class in mmaped jar file.
if (ReadMappedEntry == NULL ||
// mmaped access not available, perhaps due to compression,
// read contents into resource array
}
if (UsePerfData) {
}
// return result
}
// invoke function for each entry in the zip file
for (int n = 0; ; n++) {
}
}
_meta_index = NULL;
}
}
if (_resolved_entry != NULL) {
return (ClassPathEntry*) _resolved_entry;
}
{
if (_resolved_entry == NULL) {
return new_entry;
}
}
delete new_entry;
return (ClassPathEntry*) _resolved_entry;
}
if (_meta_index != NULL &&
return NULL;
}
}
return true;
}
GrowableArray<char*>& meta_packages) {
for (int i = 0; i < meta_packages.length(); i++) {
}
}
// Set up meta index which allows us to open boot jars lazily if
// class data sharing is enabled
int line_no = 0;
bool skipCurrentJar = false;
++line_no;
// Remove trailing newline
switch(package_name[0]) {
case '%':
{
if (TraceClassLoading && Verbose) {
}
return;
}
}
// These directives indicate jar files which contain only
// classes, only non-classfile resources, or a combination of
// make/tools/MetaIndex/BuildMetaIndex.java in the J2SE
// workspace.
case '#':
case '!':
case '@':
{
// Hand off current packages to current lazy entry (if any)
(boot_class_path_packages.length() > 0)) {
if (TraceClassLoading && Verbose) {
}
}
// Find lazy entry corresponding to this jar file
break;
}
}
// If the first character is '@', it indicates the following jar
// file is a resource only jar file in which case, we should skip
// reading the subsequent entries since the resource loading is
// totally handled by J2SE side.
if (package_name[0] == '@') {
}
skipCurrentJar = true;
} else {
skipCurrentJar = false;
}
break;
}
default:
{
}
}
}
}
// Hand off current packages to current lazy entry (if any)
(boot_class_path_packages.length() > 0)) {
if (TraceClassLoading && Verbose) {
}
}
}
}
if (TraceClassLoading && Verbose) {
}
int end = 0;
// Iterate over class path entries
end++;
}
update_class_path_entry_list(path, false);
end++;
}
}
}
void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy) {
if (lazy) {
return;
}
// Regular file, should be a zip file
// Canonicalized filename
// This matches the classic VM
}
{
// enable call to C land
}
if (TraceClassLoading) {
}
} else {
char *msg;
} else {
}
}
} else {
// Directory
if (TraceClassLoading) {
}
}
}
// Create a class path zip entry for a given path (return NULL if not found
// check for a regular file
{
// enable call to C land
}
// create using canonical path
}
}
}
}
return NULL;
}
// returns true if entry already on class path
ClassPathEntry* e = _first_entry;
while (e != NULL) {
// assume zip entries have been canonicalized
return true;
}
e = e->next();
}
return false;
}
if (_last_entry == NULL) {
} else {
}
}
}
bool check_for_duplicates) {
// File or directory found
// The kernel VM adds dynamically to the end of the classloader path and
// doesn't reorder the bootclasspath which would break java.lang.Package
// (see PackageInfo).
// Add new entry to linked list
}
}
}
ClassPathEntry* e = _first_entry;
while (e != NULL) {
e = e->next();
}
}
// First make sure native library is loaded
// Load zip library
}
// Lookup zip entry points
// ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL
}
// Lookup canonicalize entry in libjava.dll
CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, os::dll_lookup(javalib_handle, "Canonicalize"));
// This lookup only works on 1.3. Do not check for non-null here
}
// PackageInfo data exists in order to support the java.lang.Package
// class. A Package object provides information about a java package
// (version, vendor, etc.) which originates in the manifest of the jar
// file supplying the package. For application classes, the ClassLoader
// object takes care of this.
// For system (boot) classes, the Java code in the Package class needs
// to be able to identify which source jar file contained the boot
// class, so that it can extract the manifest from it. This table
// identifies java packages with jar files in the boot classpath.
// Because the boot classpath cannot change, the classpath index is
// sufficient to identify the source jar file or directory. (Since
// directories have no manifests, the directory name is not required,
// but is available.)
// When using sharing -- the pathnames of entries in the boot classpath
// may not be the same at runtime as they were when the archive was
// created (NFS, Samba, etc.). The actual files and directories named
// in the classpath must be the same files, in the same order, even
// though the exact name is not the same.
public:
}
const char* filename() {
}
}
};
private:
inline unsigned int compute_hash(const char *s, int n) {
unsigned int val = 0;
while (--n >= 0) {
}
return val;
}
}
return pp;
}
}
return NULL;
}
public:
}
return pp;
}
}
int n = 0;
for (int i = 0; i < table_size(); ++i) {
}
}
}
};
// Copy (relocate) the table to the shared space.
// Calculate the space needed for the package name strings.
int i;
int n = 0;
for (i = 0; i < table_size(); ++i) {
}
}
}
// Copy the table data (the strings) to the shared space.
n = align_size_up(n, sizeof(HeapWord));
for (i = 0; i < table_size(); ++i) {
}
}
}
}
}
// Package prefix found
}
return NULL;
}
// Bootstrap loader no longer holds system loader lock obj serializing
// load_instance_class and thereby add_package
{
// First check for previously loaded entry
// Existing entry found, check source of package
return true;
}
// Package prefix found
if (new_pkgname == NULL) {
return false;
}
new_pkgname[n] = '\0';
// Insert into hash table
}
return true;
}
}
{
}
return NULL;
} else {
return p();
}
}
int nof_entries;
const char** packages;
{
// Allocate resource char* array containing package names
return NULL;
}
}
// Allocate objArray and fill with java.lang.String
for (int i = 0; i < nof_entries; i++) {
}
return result();
}
// st.print() uses too much stack space while handling a StackOverflowError
// st.print("%s.class", h_name->as_utf8());
// Lookup stream for parsing .class file
int classpath_index = 0;
{
ClassPathEntry* e = _first_entry;
while (e != NULL) {
break;
}
e = e->next();
}
}
// class file found, parse it
false,
CHECK_(h));
// add to package table
h = result;
}
}
return h;
}
int number_of_entries) {
"bad shared package info size.");
}
}
// Initialize the class loader's access to methods in libzip. Parse and
// process the boot classpath into a list ClassPathEntry objects. Once
// this list has been created, it must not change order (see class PackageInfo)
// it can be appended to and is by jvmti and the kernel vm.
if (UsePerfData) {
// jvmstat performance counters
// The following performance counters are added for measuring the impact
// of the bug fix of 6365597. They are mainly focused on finding out
// the behavior of system & user-defined classloader lock, whether
// ClassLoader.loadClass/findClass is being called synchronized or not.
// Also two additional counters are created to see whether 'UnsyncloadClass'
// flag is being set or not and how many times load_instance_class call
// fails with linkageError etc.
"systemLoaderLockContentionRate");
"nonSystemLoaderLockContentionRate");
"jvmFindLoadedClassNoLockCalls");
"jvmDefineClassNoLockCalls");
"jniDefineClassNoLockCalls");
"unsafeDefineClassCalls");
"loadInstanceClassFailRate");
// increment the isUnsyncloadClass counter if UnsyncloadClass is set.
if (UnsyncloadClass) {
}
}
// lookup zip library entry points
// initialize search path
if (LazyBootClassLoader) {
// set up meta index which makes boot classpath initialization lazier
}
}
return UsePerfData ?
}
}
return UsePerfData ?
}
return UsePerfData ?
}
}
return UsePerfData ?
}
// hardwired for JDK1.2 -- would need to duplicate class file parsing
// code to determine actual value from file
// Would be value '11' if finals were in vtable
}
void classLoader_init() {
}
if (CanonicalizeEntry != NULL) {
return false;
}
} else {
// On JDK 1.2.2 the Canonicalize does not exist, so just do nothing
}
return true;
}
#ifndef PRODUCT
}
// CompileTheWorld
//
// Iterates over all class path entries and forces compilation of all methods
//
// The classes are loaded by the Java level bootstrap class loader, and the
// initializer is called. If DelayCompilationDuringStartup is true (default),
// the interpreter will run the initialization code. Note that forcing
// initialization in this way could potentially lead to initialization order
// problems, in which case we could just force the initialization bit to be set.
// jzcell and jzfile definitions from zip_util.h but rename jzfile to real_jzfile,
// since jzfile already has a void* definition.
//
// Note that this is only used in debug mode.
//
// HotSpot integration note:
// Matches zip_util.h 1.14 99/06/01 from jdk1.3 beta H build
// JDK 1.3 version
/* Information on metadata names in META-INF directory */
/* If there are any per-entry comments, they are in the comments array */
char **comments;
// JDK 1.2 version
}
return false;
}
if (JDK_Version::is_jdk12x_version()) {
} else {
}
if (HAS_PENDING_EXCEPTION) {
} else {
}
}
}
// Version that works for JDK 1.3.x
// Iterate over all entries in zip file
for (int n = 0; ; n++) {
}
}
// Version that works for JDK 1.2.x
// Iterate over all entries in zip file
for (int n = 0; ; n++) {
}
}
if (JDK_Version::is_jdk12x_version()) {
return is_rt_jar12();
} else {
return is_rt_jar13();
}
}
// JDK 1.3 version
// Check whether zip name ends in "rt.jar"
// This will match other archives named rt.jar as well, but this is
// only used for debugging.
}
// JDK 1.2 version
// Check whether zip name ends in "rt.jar"
// This will match other archives named rt.jar as well, but this is
// only used for debugging.
}
}
return resolve_entry()->is_rt_jar();
}
// Make sure we don't run with background compilation
BackgroundCompilation = false;
// Find bootstrap loader
// Iterate over all bootstrap class path entries
ClassPathEntry* e = _first_entry;
while (e != NULL) {
// We stop at rt.jar, unless it is the first bootstrap path entry
if (e->is_rt_jar() && e != _first_entry) break;
e = e->next();
}
{
// Print statistics as if before normal exit:
extern void print_statistics();
}
vm_exit(0);
}
static int _codecache_sweep_counter = 0;
// Filter out all exceptions except OOMs
if (HAS_PENDING_EXCEPTION &&
}
// The CHECK at the caller will propagate the exception out
}
// We have a .class file
// If the file has a period after removing .class, it's not really a
// valid class file. The class loader will check everything else.
if (_compile_the_world_counter > CompileTheWorldStopAt) return;
// Construct name without extension
// Use loader to load and initialize class
if (k.not_null() && !HAS_PENDING_EXCEPTION) {
k->initialize(THREAD);
}
if (CompileTheWorldPreloadClasses && k.not_null()) {
if (HAS_PENDING_EXCEPTION) {
// If something went wrong in preloading we just ignore it
}
}
if (k.is_null() || exception_occurred) {
// If something went wrong (e.g. ExceptionInInitializerError) we skip this class
} else {
// Preload all classes to get around uncommon traps
// Iterate over all methods in class
if (CompilationPolicy::can_be_compiled(m)) {
// Give sweeper a chance to keep up with CTW
}
// Force compilation
CompileBroker::compile_method(m, InvocationEntryBci, CompilationPolicy::policy()->initial_compile_level(),
if (HAS_PENDING_EXCEPTION) {
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string());
}
// Clobber the first compile and force second tier compilation
// Throw out the code so that the code cache doesn't fill up
nm->make_not_entrant();
m->clear_code();
}
if (HAS_PENDING_EXCEPTION) {
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_counter, m->name()->as_C_string());
}
}
}
// Throw out the code so that the code cache doesn't fill up
nm->make_not_entrant();
m->clear_code();
}
}
}
}
}
}
}
#endif //PRODUCT
// Please keep following two functions at end of this file. With them placed at top or in middle of the file,
// they could get inlined by agressive compiler, an unknown trick, see bug 6966589.
if (!UsePerfData) return;
// increment the event counter
}
// stop the current active thread-local timer to measure inclusive time
_prev_active_event = -1;
for (int i=0; i < EVENT_TYPE_COUNT; i++) {
_prev_active_event = i;
}
}
// start the inclusive timer if not recursively called
}
// start thread-local timer of the given event type
}
}
if (!UsePerfData) return;
// stop the thread-local timer as the event completes
// and resume the thread-local timer of the event next on the stack
if (_prev_active_event >= 0) {
}
// increment the counters only on the leaf call
if (_selftimep != NULL) {
}
// add all class loading related event selftime to the accumulated time counter
// reset the timer
}