Bug 11780 - Method.invoke() is slow
Summary: Method.invoke() is slow
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: libgcj (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on: 12475 12740
Blocks: 13603
  Show dependency treegraph
 
Reported: 2003-08-03 06:39 UTC by Bryce McKinlay
Modified: 2016-09-30 22:52 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-08-01 18:37:32


Attachments
Test Case (440 bytes, text/x-java)
2006-03-29 19:00 UTC, Bryce McKinlay
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bryce McKinlay 2003-08-03 06:39:36 UTC
Good performance from Method.invoke() is very important for many reflective applications.

In previous versions of libgcj security checks were not perfomed, and our performance was only a 
little worse than the JRE. A recent patch added security checks and now:

- Method.invoke is now ~10 x slower than the JRE
- Method.invoke leaks memory every time it is called

Clearly there are some simple optimizations that can be made - security check is not needed if 
method is public or accessibility flag is true. Ideally however the security check implementation 
itself should be made much faster.

Test case w/ timers follows.


import java.lang.reflect.*;

public class RefTest2
{
  static int i = 0;
  public int increment(int value)
  {
    return ++i;
  }

  public static void main(String[] args) 
    throws Exception
  {
    Method method = RefTest2.class.getMethod ("increment", 
      new Class [] { int.class });
    Object[] arg = new Object[1];
    Object value = new Integer(0);
  
    RefTest2 testObj = new RefTest2();

    while (true)
    {
      long startTime = System.currentTimeMillis();
      for (int i = 0; i < 1000000; i++)
      {
	arg[0] = value;
	value = method.invoke(testObj, arg);
      }
      System.out.println (System.currentTimeMillis() - startTime + " ms");
    }
  }
}
Comment 1 Andrew Pinski 2003-08-03 14:00:28 UTC
I can confirm the slowness on the mainline (20030802) on powerpc-apple-darwin6.6 but 
I do not see any leaks.
Comment 2 Bryce McKinlay 2003-08-03 21:12:38 UTC
Interesting - the test case consumes all available memory on my 512MB RHL 9 x86 after around 
20M calls. Perhaps the leak is in system-dependent unwinder code.
Comment 3 Andrew Pinski 2003-08-03 21:16:02 UTC
I see the memory leak on i686-pc-linuc-gnu also.
Comment 4 GCC Commits 2003-10-25 06:49:24 UTC
Subject: Bug 11780

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	bryce@gcc.gnu.org	2003-10-25 06:49:20

Modified files:
	libjava        : ChangeLog 
	libjava/java/lang/reflect: natMethod.cc natField.cc 

Log message:
	PR libgcj/11780:
	* java/lang/reflect/natMethod.cc (invoke): Look up caller and
	perform accessibility check only if target is non-public and
	accessible flag is not set.
	* java/lang/reflect/natField.cc (getAddr): Likewise.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.2295&r2=1.2296
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/java/lang/reflect/natMethod.cc.diff?cvsroot=gcc&r1=1.33&r2=1.34
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/java/lang/reflect/natField.cc.diff?cvsroot=gcc&r1=1.14&r2=1.15

Comment 5 Andrew Pinski 2004-01-01 01:24:30 UTC
It still is slow:
tin:~/src/gnu/gcctest>gij RefTest2
1574 ms
1596 ms
tin:~/src/gnu/gcctest>java RefTest2
335 ms
271 ms

But this no longer leaks so update summary.
Comment 6 Tom Tromey 2006-03-29 18:12:55 UTC
Things look even worse with svn head (4.2 atm)...
either with gij or precompiled, the test case shows
invocations about an order of magnitude slower than the JDK.
Comment 7 Bryce McKinlay 2006-03-29 18:59:33 UTC
With a public call, as in the current test case, it is "only" about 2.5X slower than HotSpot for me:

$ ./a.out
public call: 499 ms
private call: 7344 ms
$ java RefTest3
public call: 182 ms
private call: 808 ms

Private calls show a larger difference due to the requirement for an accessibility check, which involves stack inspection. 
Comment 8 Bryce McKinlay 2006-03-29 19:00:46 UTC
Created attachment 11156 [details]
Test Case

New version of the test case, which tests both public and private method invocation.
Comment 9 Andrew Pinski 2016-09-30 22:52:16 UTC
Closing as won't fix as libgcj (and the java front-end) has been removed from the trunk.