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