The Artima Developer Community
Sponsored Link

Java Buzz Forum
ActualAccessFlags: an undocumented .class format attribute

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Vlad Roubtsov

Posts: 20
Nickname: vladr
Registered: May, 2003

Vlad Roubtsov is a Java Q&A columnist for JavaWorld
ActualAccessFlags: an undocumented .class format attribute Posted: Jul 29, 2003 9:58 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Vlad Roubtsov.
Original Post: ActualAccessFlags: an undocumented .class format attribute
Feed Title: Java Curiosity Shop
Feed URL: http://www.blog-city.com/bc/
Feed Description: Java esoterics: things from "don't try this at home" category
Latest Java Buzz Posts
Latest Java Buzz Posts by Vlad Roubtsov
Latest Posts From Java Curiosity Shop

Advertisement
A comment on “synthetic accessor method” issue for the curious.Recently ADVANCED-JAVA and Eclipse jdt-dev had discussions about a somewhat confusing warning that Eclipse compiler generates when you have a nested class referencing a private outer class field:  Write access to enclosing field Outer.s_field2 is emulated by a synthetic accessor method. Increasing its visibility will improve your performance This warning is disabled by default but can be seen when you set “Access to a non-accessible member of an enclosing type” style setting in the compiler options to anything other than “Ignore”. As an example, it would be generated for s_field2 but not s_field1 below:public class Outer { private static class Nested { static void foo () { s_field1 = 1; s_field2 = -1; } } // end of nested class static int s_field1; static private int s_field2; } // end of class The explanation for this is pretty simple. Static nested and inner classes are compiled into separate .class files (with OuterClassName$NestedClassName.class naming scheme). In fact, as far as the JVM is concerned, they are completely separate classes. The only thing they have in common with their outer parents is they are always in the same package (which is not a lot).Syntactically, nested classes have access to all private internals of their enclosing classes, including private fields. But this does not work at the bytecode level: Nested.foo() cannot reference s_field2 with a direct get/putstatic or get/putfield bytecode instruction. Instead, the compiler generates a package-private accessor method in Nested with a mechanically generated name like access$<some number>. This potentially slows down access and hence you get the warning.public class Outer extends java.lang.Object { static int s_field1; private static int s_field2; public Outer(); static void access$0(int); private static class Outer. Nested extends java.lang.Object /* ACC_SUPER bit NOT set */ { Outer.Nested(); static void foo(); } Method Outer. Nested() 0 aload_0 1 invokespecial #9 4 return Method void foo() 0 iconst_1 1 putstatic #20 4 iconst_m1 5 invokestatic #24 8 return } Method Outer() 0 aload_0 1 invokespecial #12 4 return Method void access$0(int) 0 iload_0 1 putstatic #20 4 return Some people believe that this is not a cause for concern because the generated accessor is still inlinable as most other getters/setters. However, it is not clear why this method is not made final which would have made such an optimization more certain. Furthermore, the synthetic method is package-private and is a potential security loophole. Making the field in question package-private eliminates the issue, in most cases without major design ramifications.Now the esoteric part. Things were not always like that. If you had the same morbid interest in bytecode back in Java 1.1 as I did you might have known that Microsoft’s compiler supported nested classes without using any synthetic accessors. Here is a javap dump when the same code is compiled using jvc:public class Outer extends java.lang.Object { static int s_field1; static int s_field2; public Outer(); private static class Outer. Nested extends java.lang.Object { Outer.Nested(); static void foo(); } Method Outer. Nested() 0 aload_0 1 invokespecial #16 4 return Method void foo() 0 iconst_1 1 putstatic #20 4 iconst_m1 5 putstatic #23 8 return } Method Outer() 0 aload_0 1 invokespecial #12 4 return There are three differences. #1: no accessor method anymore. Can you see the other differences? s_field2 is now package-private and is being accessed directly (no invokestatic)! Yes, the compiler cheated behind your back and made the field more public that you intended in the source code! Additionally the compiler emits an undocumented field attribute called ActualAccessFlags that (I believe) contains the original access flags for the field. I believe early javac versions (for JDK 1.1.x) did something similar when you used –O flag.javap will not show you this attribute. I discovered it because I have my own javap-like tool I use to examine bytecode (I work on a bytecode coverage tool in my spare time and Sun’s javap just does not cut it in many cases). You will not find any documentation on this attribute anywhere. It is just a Java oddity at this point. ... more constant pool entries ... [19] CONSTANT_Utf8: I [20] CONSTANT_Utf8: s_field2 [21] CONSTANT_Utf8: ActualAccessFlags ------------------------------------------------------------------------ number of superinterfaces: 0 ------------------------------------------------------------------------ number of declared fields: 2 static s_field1: I 0 attribute(s): static s_field2: I 1 attribute(s): ActualAccessFlags [generic]: name @21, length = 8 ... The upshot: I am not sure I understand why Java 2 compilers from Sun and IBM went the synthetic accessor route. They could have used the same old trick of adjusting field access level. It’s the same security hole, but the performance wouldn’t suffer. I guess the new accessor solution supports separate compilation better.

Read: ActualAccessFlags: an undocumented .class format attribute

Topic: From the Aren't We All Deptartment: Previous Topic   Next Topic Topic: MoonBuzz Progress MIDP1.0 Core

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use