PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/rvm/src/org/jikesrvm/compilers/baseline/ppc/BaselineGCMapIterator.java

https://github.com/joekoolade/JEI
Java | 269 lines | 177 code | 33 blank | 59 comment | 41 complexity | 38c649c76f538b0609fa120ea2d2b753 MD5 | raw file
  1. /*
  2. * This file is part of the Jikes RVM project (http://jikesrvm.org).
  3. *
  4. * This file is licensed to You under the Eclipse Public License (EPL);
  5. * You may not use this file except in compliance with the License. You
  6. * may obtain a copy of the License at
  7. *
  8. * http://www.opensource.org/licenses/eclipse-1.0.php
  9. *
  10. * See the COPYRIGHT.txt file distributed with this work for information
  11. * regarding copyright ownership.
  12. */
  13. package org.jikesrvm.compilers.baseline.ppc;
  14. import static org.jikesrvm.ppc.BaselineConstants.FIRST_FIXED_LOCAL_REGISTER;
  15. import static org.jikesrvm.ppc.BaselineConstants.FIRST_FLOAT_LOCAL_REGISTER;
  16. import static org.jikesrvm.ppc.RegisterConstants.FIRST_VOLATILE_FPR;
  17. import static org.jikesrvm.ppc.RegisterConstants.FIRST_VOLATILE_GPR;
  18. import static org.jikesrvm.ppc.RegisterConstants.LAST_NONVOLATILE_FPR;
  19. import static org.jikesrvm.ppc.RegisterConstants.LAST_NONVOLATILE_GPR;
  20. import static org.jikesrvm.runtime.JavaSizeConstants.BYTES_IN_DOUBLE;
  21. import static org.jikesrvm.runtime.JavaSizeConstants.LOG_BYTES_IN_DOUBLE;
  22. import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS;
  23. import org.jikesrvm.VM;
  24. import org.jikesrvm.classloader.NormalMethod;
  25. import org.jikesrvm.compilers.baseline.AbstractBaselineGCMapIterator;
  26. import org.jikesrvm.compilers.common.CompiledMethod;
  27. import org.jikesrvm.runtime.Magic;
  28. import org.vmmagic.pragma.Uninterruptible;
  29. import org.vmmagic.unboxed.Address;
  30. import org.vmmagic.unboxed.AddressArray;
  31. import org.vmmagic.unboxed.Offset;
  32. /**
  33. * Iterator for stack frame built by the Baseline compiler.<p>
  34. *
  35. * An Instance of this class will iterate through a particular
  36. * reference map of a method returning the offsets of any references
  37. * that are part of the input parameters, local variables, and
  38. * java stack for the stack frame.
  39. */
  40. @Uninterruptible
  41. public final class BaselineGCMapIterator extends AbstractBaselineGCMapIterator {
  42. /** Compiled method for the frame */
  43. protected ArchBaselineCompiledMethod currentCompiledMethod;
  44. public BaselineGCMapIterator(AddressArray registerLocations) {
  45. super(registerLocations);
  46. bridgeData = new ArchBridgeDataExtractor();
  47. }
  48. /**
  49. * Set the iterator to scan the map at the machine instruction offset
  50. * provided. The iterator is positioned to the beginning of the map. NOTE: An
  51. * iterator may be reused to scan a different method and map.
  52. *
  53. * @param compiledMethod
  54. * identifies the method and class
  55. * @param instructionOffset
  56. * identifies the map to be scanned.
  57. * @param fp
  58. * identifies a specific occurrance of this method and allows for
  59. * processing instance specific information i.e JSR return address
  60. * values
  61. */
  62. @Override
  63. public void setupIterator(CompiledMethod compiledMethod, Offset instructionOffset, Address fp) {
  64. currentCompiledMethod = (ArchBaselineCompiledMethod) compiledMethod;
  65. currentMethod = (NormalMethod) compiledMethod.getMethod();
  66. currentNumLocals = currentMethod.getLocalWords();
  67. // setup superclass
  68. //
  69. framePtr = fp;
  70. // setup stackframe mapping
  71. //
  72. mapReader.setMethod(currentMethod, compiledMethod);
  73. mapReader.locateGCPoint(instructionOffset);
  74. if (mapReader.currentMapIsForJSR()) {
  75. mapReader.acquireLockForJSRProcessing();
  76. int JSRindex = mapReader.setupJSRSubroutineMap();
  77. while (JSRindex != 0) {
  78. Address nextCallerAddress;
  79. short location = convertIndexToLocation(JSRindex);
  80. if (BaselineCompilerImpl.isRegister(location)) {
  81. nextCallerAddress = registerLocations.get(location);
  82. } else {
  83. nextCallerAddress =
  84. framePtr.plus(BaselineCompilerImpl.locationToOffset(location) -
  85. BYTES_IN_ADDRESS); //location offsets are positioned on top of stackslot
  86. }
  87. nextCallerAddress = nextCallerAddress.loadAddress();
  88. Offset nextMachineCodeOffset = compiledMethod.getInstructionOffset(nextCallerAddress);
  89. if (VM.TraceStkMaps) {
  90. traceSetupJSRsubroutineMap(JSRindex, nextCallerAddress, nextMachineCodeOffset);
  91. }
  92. JSRindex = mapReader.getNextJSRAddressIndex(nextMachineCodeOffset);
  93. }
  94. }
  95. if (VM.TraceStkMaps || TRACE_ALL) {
  96. VM.sysWrite("BaselineGCMapIterator setupIterator mapId = ");
  97. VM.sysWrite(mapReader.getMapId());
  98. VM.sysWrite(" for ");
  99. VM.sysWrite(currentMethod);
  100. VM.sysWriteln(".");
  101. }
  102. bridgeData.setupDynamicBridgeMapping(currentMethod, fp);
  103. reset();
  104. }
  105. @Override
  106. protected void resetArchitectureSpecificBridgeSState() {
  107. bridgeData.resetBridgeRegisterIndex();
  108. bridgeData.setBridgeRegisterLocation(framePtr.loadAddress());
  109. // point to first saved gpr
  110. bridgeData.decBrigeRegisterLocation(BYTES_IN_DOUBLE * (LAST_NONVOLATILE_FPR.value() - FIRST_VOLATILE_FPR.value() + 1) +
  111. BYTES_IN_ADDRESS * (LAST_NONVOLATILE_GPR.value() - FIRST_VOLATILE_GPR.value() + 1));
  112. // get to my caller's frameptr and then walk up to the spill area
  113. Address callersFP = Magic.getCallerFramePointer(framePtr);
  114. bridgeData.resetBridgeSpilledParamLocation(callersFP);
  115. }
  116. /**
  117. * given a index in the local area (biased : local0 has index 1)
  118. * this routine determines the correspondig offset in the stack
  119. */
  120. public short convertIndexToLocation(int index) {
  121. if (index == 0) return 0;
  122. if (index <= currentNumLocals) { //index is biased by 1;
  123. //register (positive value) or stacklocation (negative value)
  124. return currentCompiledMethod.getGeneralLocalLocation(index - 1);
  125. } else {
  126. //locations must point to the top of the slot
  127. return currentCompiledMethod.getGeneralStackLocation(index - 1 - currentNumLocals);
  128. }
  129. }
  130. @Override
  131. public Address getNextReferenceAddress() {
  132. if (!mapReader.isFinishedWithRegularMap()) {
  133. mapReader.updateMapIndex();
  134. if (VM.TraceStkMaps || TRACE_ALL) {
  135. VM.sysWrite("BaselineGCMapIterator getNextReferenceIndex = ");
  136. VM.sysWrite(mapReader.getMapIndex());
  137. VM.sysWriteln(".");
  138. if (mapReader.currentMapIsForJSR()) {
  139. VM.sysWriteln("Index is a JSR return address ie internal pointer.");
  140. }
  141. }
  142. if (mapReader.currentMapHasMorePointers()) {
  143. short location = convertIndexToLocation(mapReader.getMapIndex());
  144. if (VM.TraceStkMaps || TRACE_ALL) {
  145. VM.sysWrite("BaselineGCMapIterator getNextReference location = ");
  146. VM.sysWrite(location);
  147. VM.sysWriteln();
  148. }
  149. if (BaselineCompilerImpl.isRegister(location)) {
  150. return registerLocations.get(location);
  151. } else {
  152. return framePtr.plus(BaselineCompilerImpl.locationToOffset(location) -
  153. BYTES_IN_ADDRESS); //location offsets are positioned on top of stackslot
  154. }
  155. } else {
  156. // remember that we are done with the map for future calls, and then
  157. // drop down to the code below
  158. mapReader.setFinishedWithRegularMap();
  159. }
  160. }
  161. if (bridgeData.isBridgeParameterMappingRequired()) {
  162. if (bridgeData.needsBridgeRegisterLocationsUpdate()) {
  163. // point registerLocations[] to our callers stackframe
  164. //
  165. Address location = framePtr.plus(currentCompiledMethod.getFrameSize());
  166. location = location.minus((LAST_NONVOLATILE_FPR.value() - FIRST_VOLATILE_FPR.value() + 1) * BYTES_IN_DOUBLE);
  167. // skip non-volatile and volatile fprs
  168. for (int i = LAST_NONVOLATILE_GPR.value(); i >= FIRST_VOLATILE_GPR.value(); --i) {
  169. location = location.minus(BYTES_IN_ADDRESS);
  170. registerLocations.set(i, location);
  171. }
  172. bridgeData.setBridgeRegistersLocationUpdated();
  173. }
  174. if (bridgeData.hasUnprocessedImplicitThis()) {
  175. return bridgeData.getImplicitThisAddress();
  176. }
  177. // now the remaining parameters
  178. //
  179. while (bridgeData.hasMoreBridgeParameters()) {
  180. return bridgeData.getNextBridgeParameterAddress();
  181. }
  182. }
  183. return Address.zero();
  184. }
  185. @Override
  186. public Address getNextReturnAddressAddress() {
  187. if (!mapReader.currentMapIsForJSR()) {
  188. if (VM.TraceStkMaps || TRACE_ALL) {
  189. traceMapIdForGetNextReturnAddressAddress();
  190. }
  191. return Address.zero();
  192. }
  193. mapReader.updateMapIndexWithJSRReturnAddrIndex();
  194. if (VM.TraceStkMaps || TRACE_ALL) {
  195. VM.sysWrite("BaselineGCMapIterator getNextReturnAddressIndex = ");
  196. VM.sysWrite(mapReader.getMapIndex());
  197. VM.sysWriteln(".");
  198. }
  199. if (!mapReader.currentMapHasMorePointers()) return Address.zero();
  200. short location = convertIndexToLocation(mapReader.getMapIndex());
  201. if (VM.TraceStkMaps || TRACE_ALL) {
  202. VM.sysWrite("BaselineGCMapIterator getNextReturnAddress location = ");
  203. VM.sysWrite(location);
  204. VM.sysWriteln(".");
  205. }
  206. if (BaselineCompilerImpl.isRegister(location)) {
  207. return registerLocations.get(location);
  208. } else {
  209. return framePtr.plus(BaselineCompilerImpl.locationToOffset(location) -
  210. BYTES_IN_ADDRESS); //location offsets are positioned on top of stackslot
  211. }
  212. }
  213. @Override
  214. public void cleanupPointers() {
  215. // Make sure that the registerLocation array is updated with the
  216. // locations where this method cached its callers registers.
  217. // [[Yuck. I hate having to do this here, but it seems to be the
  218. // only safe way to do this...]]
  219. updateCallerRegisterLocations();
  220. super.cleanupPointers();
  221. }
  222. private void updateCallerRegisterLocations() {
  223. //dynamic bridge's registers already restored by calls to getNextReferenceAddress()
  224. if (!currentMethod.getDeclaringClass().hasDynamicBridgeAnnotation()) {
  225. if (VM.TraceStkMaps || TRACE_ALL) VM.sysWriteln(" Update Caller RegisterLocations");
  226. Address addr = framePtr.plus(currentCompiledMethod.getFrameSize());
  227. addr =
  228. addr.minus((currentCompiledMethod.getLastFloatStackRegister() - FIRST_FLOAT_LOCAL_REGISTER.value() + 1) <<
  229. LOG_BYTES_IN_DOUBLE); //skip float registers
  230. for (int i = currentCompiledMethod.getLastFixedStackRegister(); i >= FIRST_FIXED_LOCAL_REGISTER.value(); --i) {
  231. addr = addr.minus(BYTES_IN_ADDRESS);
  232. registerLocations.set(i, addr);
  233. }
  234. }
  235. }
  236. }