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 * <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 */ 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 @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 @Unpreemptible 092 public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) { 093 return -1; 094 } 095 096 @Override 097 public void printStackTrace(Offset instructionOffset, org.jikesrvm.PrintLN out) { 098 if (method != null) { 099 // print name of native method 100 out.print("\tat "); 101 out.print(method.getDeclaringClass()); 102 out.print("."); 103 out.print(method.getName()); 104 out.println(" (native method)"); 105 } else { 106 out.println("\tat <native method>"); 107 } 108 } 109 110 @Override 111 public void set(StackBrowser browser, Offset instr) { 112 browser.setBytecodeIndex(-1); 113 browser.setCompiledMethod(this); 114 browser.setMethod(method); 115 } 116 }