/libraryInterface/OpenJDK/GPL/src/org/jikesrvm/classlibrary/openjdk/replacements/sun_reflect_Reflection.java

https://github.com/JikesRVM/JikesRVM · Java · 88 lines · 44 code · 12 blank · 32 comment · 6 complexity · 0f12308a38032ce1c5480bef995665a8 MD5 · raw file

  1. /*
  2. * Copyright (c) 2001, 2006, Oracle and/or its affiliates. All rights reserved.
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * This code is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 only, as
  7. * published by the Free Software Foundation. Oracle designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Oracle in the LICENSE file that accompanied this code.
  10. *
  11. * This code is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * version 2 for more details (a copy is included in the LICENSE file that
  15. * accompanied this code).
  16. *
  17. * You should have received a copy of the GNU General Public License version
  18. * 2 along with this work; if not, write to the Free Software Foundation,
  19. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22. * or visit www.oracle.com if you need additional information or have any
  23. * questions.
  24. */
  25. package org.jikesrvm.classlibrary.openjdk.replacements;
  26. import org.jikesrvm.VM;
  27. import org.jikesrvm.classloader.RVMClass;
  28. import org.jikesrvm.classloader.RVMType;
  29. import org.jikesrvm.runtime.StackBrowser;
  30. import org.jikesrvm.scheduler.RVMThread;
  31. import org.vmmagic.pragma.ReplaceClass;
  32. import org.vmmagic.pragma.ReplaceMember;
  33. @ReplaceClass(className = "sun.reflect.Reflection")
  34. public class sun_reflect_Reflection {
  35. private static final boolean DEBUG_GET_CALLER_CLASS = false;
  36. @ReplaceMember
  37. public static Class<?> getCallerClass() {
  38. // TODO OPENJDK/ICEDTEA this implementation is rather messy. If we have to adjust this again,
  39. // we ought to write a better one, with a test case for all the cases.
  40. StackBrowser b = new StackBrowser();
  41. VM.disableGC();
  42. b.init();
  43. b.up(); // skip sun.reflect.Reflection.getCallerClass (this call)
  44. /* Skip Method.invoke and Constructor.newInstance, (if the caller was called by reflection) */
  45. if (b.currentMethodIs_Java_Lang_Reflect_Method_InvokeMethod() || b.currentMethodIs_Java_Lang_Reflect_Constructor_NewInstance()) {
  46. b.up();
  47. }
  48. /* Work around OpenJDK's work around for Reflection.getCallerClass(..) in java.lang.reflect.Method.invoke(..).
  49. * The OpenJDK implementation of getCallerClass assumes a fixed stack depth of 2. The Jikes RVM implementation
  50. * is different so we have to work around OpenJDK's work around */
  51. if (b.currentMethodIs_Java_Lang_Reflect_Method_GetCallerClass()) {
  52. b.up();
  53. }
  54. /* Skip JNI if necessary */
  55. while (b.currentMethodIsPartOfJikesRVMJNIImplementation()) {
  56. b.up();
  57. }
  58. /* Don't skip if we're already in the application */
  59. if (b.currentMethodIsInClassLibrary()) {
  60. b.up(); // skip method that contains the call
  61. }
  62. RVMType ret = b.getCurrentClass();
  63. VM.enableGC();
  64. Class<?> clazz = ret.getClassForType();
  65. if (DEBUG_GET_CALLER_CLASS) {
  66. VM.sysWriteln("Returning caller class " + clazz + " for stack:");
  67. RVMThread.dumpStack();
  68. }
  69. return clazz;
  70. }
  71. @ReplaceMember
  72. private static int getClassAccessFlags(Class c) {
  73. RVMClass clazz = JikesRVMSupport.getTypeForClass(c).asClass();
  74. return clazz.getOriginalModifiers();
  75. }
  76. }