blob: 88152838663c904bc52fe6fdf83992a43b98b778 [file] [log] [blame]
//===----------- JavaObject.h - Java object definition -------------------===//
//
// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef JNJVM_JAVA_OBJECT_H
#define JNJVM_JAVA_OBJECT_H
#include "vmkit/Allocator.h"
#include "vmkit/UTF8.h"
#include "vmkit/Locks.h"
#include "vmkit/Thread.h"
#include "VmkitGC.h"
#include "types.h"
#include "JnjvmConfig.h"
union jvalue;
namespace j3 {
class JavaObject;
class JavaThread;
class Jnjvm;
class Typedef;
class UserCommonClass;
class InterfaceMethodTable : public vmkit::PermanentObject {
public:
static const uint32_t NumIndexes = 29;
word_t contents[NumIndexes];
static uint32_t getIndex(const vmkit::UTF8* name, const vmkit::UTF8* type) {
return (name->hash() + type->hash()) % NumIndexes;
}
};
/// JavaVirtualTable - This class is the virtual table of instances of
/// Java classes. Besides holding function pointers for virtual calls,
/// it contains a bunch of information useful for fast dynamic type checking.
/// These are placed here for fast access of information from a Java object
/// (that only points to the VT, not the class).
///
class JavaVirtualTable : public VirtualTable {
public:
/// cl - The class which defined this virtual table.
///
CommonClass* cl;
/// depth - The super hierarchy depth of the class.
///
size_t depth;
/// offset - Offset in the virtual table where this virtual
/// table may be pointed. The offset is the cache if the class
/// is an interface or depth is too big, or an offset in the display.
///
size_t offset;
/// cache - The cached result for better type checks on secondary types.
///
JavaVirtualTable* cache;
/// display - Array of super classes.
///
JavaVirtualTable* display[8];
/// nbSecondaryTypes - The length of the secondary type list.
///
size_t nbSecondaryTypes;
/// secondaryTypes - The list of secondary types of this type. These
/// are the interface and all the supers whose depth is too big.
///
JavaVirtualTable** secondaryTypes;
/// baseClassVT - Holds the base class VT of an array. Used for AASTORE
/// checks.
///
JavaVirtualTable* baseClassVT;
/// IMT - The interface method table.
///
InterfaceMethodTable* IMT;
/// Java methods for the virtual table functions.
word_t init;
word_t equals;
word_t hashCode;
word_t toString;
word_t clone;
word_t getClass;
word_t notify;
word_t notifyAll;
word_t waitIndefinitely;
word_t waitMs;
word_t waitMsNs;
word_t virtualMethods[1];
/// operator new - Allocates a JavaVirtualTable with the given size. The
/// size must contain the additional information for type checking, as well
/// as the function pointers.
///
void* operator new(size_t sz, vmkit::BumpPtrAllocator& allocator,
uint32 nbMethods) {
return allocator.Allocate(sizeof(word_t) * (nbMethods), "Virtual table");
}
/// JavaVirtualTable - Create JavaVirtualTable objects for classes, array
/// classes and primitive classes.
///
JavaVirtualTable(Class* C);
JavaVirtualTable(ClassArray* C);
JavaVirtualTable(ClassPrimitive* C);
/// getFirstJavaMethod - Get the byte offset of the first Java method
/// (<init>).
///
word_t* getFirstJavaMethod() {
return &init;
}
/// getFirstJavaMethodIndex - Get the word offset of the first Java method.
///
static uint32_t getFirstJavaMethodIndex() {
return numberOfBaseFunctions() + 16;
}
/// getBaseSize - Get the size of the java.lang.Object virtual table.
///
static uint32_t getBaseSize() {
return numberOfBaseFunctions() + 27;
}
/// getNumJavaMethods - Get the number of methods of the java.lang.Object
/// class.
///
static uint32_t getNumJavaMethods() {
return 11;
}
/// getDisplayLength - Get the length of the display (primary type) array.
///
static uint32_t getDisplayLength() {
return 8;
}
/// getClassIndex - Get the word offset of the class.
///
static uint32_t getClassIndex() {
return numberOfBaseFunctions();
}
/// getDepthIndex - Get the word offset of the depth.
///
static uint32_t getDepthIndex() {
return numberOfBaseFunctions() + 1;
}
/// getOffsetIndex - Get the word offset of the type cache.
///
static uint32_t getOffsetIndex() {
return numberOfBaseFunctions() + 2;
}
/// getCacheIndex - Get the word offset of the type cache.
///
static uint32_t getCacheIndex() {
return numberOfBaseFunctions() + 3;
}
/// getDisplayIndex - Get the word offset of the display.
///
static uint32_t getDisplayIndex() {
return numberOfBaseFunctions() + 4;
}
/// getNumSecondaryTypesIndex - Get the word offset of the number of
/// secondary types.
///
static uint32_t getNumSecondaryTypesIndex() {
return numberOfBaseFunctions() + 12;
}
/// getSecondaryTypesIndex - Get the word offset of the secondary types
/// list.
///
static uint32_t getSecondaryTypesIndex() {
return numberOfBaseFunctions() + 13;
}
/// getBaseClassIndex - Get the word offset of the base class.
///
static uint32_t getBaseClassIndex() {
return numberOfBaseFunctions() + 14;
}
/// getIMTIndex - Get the word offset of the IMT.
///
static uint32_t getIMTIndex() {
return numberOfBaseFunctions() + 15;
}
/// isSubtypeOf - Returns true if the given VT is a subtype of the this
/// VT.
///
bool isSubtypeOf(JavaVirtualTable* VT);
/// setNativeTracer - Set the tracer of this virtual table as a method
/// defined by JnJVM.
///
void setNativeTracer(word_t tracer, const char* name);
/// setNativeDestructor - Set the destructor of this virtual table as a method
/// defined by JnJVM.
///
void setNativeDestructor(word_t tracer, const char* name);
};
/// JavaObject - This class represents a Java object.
///
class JavaObject : public gc {
private:
/// waitIntern - internal wait on a monitor
///
static void waitIntern(JavaObject* self, struct timeval *info, bool timed);
public:
/// Methods to match with VirtualTable
///
virtual ~JavaObject() {}
virtual void tracer(word_t closure) {}
/// operator new - Optimized operator new for VT based objects
///
void* operator new(size_t sz, VirtualTable *VT) {
return VTgcmallocUnresolved(sz, VT);
}
/// getVirtualTable - Returns the java virtual table of this object.
///
JavaVirtualTable* getVirtualTable() const {
return ((JavaVirtualTable**)(this))[0];
}
/// setVirtualTable - Sets the java virtual table of this object.
///
void setVirtualTable(JavaVirtualTable* VT) {
((JavaVirtualTable**)(this))[0] = VT;
}
/// getClass - Returns the class of this object.
///
static UserCommonClass* getClass(const JavaObject* self) __attribute__ ((always_inline)) {
llvm_gcroot(self, 0);
return ((JavaVirtualTable*)self->getVirtualTable())->cl;
}
/// instanceOf - Is this object's class of type the given class?
///
static bool instanceOf(JavaObject* self, UserCommonClass* cl);
/// wait - Java wait. Makes the current thread waiting on a monitor.
///
static void wait(JavaObject* self);
/// timedWait - Java timed wait. Makes the current thread waiting on a
/// monitor for the given amount of time.
///
static void timedWait(JavaObject* self, struct timeval &info);
/// wait - Wait for specified ms and ns. Wrapper for either wait() or
/// timedWait, depending on duration specified.
static void wait(JavaObject* self, int64_t ms, int32_t ns);
/// notify - Java notify. Notifies a thread from the availability of the
/// monitor.
///
static void notify(JavaObject* self);
/// notifyAll - Java notifyAll. Notifies all threads from the availability of
/// the monitor.
///
static void notifyAll(JavaObject* self);
/// clone - Java clone. Creates a copy of this object.
///
static JavaObject* clone(JavaObject* other);
/// overflowThinLock - Notify that the thin lock has overflowed.
///
static void overflowThinLock(JavaObject* self);
/// acquire - Acquire the lock on this object.
static void acquire(JavaObject* self);
/// release - Release the lock on this object
static void release(JavaObject* self);
/// owner - Returns true if the current thread is the owner of this object's
/// lock.
static bool owner(JavaObject* self);
#ifdef SIGSEGV_THROW_NULL
#define verifyNull(obj) {}
#else
#define verifyNull(obj) \
if (obj == NULL) JavaThread::get()->getJVM()->nullPointerException();
#endif
/// decapsulePrimitive - Based on the signature argument, decapsule
/// obj as a primitive and put it in the buffer.
///
static void decapsulePrimitive(JavaObject* self, Jnjvm* vm, jvalue* buf,
const Typedef* signature);
static uint16_t hashCodeGenerator;
/// hashCode - Return the hash code of this object.
static uint32_t hashCode(JavaObject* self);
void dumpClass() const __attribute__((noinline));
void dump() const __attribute__((noinline));
friend std::ostream& operator << (std::ostream&, const JavaObject&);
void dumpToString() const __attribute__((noinline));
};
} // end namespace j3
#endif