blob: 2210dd64d23a623380408e924636521e1bbcd143 [file] [log] [blame]
//===- ClasspathVMStackWalker.cpp -----------------------------------------===//
//===------------ GNU classpath gnu/classpath/VMStackWalker ---------------===//
//
// JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <string.h>
#include "types.h"
#include "mvm/JIT.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaJIT.h"
#include "JavaObject.h"
#include "JavaTypes.h"
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "NativeUtil.h"
using namespace jnjvm;
extern "C" {
#ifdef MULTIPLE_VM
uint32 getPools(UserConstantPool** pools, uint32 size) {
unsigned int* top;
register unsigned int **cur = &top;
register unsigned int **max = (unsigned int**)mvm::Thread::get()->baseSP;
uint32 i = 0;
for(; cur<max && i < size; cur++) {
void* obj = (void*)(*cur);
obj = Collector::begOf(obj);
if (obj && ((mvm::Object*)obj)->getVirtualTable() == UserConstantPool::VT) {
UserConstantPool* ctp = (UserConstantPool*)obj;
pools[i++] = ctp;
}
}
return i;
}
#endif
#ifdef MULTIPLE_VM
JavaObject* getClassInContext(Jnjvm* vm, Class* cl, UserConstantPool** ctps, uint32& ctpIndex) {
for (; ctpIndex < 100; ++ctpIndex) {
UserClass* newCl = ctps[ctpIndex]->getClass();
if (cl == newCl->classDef) return newCl->getClassDelegatee(vm);
}
return 0;
}
ArrayObject* recGetClassContext(Jnjvm* vm, int** stack, uint32 size, uint32 first, uint32 rec, UserConstantPool** ctps, uint32 ctpIndex) {
if (size != first) {
JavaMethod* meth = JavaJIT::IPToJavaMethod(stack[first]);
if (meth) {
JavaObject* obj = getClassInContext(vm, meth->classDef, ctps, ctpIndex);
ArrayObject* res = recGetClassContext(vm, stack, size, first + 1, rec + 1, ctps, ctpIndex);
res->elements[rec] = obj;
assert(res->elements[rec] && "Did not found the user class");
return res;
} else {
return recGetClassContext(vm, stack, size, first + 1, rec, ctps, ctpIndex);
}
} else {
return (ArrayObject*)vm->upcalls->classArrayClass->doNew(rec, vm);
}
}
#else
ArrayObject* recGetClassContext(Jnjvm* vm, int** stack, uint32 size, uint32 first, uint32 rec) {
if (size != first) {
JavaMethod* meth = JavaJIT::IPToJavaMethod(stack[first]);
if (meth) {
ArrayObject* res = recGetClassContext(vm, stack, size, first + 1, rec + 1);
res->elements[rec] = meth->classDef->getClassDelegatee(vm);
return res;
} else {
return recGetClassContext(vm, stack, size, first + 1, rec);
}
} else {
return (ArrayObject*)vm->upcalls->classArrayClass->doNew(rec, vm);
}
}
#endif
JNIEXPORT jobject JNICALL Java_gnu_classpath_VMStackWalker_getClassContext(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
) {
Jnjvm* vm = JavaThread::get()->isolate;
int* ips[100];
int real_size = mvm::jit::getBacktrace((void**)(void*)ips, 100);
#ifdef MULTIPLE_VM
UserConstantPool* pools[100];
getPools(pools, 100);
#endif
int i = 0;
int first = 0;
UserCommonClass* cl = vm->upcalls->vmStackWalker;
while (i < real_size) {
JavaMethod* meth = JavaJIT::IPToJavaMethod(ips[i++]);
#ifdef MULTIPLE_VM
if (meth && meth->classDef == cl->classDef) {
#else
if (meth && meth->classDef == cl) {
#endif
first = i;
break;
}
}
#ifdef MULTIPLE_VM
return (jobject)recGetClassContext(vm, ips, real_size, first, 0, pools, 0);
#else
return (jobject)recGetClassContext(vm, ips, real_size, first, 0);
#endif
}
JNIEXPORT jobject JNICALL Java_gnu_classpath_VMStackWalker_getClassLoader(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
jclass _Cl) {
Jnjvm* vm = JavaThread::get()->isolate;
JavaObject* Cl = (JavaObject*)_Cl;
UserCommonClass* cl = (UserCommonClass*)vm->upcalls->vmdataClass->getObjectField(Cl);
return (jobject)cl->classLoader->getJavaClassLoader();
}
extern "C" JavaObject* getCallingClass() {
UserClass* cl = JavaJIT::getCallingClass();
if (cl) return cl->getClassDelegatee(JavaThread::get()->isolate);
return 0;
}
extern "C" JavaObject* getCallingClassLoader() {
return JavaJIT::getCallingClassLoader();
}
}