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.osr; 014 015import org.jikesrvm.VM; 016import org.jikesrvm.architecture.StackFrameLayout; 017import org.jikesrvm.compilers.common.CompiledMethod; 018import org.jikesrvm.compilers.common.CompiledMethods; 019import org.jikesrvm.runtime.Magic; 020import org.jikesrvm.runtime.RuntimeEntrypoints; 021import org.jikesrvm.scheduler.RVMThread; 022import org.jikesrvm.util.PrintContainer; 023import org.vmmagic.unboxed.Address; 024import org.vmmagic.unboxed.Offset; 025 026/** 027 * A ExecutionStateExtractor extracts a runtime state (VM scope descriptor) 028 * of a method activation. The implementation depends on compilers and 029 * hardware architectures.<p> 030 * 031 * It returns a compiler and architecture neutered runtime state 032 * ExecutionState. 033 */ 034public abstract class ExecutionStateExtractor { 035 /** 036 * @param thread a suspended RVM thread 037 * @param tsFromFPoff the frame pointer offset of the threadSwitchFrom method 038 * @param ypTakenFPoff the frame pointer offset of the real method where 039 * yield point was taken. tsFrom is the callee of ypTaken 040 * @param cmid the compiled method id of ypTaken 041 * 042 * @return a VM scope descriptor (ExecutionState) for a compiled method 043 * on the top of a thread stack, (or a list of descriptors for an inlined 044 * method). 045 */ 046 public abstract ExecutionState extractState(RVMThread thread, Offset tsFromFPoff, Offset ypTakenFPoff, int cmid); 047 048 public static void printStackTraces(int[] stack, Offset osrFPoff) { 049 050 VM.disableGC(); 051 052 Address fp = Magic.objectAsAddress(stack).plus(osrFPoff); 053 Address ip = Magic.getReturnAddressUnchecked(fp); 054 fp = Magic.getCallerFramePointer(fp); 055 while (Magic.getCallerFramePointer(fp).NE(StackFrameLayout.getStackFrameSentinelFP())) { 056 int cmid = Magic.getCompiledMethodID(fp); 057 058 if (cmid == StackFrameLayout.getInvisibleMethodID()) { 059 VM.sysWriteln(" invisible method "); 060 } else { 061 CompiledMethod cm = CompiledMethods.getCompiledMethod(cmid); 062 Offset instrOff = cm.getInstructionOffset(ip); 063 cm.printStackTrace(instrOff, PrintContainer.get(System.out)); 064 065 if (cm.getMethod().getDeclaringClass().hasBridgeFromNativeAnnotation()) { 066 fp = RuntimeEntrypoints.unwindNativeStackFrame(fp); 067 } 068 } 069 070 ip = Magic.getReturnAddressUnchecked(fp); 071 fp = Magic.getCallerFramePointer(fp); 072 } 073 074 VM.enableGC(); 075 } 076}