Closed Bug 201893 Opened 22 years ago Closed 21 years ago

Too slow invocation of reflected methods for package-private classes

Categories

(Rhino Graveyard :: Core, enhancement)

enhancement
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: igor, Assigned: norrisboyd)

Details

Attachments

(1 file, 1 obsolete file)

Steven Beal wrote to me some time ago: -------- Original Message -------- Subject: Rhino performance tip (FAQ recommendation) Date: Fri, 28 Feb 2003 10:20:34 -0800 From: Steven Beal <steven.beal@peregrine.com> To: "Igor Bukanov (E-mail)" <igor@icesoft.com> Igor, I was experiencing poor performance on the IBM virtual machine (the one shipped with Websphere) and eventually traced the problem to excessive throwing and catching of exceptions. The Sun VM handles exceptions much more efficiently and thus does not suffer quite so much from exceptions being thrown and caught in quick succession, which is why I didn't notice the issue before. This is not a bug in rhino, in fact the condition is produced by a workaround for a Sun java bug http://developer.java.sun.com/developer/bugParade/bugs/4071593.html See org.mozilla.javascript.NativeJavaMethod.retryIllegalAccessInvoke(). The pattern used here is the same as that shown in one of the annotations of the currently open incarnation of the same bug http://developer.java.sun.com/developer/bugParade/bugs/4071957.html This bug is not limited to inner classes though. It will also manifest itself why trying to invoke via reflection a method on a pkg. private class offered via an Interface. I place several references into the local scope created for a request that are interface references to pkg. private classes created via an Abstract Factory pattern. By making these classes public I avoided the need for the bug workaround and improved performance significantly (a necessary compromise). Perhaps some mention of this should be made in the FAQ since the performance impact is significant (extremely so on the IBM VM). The same problem would be seen when using Dynamic Proxies, and features of the Collection classes. If you read through the associated bug reports I'm sure you will find more cases. Regards, -Steve
I think besides documentation it could be possible to do something with Rhino code as well. If on the first failed method invocation code would search for a public method in a class public super classes or interfaces which this method overrides, then the issue can be solved.
The reason for performance problem is that the above NativeJavaMethod.retryIllegalAccessInvoke() does not cache the accessible method it found. Thus the idea is to replace on the first IllegalAccessException the original method in NativeJavaMethod.methods by its accessible version so the following invocations would not throw IllegalAccessException. It would be simple to modify retryIllegalAccessInvoke if only NativeJavaMethod used it, but the same problem presents with JavaMembers.BeanProperty.setter/getter and I would like not to repeat the same code there twice. To resolve this, I replaced Method references in BeanProperty by references to NativeJavaMethod together with method indexes since previously BeanProperty was created from NativeJavaMethod in any case. In this way single invoke utility in NativeJavaMethod would be sufficient and if a getter method is called both directly and through a property access, it will be replaced only one time. In addition, it allowed not to call Method.getPrametersInfo() on setter during its invocation since this information is already cached in NativeJavaMethod.
Note for the above patch: it depends essentially on my chages to cache Method.getParameterInfo() in NativeJavaMethod/NativeJavaConstructor that I put to CVS on 2003-07-06.
The patch moved all logic to recover from IllegalArgumentException to new MemberBox class that wraps Method or Constructor instances. The class also cache results of getParameterTyps() and implements Serializable. The later allows to skip implementing read/writeObject when class previously contained Method or Constructor instances which are replaced by MemeberBox wrappers.
Attachment #127127 - Attachment is obsolete: true
I committed the patch. Steven does not have time to verify that now but perhaps later he can test.
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
I think there are some problems with the patch you committed. I'm no longer able to invoke public methods on non-public classes. The error message I get is: TypeError: undefined is not a function. Which may serve as clue, because it's not that we get a security exception when invoking the method, the method is simply not there. Also, when trying to invoke a public static method on a non-public class, I get the following message: org.mozilla.javascript.EvaluatorException: Java class "java.lang.Object" has no public instance field or method named "foo". Should I open a new bug for this, or will this one be reopened?
Please open a new bug, since it is a different issue.
I openned the bug 214608 about the problem reported in the comments 6
Targeting as resolved against 1.5R5
Target Milestone: --- → 1.5R5
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: