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 */ 013package org.jikesrvm.jni; 014 015import org.jikesrvm.VM; 016import org.jikesrvm.classloader.RVMMethod; 017import org.jikesrvm.classloader.RVMType; 018import org.jikesrvm.compilers.common.CompiledMethod; 019import org.jikesrvm.runtime.DynamicLink; 020import org.jikesrvm.runtime.ExceptionDeliverer; 021import org.jikesrvm.runtime.StackBrowser; 022import org.vmmagic.pragma.Uninterruptible; 023import org.vmmagic.pragma.Unpreemptible; 024import org.vmmagic.unboxed.Offset; 025 026/** 027 * Information associated with artifical stackframe inserted at the 028 * transition from Jave to JNI Native C. 029 * <p> 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 */ 037public 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 @Override 060 @Uninterruptible 061 public int getCompilerType() { 062 return JNI; 063 } 064 065 @Override 066 public String getCompilerName() { 067 return "JNI compiler"; 068 } 069 070 @Override 071 @Uninterruptible 072 public ExceptionDeliverer getExceptionDeliverer() { 073 // this method should never get called on PPC 074 if (VM.VerifyAssertions) VM._assert(VM.BuildForIA32); 075 return deliverer; 076 } 077 078 @Override 079 @Uninterruptible 080 public void getDynamicLink(DynamicLink dynamicLink, Offset instructionOffset) { 081 // this method should never get called. 082 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 083 } 084 085 @Override 086 public boolean isWithinUninterruptibleCode(Offset instructionOffset) { 087 return false; 088 } 089 090 @Override 091 @Uninterruptible 092 public int findLineNumberForInstruction(Offset instructionOffset) { 093 return NATIVE_METHOD_LINE_NUMBER; 094 } 095 096 @Override 097 @Unpreemptible 098 public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) { 099 return -1; 100 } 101 102 @Override 103 public void printStackTrace(Offset instructionOffset, org.jikesrvm.util.PrintLN out) { 104 if (method != null) { 105 // print name of native method 106 out.print("\tat "); 107 out.print(method.getDeclaringClass()); 108 out.print("."); 109 out.print(method.getName()); 110 out.println(" (native method)"); 111 } else { 112 out.println("\tat <native method>"); 113 } 114 } 115 116 @Override 117 public void set(StackBrowser browser, Offset instr) { 118 browser.setBytecodeIndex(-1); 119 browser.setCompiledMethod(this); 120 browser.setMethod(method); 121 } 122}