blob: 872e8dd7ef9195acb9184de24e832fd8df191902 [file] [log] [blame]
//===-- JnjvmClassLoader.h - Jnjvm representation of a class loader -------===//
//
// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef JNJVM_CLASSLOADER_H
#define JNJVM_CLASSLOADER_H
#include <map>
#include <vector>
#include "types.h"
#include "mvm/Allocator.h"
#include "mvm/Object.h"
#include "JavaObject.h"
#include "JnjvmConfig.h"
#include "UTF8.h"
namespace j3 {
class ArrayUInt8;
class UserClass;
class UserClassArray;
class ClassMap;
class Classpath;
class UserCommonClass;
class JavaCompiler;
class JavaMethod;
class JavaObject;
class JavaString;
class Jnjvm;
class JnjvmBootstrapLoader;
class JnjvmClassLoader;
class Signdef;
class SignMap;
class StringList;
class Typedef;
class TypeMap;
class ZipArchive;
/// JnjvmClassLoader - Runtime representation of a class loader. It contains
/// its own tables (signatures, UTF8, types) which are mapped to a single
/// table for non-isolate environments.
///
class JnjvmClassLoader : public mvm::PermanentObject {
private:
/// isolate - Which isolate defined me? Null for the bootstrap class loader.
///
Jnjvm* isolate;
/// javaLoder - The Java representation of the class loader. Null for the
/// bootstrap class loader.
///
JavaObject* javaLoader;
/// internalLoad - Load the class with the given name.
///
virtual UserClass* internalLoad(const UTF8* utf8, bool doResolve,
JavaString* strName = 0);
/// internalConstructType - Hashes a Typedef, an internal representation of
/// a class still not loaded.
///
Typedef* internalConstructType(const UTF8 * name);
/// JnjvmClassLoader - Allocate a user-defined class loader. Called on
/// first use of a Java class loader.
///
JnjvmClassLoader(mvm::BumpPtrAllocator& Alloc, JnjvmClassLoader& JCL,
JavaObject* loader, Jnjvm* isolate);
/// lookupComponentName - Try to find the component name of the given array
/// name. If the component name is not in the table of UTF8s and holder
/// is null, the function returns 0.
///
const UTF8* lookupComponentName(const UTF8* name, UTF8* holder, bool& prim);
protected:
JnjvmClassLoader(mvm::BumpPtrAllocator& Alloc) : allocator(Alloc) {}
/// TheCompiler - The Java compiler for this class loader.
///
JavaCompiler* TheCompiler;
/// classes - The classes this class loader has loaded.
///
ClassMap* classes;
/// javaTypes - Tables of Typedef defined by this class loader.
///
TypeMap* javaTypes;
/// javaSignatures - Tables of Signdef defined by this class loader.
///
SignMap* javaSignatures;
public:
/// allocator - Reference to the memory allocator, which will allocate UTF8s,
/// signatures and types.
///
mvm::BumpPtrAllocator& allocator;
/// getIsolate - Returns the isolate that created this class loader.
///
Jnjvm* getIsolate() const { return isolate; }
/// getClasses - Returns the classes this class loader has loaded.
///
ClassMap* getClasses() const { return classes; }
/// hashUTF8 - Tables of UTF8s defined by this class loader.
///
UTF8Map* hashUTF8;
/// getCompiler - Get the Java compiler of this class loader.
///
JavaCompiler* getCompiler() const { return TheCompiler; }
/// setCompiler - Set the compiler of classes loaded by this class loader.
///
void setCompiler(JavaCompiler* Comp);
/// tracer - Traces a JnjvmClassLoader for GC.
///
virtual void tracer();
/// getJnjvmLoaderFromJavaObject - Return the Jnjvm runtime representation
/// of the given class loader.
///
static JnjvmClassLoader* getJnjvmLoaderFromJavaObject(JavaObject*, Jnjvm *vm);
/// getJavaClassLoader - Return the Java representation of this class loader.
///
JavaObject* getJavaClassLoader() const {
return javaLoader;
}
/// getJavaClassLoaderPtr - Return a pointer to the Java representation of
/// this class loader.
///
JavaObject** getJavaClassLoaderPtr() {
return &javaLoader;
}
/// loadName - Loads the class of the given name.
///
UserClass* loadName(const UTF8* name, bool doResolve, bool doThrow,
JavaString* strName = 0);
/// loadClassFromUTF8 - Lookup a class from an UTF8 name and load it.
///
UserCommonClass* loadClassFromUserUTF8(const UTF8* utf8,
bool doResolve, bool doThrow,
JavaString* strName = 0);
/// loadClassFromAsciiz - Lookup a class from an asciiz name and load it.
///
UserCommonClass* loadClassFromAsciiz(const char* name,
bool doResolve, bool doThrow);
/// loadClassFromJavaString - Lookup a class from a Java String and load it.
///
UserCommonClass* loadClassFromJavaString(JavaString* str,
bool doResolve, bool doThrow);
/// lookupClassFromJavaString - Finds the class of the given string name in
/// the class loader's table. Do not inline this function, because it
/// does an alloca and is called by Classpath functions.
///
UserCommonClass* lookupClassFromJavaString(JavaString* str)
__attribute__ ((noinline));
/// lookupClass - Finds the class of the given name in the class loader's
/// table.
///
UserCommonClass* lookupClass(const UTF8* utf8);
/// lookupClassOrArray - Finds the class of the given name in the class
/// loader's table. If the class has not been loaded, and if it's an
/// array whose base class is loaded, then this function loads the array class
/// and returns it.
///
UserCommonClass* lookupClassOrArray(const UTF8* utf8);
/// constructArray - Hashes a runtime representation of a class with
/// the given name.
///
UserClassArray* constructArray(const UTF8* name);
UserClassArray* constructArray(const UTF8* name, UserCommonClass* base);
UserCommonClass* loadBaseClass(const UTF8* name, uint32 start, uint32 len);
/// constructClass - Hashes a runtime representation of a class with
/// the given name.
///
UserClass* constructClass(const UTF8* name, ArrayUInt8* bytes);
/// constructType - Hashes a Typedef, an internal representation of a class
/// still not loaded.
///
Typedef* constructType(const UTF8 * name);
/// constructSign - Hashes a Signdef, a method signature.
///
Signdef* constructSign(const UTF8 * name);
/// asciizConstructUTF8 - Hashes an UTF8 created from the given asciiz.
///
const UTF8* asciizConstructUTF8(const char* asciiz);
/// readerConstructUTF8 - Hashes an UTF8 created from the given Unicode
/// buffer.
///
const UTF8* readerConstructUTF8(const uint16* buf, uint32 size);
/// bootstrapLoader - The bootstrap loader of the JVM. Loads the base
/// classes.
///
JnjvmBootstrapLoader* bootstrapLoader;
/// ~JnjvmClassLoader - Destroy the loader: destroy the tables, JIT module and
/// module provider.
///
virtual ~JnjvmClassLoader();
/// loadClass - The user class that defines the loadClass method.
///
UserClass* loadClass;
/// constructArrayName - Construct an array name based on a class name
/// and the number of dimensions.
const UTF8* constructArrayName(uint32 steps, const UTF8* className);
/// UTF8ToStr - Constructs a Java string out of the UTF8.
///
virtual JavaString** UTF8ToStr(const UTF8* utf8);
/// Strings hashed by this classloader.
///
StringList* strings;
/// nativeLibs - Native libraries (e.g. '.so') loaded by this class loader.
///
std::vector<void*> nativeLibs;
/// loadInLib - Loads a native function out of the native libraries loaded
/// by this class loader. The last argument tells if the returned method
/// is defined in j3.
///
intptr_t loadInLib(const char* buf, bool& j3);
/// loadInLib - Loads a native function out of the given native library.
///
intptr_t loadInLib(const char* buf, void* handle);
/// loadLib - Loads the library with the given name.
///
void* loadLib(const char* buf);
/// nativeLookup - Lookup in the class loader a function pointer for the
/// method. Also set in the j3 parameter is the function is defined in
/// JnJVM.
///
intptr_t nativeLookup(JavaMethod* meth, bool& j3, char* buf);
/// insertAllMethodsInVM - Insert all methods defined by this class loader
/// in the VM.
///
void insertAllMethodsInVM(Jnjvm* vm);
/// loadLibFromJar - Try to load the shared library compiled by vmjc with
/// this jar file.
///
void loadLibFromJar(Jnjvm* vm, const char* name, const char* file);
/// loadLibFromFile - Try to load the shared library compiled by vmjc with
/// this class file.
///
void loadLibFromFile(Jnjvm* vm, const char* name);
/// loadClassFromSelf - Load the main class if we are an executable.
///
Class* loadClassFromSelf(Jnjvm* vm, const char* name);
};
/// JnjvmBootstrapLoader - This class is for the bootstrap class loader, which
/// loads base classes, ie glibj.zip or rt.jar and -Xbootclasspath.
///
class JnjvmBootstrapLoader : public JnjvmClassLoader {
private:
/// internalLoad - Load the class with the given name.
///
virtual UserClass* internalLoad(const UTF8* utf8, bool doResolve,
JavaString* strName = 0);
/// bootClasspath - List of paths for the base classes.
///
std::vector<const char*> bootClasspath;
/// bootArchives - List of .zip or .jar files that contain base classes.
///
std::vector<ZipArchive*> bootArchives;
/// openName - Opens a file of the given name and returns it as an array
/// of byte.
///
ArrayUInt8* openName(const UTF8* utf8);
public:
/// tracer - Traces instances of this class.
///
virtual void tracer();
/// libClasspathEnv - The paths for dynamic libraries of Classpath, separated
/// by ':'.
///
const char* libClasspathEnv;
/// bootClasspathEnv - The path for base classes, seperated by '.'.
///
const char* bootClasspathEnv;
/// analyseClasspathEnv - Analyse the paths for base classes.
///
void analyseClasspathEnv(const char*);
/// createBootstrapLoader - Creates the bootstrap loader, first thing
/// to do before any execution of a JVM. Also try to load libvmjc.so
/// if dlLoad is not false.
///
JnjvmBootstrapLoader(mvm::BumpPtrAllocator& Alloc, JavaCompiler* Comp,
bool dlLoad = true);
virtual JavaString** UTF8ToStr(const UTF8* utf8);
/// nativeHandle - Non-null handle if boot classes were static compiled in
/// a dynamic library
///
void* nativeHandle;
/// upcalls - Upcall classes, fields and methods so that C++ code can call
/// Java code.
///
Classpath* upcalls;
/// InterfacesArray - The interfaces that array classes implement.
///
UserClass** InterfacesArray;
/// SuperArray - The super of array classes.
UserClass* SuperArray;
/// Lists of UTF8s used internaly in VMKit.
const UTF8* NoClassDefFoundError;
const UTF8* initName;
const UTF8* clinitName;
const UTF8* clinitType;
const UTF8* initExceptionSig;
const UTF8* runName;
const UTF8* prelib;
const UTF8* postlib;
const UTF8* mathName;
const UTF8* stackWalkerName;
const UTF8* abs;
const UTF8* sqrt;
const UTF8* sin;
const UTF8* cos;
const UTF8* tan;
const UTF8* asin;
const UTF8* acos;
const UTF8* atan;
const UTF8* atan2;
const UTF8* exp;
const UTF8* log;
const UTF8* pow;
const UTF8* ceil;
const UTF8* floor;
const UTF8* rint;
const UTF8* cbrt;
const UTF8* cosh;
const UTF8* expm1;
const UTF8* hypot;
const UTF8* log10;
const UTF8* log1p;
const UTF8* sinh;
const UTF8* tanh;
const UTF8* finalize;
/// primitiveMap - Map of primitive classes, hashed by id.
std::map<const char, UserClassPrimitive*> primitiveMap;
UserClassPrimitive* getPrimitiveClass(char id) {
return primitiveMap[id];
}
/// arrayTable - Table of array classes.
UserClassArray* arrayTable[8];
UserClassArray* getArrayClass(unsigned id) {
return arrayTable[id - 4];
}
virtual ~JnjvmBootstrapLoader();
};
/// VMClassLoader - The vmdata object that will be placed in and will only
/// be referenced by the java.lang.Classloader Java object. Having a
/// separate class between VMClassLoader and JnjvmClassLoader allows to
/// have a JnjvmClassLoader non-GC object. Also the finalizer of this class
/// will delete the internal class loader and we do not have to implement
/// hacks in the java.lang.Classloader finalizer.
class VMClassLoader : public JavaObject {
private:
/// JCL - The internal class loader.
///
JnjvmClassLoader* JCL;
public:
static VMClassLoader* allocate(JnjvmClassLoader* J) {
VMClassLoader* res = 0;
llvm_gcroot(res, 0);
res = (VMClassLoader*)gc::operator new(sizeof(VMClassLoader), &VT);
res->JCL = J;
return res;
}
/// VT - The VirtualTable for this GC-class.
///
static VirtualTable VT;
/// Is the object a VMClassLoader object?
///
static bool isVMClassLoader(JavaObject* obj) {
return obj->getVirtualTable() == &VT;
}
/// staticTracer - Trace the internal class loader.
///
static void staticTracer(VMClassLoader* obj) {
if (obj->JCL) obj->JCL->tracer();
}
/// ~VMClassLoader - Delete the internal class loader.
///
static void staticDestructor(VMClassLoader* obj) {
if (obj->JCL) {
obj->JCL->~JnjvmClassLoader();
delete &(obj->JCL->allocator);
}
}
/// VMClassLoader - Default constructors.
///
VMClassLoader(JnjvmClassLoader* J) : JCL(J) {}
/// getClassLoader - Get the internal class loader.
///
JnjvmClassLoader* getClassLoader() {
return JCL;
}
};
#define MAXIMUM_STRINGS 100
class StringList : public mvm::PermanentObject {
friend class JnjvmClassLoader;
friend class Jnjvm;
private:
StringList* prev;
uint32_t length;
JavaString* strings[MAXIMUM_STRINGS];
public:
StringList() {
prev = 0;
length = 0;
}
JavaString** addString(JnjvmClassLoader* JCL, JavaString* obj) {
llvm_gcroot(obj, 0);
if (length == MAXIMUM_STRINGS) {
StringList* next = new(JCL->allocator, "StringList") StringList();
next->prev = this;
JCL->strings = next;
return next->addString(JCL, obj);
} else {
strings[length] = obj;
return &strings[length++];
}
}
};
} // end namespace j3
#endif // JNJVM_CLASSLOADER_H