001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.jni;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.classloader.RVMMethod;
017 import org.jikesrvm.classloader.RVMType;
018 import org.jikesrvm.compilers.common.CompiledMethod;
019 import org.jikesrvm.runtime.DynamicLink;
020 import org.jikesrvm.runtime.ExceptionDeliverer;
021 import org.jikesrvm.runtime.StackBrowser;
022 import org.vmmagic.pragma.Uninterruptible;
023 import org.vmmagic.pragma.Unpreemptible;
024 import org.vmmagic.unboxed.Offset;
025
026 /**
027 * Information associated with artifical stackframe inserted at the
028 * transition from Jave to JNI Native C.
029 *
030 * Exception delivery should never see Native C frames, or the Java to C
031 * transition frame. Native C code is redispatched during exception
032 * handling to either process/handle and clear the exception or to return
033 * to Java leaving the exception pending. If it returns to the transition
034 * frame with a pending exception. JNI causes an athrow to happen as if it
035 * was called at the call site of the call to the native method.
036 */
037 public final class JNICompiledMethod extends CompiledMethod {
038
039 /** Architecture specific deliverer of exceptions */
040 private static final ExceptionDeliverer deliverer;
041
042 static {
043 if (VM.BuildForIA32) {
044 try {
045 deliverer =
046 (ExceptionDeliverer)Class.forName("org.jikesrvm.jni.ia32.JNIExceptionDeliverer").newInstance();
047 } catch (Exception e) {
048 throw new Error(e);
049 }
050 } else {
051 deliverer = null;
052 }
053 }
054
055 public JNICompiledMethod(int id, RVMMethod m) {
056 super(id, m);
057 }
058
059 @Uninterruptible
060 public int getCompilerType() {
061 return JNI;
062 }
063
064 public String getCompilerName() {
065 return "JNI compiler";
066 }
067
068 @Uninterruptible
069 public ExceptionDeliverer getExceptionDeliverer() {
070 // this method should never get called on PPC
071 if (VM.VerifyAssertions) VM._assert(VM.BuildForIA32);
072 return deliverer;
073 }
074
075 @Uninterruptible
076 public void getDynamicLink(DynamicLink dynamicLink, Offset instructionOffset) {
077 // this method should never get called.
078 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);
079 }
080
081 public boolean isWithinUninterruptibleCode(Offset instructionOffset) {
082 return false;
083 }
084
085 @Unpreemptible
086 public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) {
087 return -1;
088 }
089
090 public void printStackTrace(Offset instructionOffset, org.jikesrvm.PrintLN out) {
091 if (method != null) {
092 // print name of native method
093 out.print("\tat ");
094 out.print(method.getDeclaringClass());
095 out.print(".");
096 out.print(method.getName());
097 out.println(" (native method)");
098 } else {
099 out.println("\tat <native method>");
100 }
101 }
102
103 public void set(StackBrowser browser, Offset instr) {
104 browser.setBytecodeIndex(-1);
105 browser.setCompiledMethod(this);
106 browser.setMethod(method);
107 }
108 }