blob: 365ec18505a065a018ac6710b9c2bedd06ce6865 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Pavel Pervov
*/
#define LOG_DOMAIN LOG_CLASS_INFO
#include "cxxlog.h"
#include "open/vm_properties.h"
#include "environment.h"
#include "Package.h"
#include "String_Pool.h"
#include "Class.h"
#include "nogc.h"
#include "GlobalClassLoaderIterator.h"
#include "verifier.h"
#include "native_overrides.h"
#include "compile.h"
#include "component_manager.h"
Global_Env::Global_Env(apr_pool_t * pool, size_t string_pool_size):
mem_pool(pool),
bootstrap_class_loader(NULL),
system_class_loader(NULL),
TI(NULL),
nsoTable(NULL),
portLib(NULL),
dcList(NULL),
assert_reg(NULL),
string_pool(string_pool_size),
total_loaded_class_count(0),
unloaded_class_count(0),
total_compilation_time(0),
bootstrapping(false),
ready_for_exceptions(false)
{
// TODO: Use proper MM.
m_java_properties = new Properties();
m_vm_properties = new Properties();
bootstrap_class_loader = new BootstrapClassLoader(this);
hythread_lib_create(&hythread_lib);
#if defined _IPF_ || defined _EM64T_
compact_fields = true;
sort_fields = true;
#else // !_IPF_
compact_fields = false;
sort_fields = false;
#endif // !IPF_
heap_base = heap_end = managed_null = NULL;
JavaLangString_String = string_pool.lookup("java/lang/String");
JavaLangStringBuffer_String = string_pool.lookup("java/lang/StringBuffer");
JavaLangObject_String = string_pool.lookup("java/lang/Object");
JavaLangClass_String = string_pool.lookup("java/lang/Class");
VoidVoidDescriptor_String = string_pool.lookup("()V");
VoidBooleanDescriptor_String = string_pool.lookup("()Z");
VoidIntegerDescriptor_String = string_pool.lookup("()I");
JavaLangThrowable_String = string_pool.lookup("java/lang/Throwable");
JavaLangNoClassDefFoundError_String = string_pool.lookup("java/lang/NoClassDefFoundError");
JavaLangArrayIndexOutOfBoundsException_String = string_pool.lookup("java/lang/ArrayIndexOutOfBoundsException");
JavaNioByteBuffer_String = string_pool.lookup("java/nio/ByteBuffer");
JavaLangIllegalArgumentException_String = string_pool.lookup("java/lang/IllegalArgumentException");
JavaLangReflectField_String = string_pool.lookup("java/lang/reflect/Field");
JavaLangReflectConstructor_String = string_pool.lookup("java/lang/reflect/Constructor");
JavaLangReflectMethod_String = string_pool.lookup("java/lang/reflect/Method");
JavaLangUnsatisfiedLinkError_String = string_pool.lookup("java/lang/UnsatisfiedLinkError");
JavaLangNullPointerException_String = string_pool.lookup("java/lang/NullPointerException");
Init_String = string_pool.lookup("<init>");
Clinit_String = string_pool.lookup("<clinit>");
FinalizeName_String = string_pool.lookup("finalize");
EnqueueName_String = string_pool.lookup("enqueue");
Clonable_String = string_pool.lookup("java/lang/Cloneable");
Serializable_String = string_pool.lookup("java/io/Serializable");
Detach_String = string_pool.lookup("detach");
DetachDescriptor_String = string_pool.lookup("(Ljava/lang/Throwable;)V");
GetUncaughtExceptionHandler_String = string_pool.lookup("getUncaughtExceptionHandler");
GetUncaughtExceptionHandlerDescriptor_String = string_pool.lookup("()Ljava/lang/Thread$UncaughtExceptionHandler;");
UncaughtException_String = string_pool.lookup("uncaughtException");
UncaughtExceptionDescriptor_String = string_pool.lookup("(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
GetDefaultUncaughtExceptionHandler_String = string_pool.lookup("getDefaultUncaughtExceptionHandler");
GetDefaultUncaughtExceptionHandlerDescriptor_String = string_pool.lookup("()Ljava/lang/Thread$UncaughtExceptionHandler;");
GetName_String = string_pool.lookup("getName");
GetNameDescriptor_String = string_pool.lookup("()Ljava/lang/String;");
Remove_String = string_pool.lookup("remove");
RemoveDescriptor_String = string_pool.lookup("(Ljava/lang/Thread;)V");
LLRemove_String = string_pool.lookup("remove");
LLRemoveDescriptor_String = string_pool.lookup("(Ljava/lang/Object;)Z");
Length_String = string_pool.lookup("length");
LoadClass_String = string_pool.lookup("loadClass");
InitCause_String = string_pool.lookup("initCause");
FromStringConstructorDescriptor_String = string_pool.lookup("(Ljava/lang/String;)V");
LoadClassDescriptor_String = string_pool.lookup("(Ljava/lang/String;)Ljava/lang/Class;");
InitCauseDescriptor_String = string_pool.lookup("(Ljava/lang/Throwable;)Ljava/lang/Throwable;");
//
// globals
//
// HT support from command line disabled. VM should automatically detect HT status at startup.
is_hyperthreading_enabled = false;
use_lil_stubs = true;
#ifdef REFS_USE_RUNTIME_SWITCH
#ifdef POINTER64
compress_references = true;
#else // POINTER64
compress_references = false;
#endif // POINTER64
#endif // REFS_USE_RUNTIME_SWITCH
strings_are_compressed = false;
// page size detection
use_large_pages = false;
size_t *ps = port_vmem_page_sizes();
if (ps[1] != 0 && use_large_pages) {
system_page_size = ps[1];
}
else {
system_page_size = ps[0];
}
verify_all = false;
verify_strict = false;
verify = true;
pin_interned_strings = false;
retain_invisible_annotations = false;
// initialize critical sections
p_jit_a_method_lock = new Lock_Manager();
p_vtable_patch_lock = new Lock_Manager();
p_handle_lock = new Lock_Manager();
p_method_call_lock = new Lock_Manager();
p_dclist_lock = new Lock_Manager();
p_suspend_lock = new Lock_Manager();
//
// preloaded classes
//
Boolean_Class = NULL;
Char_Class = NULL;
Float_Class = NULL;
Double_Class = NULL;
Byte_Class = NULL;
Short_Class = NULL;
Int_Class = NULL;
Long_Class = NULL;
ArrayOfBoolean_Class = NULL;
ArrayOfChar_Class = NULL;
ArrayOfFloat_Class = NULL;
ArrayOfDouble_Class = NULL;
ArrayOfByte_Class = NULL;
ArrayOfShort_Class = NULL;
ArrayOfInt_Class = NULL;
ArrayOfLong_Class = NULL;
JavaLangObject_Class = NULL;
JavaLangString_Class = NULL;
JavaLangClass_Class = NULL;
java_lang_Throwable_Class = NULL;
java_lang_Error_Class = NULL;
java_lang_ExceptionInInitializerError_Class = NULL;
java_lang_NullPointerException_Class = NULL;
java_lang_StackOverflowError_Class = NULL;
java_lang_ArrayIndexOutOfBoundsException_Class = NULL;
java_lang_ArrayStoreException_Class = NULL;
java_lang_ArithmeticException_Class = NULL;
java_lang_ClassCastException_Class = NULL;
java_lang_OutOfMemoryError_Class = NULL;
java_lang_InternalError_Class = NULL;
java_lang_ThreadDeath_Class = NULL;
java_lang_OutOfMemoryError = NULL;
popFrameException = NULL;
java_lang_FinalizerThread_Class = NULL;
java_io_Serializable_Class = NULL;
java_lang_Cloneable_Class = NULL;
java_lang_Thread_Class = NULL;
java_lang_ThreadGroup_Class = NULL;
java_lang_reflect_Constructor_Class = NULL;
java_lang_reflect_Field_Class = NULL;
java_lang_reflect_Method_Class = NULL;
JavaLangString_VTable = NULL;
java_security_ProtectionDomain_Class = NULL;
Class_domain_field_offset = 0;
vm_class_offset = 0;
vm_state = VM_INITIALIZING;
TI = new DebugUtilsTI;
NCAI = new GlobalNCAI;
nsoTable = nso_init_lookup_table(&string_pool);
} //Global_Env::Global_Env
Global_Env::~Global_Env()
{
GlobalClassLoaderIterator ClIterator;
ClassLoader *cl = ClIterator.first();
while(cl) {
ClassLoader* cltmp = cl;
cl = ClIterator.next();
delete cltmp;
}
ClassLoader::DeleteClassLoaderTable();
delete TI;
TI = NULL;
delete NCAI;
NCAI = NULL;
delete m_java_properties;
m_java_properties = NULL;
delete m_vm_properties;
m_vm_properties = NULL;
nso_clear_lookup_table(nsoTable);
nsoTable = NULL;
compile_clear_dynamic_code_list(dcList);
dcList = NULL;
// uninitialize critical sections
delete p_jit_a_method_lock;
delete p_vtable_patch_lock;
delete p_handle_lock;
delete p_method_call_lock;
delete p_dclist_lock;
delete p_suspend_lock;
// Unload jit instances.
vm_delete_all_jits();
// Unload all system native libraries.
natives_cleanup();
// Unload GC-related resources.
gc_wrapup();
delete GlobalCodeMemoryManager;
GlobalCodeMemoryManager = NULL;
delete VTableMemoryManager;
VTableMemoryManager = NULL;
// TODO: Currently, there is only one global thread library instance.
// It still can be used after VM is destroyed.
// hythread_lib_destroy(hythread_lib);
}
Class* Global_Env::LoadCoreClass(const String* s)
{
Class* clss =
bootstrap_class_loader->LoadVerifyAndPrepareClass(this, s);
if(clss == NULL) {
// print error diagnostics and exit VM
LWARN(4, "Failed to load bootstrap class {0}" << s->bytes);
log_exit(1);
}
return clss;
}
Class* Global_Env::LoadCoreClass(const char* s)
{
return LoadCoreClass(this->string_pool.lookup(s));
}
size_t parse_size(const char* value) {
size_t size = atol(value);
int sizeModifier = tolower(value[strlen(value) - 1]);
size_t modifier;
switch(sizeModifier) {
case 'k': modifier = 1024; break;
case 'm': modifier = 1024 * 1024; break;
default: modifier = 1; break;
}
return size * modifier;
}
static size_t parse_size_prop(const char* name, size_t default_size) {
if(!vm_property_is_set(name, VM_PROPERTIES)) {
return default_size;
}
char* value = vm_properties_get_value(name, VM_PROPERTIES);
size_t size = parse_size(value);
vm_properties_destroy_value(value);
return size;
}
void Global_Env::init_pools() {
size_t pool_size;
pool_size = parse_size_prop("vm.code_pool_size.stubs", DEFAULT_JIT_CODE_POOL_SIZE);
assert(pool_size);
GlobalCodeMemoryManager = new PoolManager(pool_size, use_large_pages,
true/*is_code*/);
pool_size = parse_size_prop("vm.vtable_pool_size", DEFAULT_VTABLE_POOL_SIZE);
assert(pool_size);
VTableMemoryManager = new VTablePool(pool_size, use_large_pages);
bootstrap_code_pool_size = pool_size = parse_size_prop("vm.code_pool_size.bootstrap_loader",
DEFAULT_BOOTSTRAP_JIT_CODE_POOL_SIZE);
assert(pool_size);
user_code_pool_size = pool_size = parse_size_prop("vm.code_pool_size.user_loader",
DEFAULT_CLASSLOADER_JIT_CODE_POOL_SIZE);
assert(pool_size);
}
void* vm_get_vtable_base_address()
{
assert (VM_Global_State::loader_env->VTableMemoryManager);
#ifdef USE_COMPRESSED_VTABLE_POINTERS
assert (VM_Global_State::loader_env->VTableMemoryManager->get_base());
// Subtract a small number (like 1) from the real base so that
// no valid vtable offsets will ever be 0.
return (void*) (VM_Global_State::loader_env->VTableMemoryManager->get_base() - 8);
#else
return NULL;
#endif
} //vm_get_vtable_base