< prev index next >

src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this

@@ -23,19 +23,21 @@
   * questions.
   */
  
  package jdk.internal.reflect;
  
- import java.lang.reflect.*;
+ import java.lang.reflect.InvocationTargetException;
+ import java.lang.reflect.Method;
  import jdk.internal.misc.Unsafe;
+ import sun.reflect.misc.ReflectUtil;
  
  /** Used only for the first few invocations of a Method; afterward,
      switches to bytecode-based implementation */
  
  class NativeMethodAccessorImpl extends MethodAccessorImpl {
-      private static final Unsafe U = Unsafe.getUnsafe();
-      private static final long GENERATED_OFFSET
+     private static final Unsafe U = Unsafe.getUnsafe();
+     private static final long GENERATED_OFFSET
          = U.objectFieldOffset(NativeMethodAccessorImpl.class, "generated");
  
      private final Method method;
      private final DelegatingMethodAccessorImpl parent;
      private int numInvocations;

@@ -47,32 +49,51 @@
      }
  
      public Object invoke(Object obj, Object[] args)
          throws IllegalArgumentException, InvocationTargetException
      {
-         // We can't inflate methods belonging to vm-anonymous classes because
-         // that kind of class can't be referred to by name, hence can't be
-         // found from the generated bytecode.
-         if (++numInvocations > ReflectionFactory.inflationThreshold()
-                 && !method.getDeclaringClass().isHidden()
-                 && generated == 0
-                 && U.compareAndSetInt(this, GENERATED_OFFSET, 0, 1)) {
+         boolean generate = false;
+         if (!method.getDeclaringClass().isHidden()) {
+             if (Thread.currentThread().isVirtual()) {
+                 generate = true;
+             } else {
+                 if (++numInvocations > ReflectionFactory.inflationThreshold()
+                         && generated == 0
+                         && U.compareAndSetInt(this, GENERATED_OFFSET, 0, 1)) {
+                     generate = true;
+                 }
+             }
+         }
+ 
+         if (generate) {
+             Class<?> declaringClass = method.getDeclaringClass();
+ 
+             // class initializer may not have run
+             Unsafe.getUnsafe().ensureClassInitialized(declaringClass);
+ 
+             MethodAccessorImpl acc;
              try {
-                 MethodAccessorImpl acc = (MethodAccessorImpl)
-                     new MethodAccessorGenerator().
-                         generateMethod(method.getDeclaringClass(),
-                                        method.getName(),
-                                        method.getParameterTypes(),
-                                        method.getReturnType(),
-                                        method.getExceptionTypes(),
-                                        method.getModifiers());
-                 parent.setDelegate(acc);
+                 // use bytecode generated implementation for @CS methods for now
+                 if (Reflection.isCallerSensitive(method)) {
+                     acc = (MethodAccessorImpl) new MethodAccessorGenerator()
+                                 .generateMethod(declaringClass,
+                                                 method.getName(),
+                                                 method.getParameterTypes(),
+                                                 method.getReturnType(),
+                                                 method.getExceptionTypes(),
+                                                 method.getModifiers());
+                 } else {
+                     acc = NewAccessorImplFactory.newMethodAccessorImpl(method);
+                 }
              } catch (Throwable t) {
-                 // Throwable happens in generateMethod, restore generated to 0
+                 // generateMethod failed, restore generated to 0
                  generated = 0;
                  throw t;
              }
+ 
+             parent.setDelegate(acc);
+             return acc.invoke(obj, args);
          }
  
          return invoke0(method, obj, args);
      }
  
< prev index next >