Esempio n. 1
0
Object* rvmNewObjectV(Env* env, Class* clazz, Method* method, va_list args) {
    Object* obj = rvmAllocateObject(env, clazz);
    if (!obj) return NULL;
    rvmCallNonvirtualVoidInstanceMethodV(env, obj, method, args);
    if (rvmExceptionOccurred(env)) return NULL;
    return obj;
}
Esempio n. 2
0
Object* Java_aura_rt_VM_allocateObject(Env* env, Class* c, Class* cls) {
    Object *o = rvmAllocateObject(env, cls);
    if (o && CLASS_IS_FINALIZABLE(cls)) {
        rvmRegisterFinalizer(env, o);
    }
    return o;
}
Esempio n. 3
0
jboolean rvmThrowOutOfMemoryError(Env* env) {
    // Don't run the constructor on OutOfMemoryError instances since that will
    // likely cause more OOM.
    Object* e = rvmAllocateObject(env, java_lang_OutOfMemoryError);
    if (!e) {
        return FALSE;
    }
    rvmThrow(env, e);
    return TRUE;
}
Esempio n. 4
0
static void signalHandler_npe_so(int signum, siginfo_t* info, void* context) {
    // rvmGetEnv() uses pthread_getspecific() which isn't listed as 
    // async-signal-safe. Others (e.g. mono) do this too so we assume it is safe 
    // in practice.
    Env* env = rvmGetEnv();
    if (env && rvmIsNonNativeFrame(env)) {
        // We now know the fault occurred in non-native code and not in our 
        // native code or in any non-async-signal-safe system function. It 
        // should be safe to do things here that would normally be unsafe to do
        // in a signal handler.
        void* faultAddr = info->si_addr;
        void* stackAddr = env->currentThread->stackAddr;
        Class* exClass = NULL;
        if (faultAddr < stackAddr && faultAddr >= (void*) (stackAddr - THREAD_STACK_GUARD_SIZE)) {
            // StackOverflowError
            exClass = java_lang_StackOverflowError;
        } else {
            // At least on Linux x86 it seems like si_addr isn't always 0x0 even
            // if a read of address 0x0 triggered SIGSEGV so we assume 
            // everything that isn't a stack overflow is a read of address 0x0
            // and throw NullPointerException.
            exClass = java_lang_NullPointerException;
        }

        if (exClass) {
            Object* throwable = rvmAllocateObject(env, exClass);
            if (!throwable) {
                throwable = rvmExceptionClear(env);
            }
            Frame fakeFrame;
            fakeFrame.prev = (Frame*) getFramePointer((ucontext_t*) context);
            fakeFrame.returnAddress = getPC((ucontext_t*) context);
            CallStack* callStack = captureCallStackFromFrame(env, &fakeFrame);
            rvmSetLongInstanceFieldValue(env, throwable, stackStateField, PTR_TO_LONG(callStack));
            rvmRaiseException(env, throwable);
        }
    }

    struct sigaction sa;
    sa.sa_flags = 0;
    sa.sa_handler = SIG_DFL;
    sigaction(signum, &sa, NULL);
    kill(0, signum);
}
Esempio n. 5
0
static void signalHandler_npe_so(int signum, siginfo_t* info, void* context) {
    // SIGSEGV/SIGBUS are synchronous signals so we shouldn't have to worry about only calling
    // async-signal-safe functions here.
    Env* env = rvmGetEnv();
    if (env && rvmIsNonNativeFrame(env)) {
        // We now know the fault occurred in non-native code.
        void* faultAddr = info->si_addr;
        void* stackAddr = env->currentThread->stackAddr;
        Class* exClass = NULL;
        if (faultAddr < stackAddr && faultAddr >= (void*) (stackAddr - THREAD_STACK_GUARD_SIZE)) {
            // StackOverflowError
            exClass = java_lang_StackOverflowError;
        } else {
            // At least on Linux x86 it seems like si_addr isn't always 0x0 even
            // if a read of address 0x0 triggered SIGSEGV so we assume 
            // everything that isn't a stack overflow is a read of address 0x0
            // and throw NullPointerException.
            exClass = java_lang_NullPointerException;
        }

        if (exClass) {
            Frame fakeFrame;
            fakeFrame.prev = (Frame*) getFramePointer((ucontext_t*) context);
            fakeFrame.returnAddress = getPC((ucontext_t*) context);
            Object* throwable = NULL;
            CallStack* callStack = captureCallStackFromFrame(env, &fakeFrame);
            if (callStack) {
                throwable = rvmAllocateObject(env, exClass);
                if (throwable) {
                    rvmCallVoidClassMethod(env, exClass, throwableInitMethod, throwable, PTR_TO_LONG(callStack));
                    if (rvmExceptionCheck(env)) {
                        throwable = NULL;
                    }
                }
            }
            if (!throwable) {
                throwable = rvmExceptionClear(env);
            }
            rvmRaiseException(env, throwable); // Never returns!
        }
    }
}
Esempio n. 6
0
File: bc.c Progetto: SinoJerk/robovm
Object* _bcAllocate(Env* env, ClassInfoHeader* header) {
    ENTER;
    Object* obj = rvmAllocateObject(env, header->clazz);
    LEAVE(obj);
}
Esempio n. 7
0
static jobject AllocObject(JNIEnv* env, jclass clazz) {
    return (jobject) rvmAllocateObject((Env*) env, (Class*) clazz);
}
Esempio n. 8
0
static jint attachThread(VM* vm, Env** envPtr, char* name, Object* group, jboolean daemon) {
    Env* env = *envPtr; // env is NULL if rvmAttachCurrentThread() was called. If non NULL rvmInitThreads() was called.
    if (!env) {
        // If the thread was already attached there's an Env* associated with the thread.
        env = (Env*) pthread_getspecific(tlsEnvKey);
        if (env) {
            env->attachCount++;
            *envPtr = env;
            return JNI_OK;
        }
    }
    
    if (!env) {
        env = rvmCreateEnv(vm);
        if (!env) goto error;
    }

    setThreadEnv(env);
    if (rvmExceptionOccurred(env)) goto error;

    Thread* thread = allocThread(env);
    if (!thread) goto error;
    thread->stackAddr = getStackAddress();
    thread->pThread = pthread_self();
    env->currentThread = thread;
    rvmChangeThreadStatus(env, thread, THREAD_RUNNING);
    
    JavaThread* threadObj = (JavaThread*) rvmAllocateObject(env, java_lang_Thread);
    if (!threadObj) goto error;

    rvmLockThreadsList();
    if (!initThread(env, thread, threadObj)) {
        rvmUnlockThreadsList();
        goto error;
    }
    if (!rvmSetupSignals(env)) {
        rvmUnlockThreadsList();
        goto error;
    }
    DL_PREPEND(threads, thread);
    pthread_cond_broadcast(&threadsChangedCond);
    rvmUnlockThreadsList();

    Object* threadName = NULL;
    if (name) {
        threadName = rvmNewStringUTF(env, name, -1);
        if (!threadName) goto error_remove;
    }

    Method* threadConstructor = rvmGetInstanceMethod2(env, java_lang_Thread, "<init>", "(JLjava/lang/String;Ljava/lang/ThreadGroup;Z)V");
    if (!threadConstructor) goto error_remove;

    rvmCallNonvirtualVoidInstanceMethod(env, (Object*) threadObj, threadConstructor, PTR_TO_LONG(thread), threadName, group, daemon);
    if (rvmExceptionOccurred(env)) goto error_remove;

    *envPtr = env;

    return JNI_OK;

error_remove:
    rvmLockThreadsList();
    DL_DELETE(threads, thread);
    pthread_cond_broadcast(&threadsChangedCond);
    rvmTearDownSignals(env);
    rvmUnlockThreadsList();
error:
    if (env) env->currentThread = NULL;
    clearThreadEnv();
    return JNI_ERR;
}
Esempio n. 9
0
Object* Java_sun_misc_Unsafe_allocateInstance(Env* env, Object* unsafe, Class* c) {
  return rvmAllocateObject(env, c);
}