EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.services.bytecode]

COVERAGE SUMMARY FOR SOURCE FILE [BCJava.java]

nameclass, %method, %block, %line, %
BCJava.java100% (1/1)100% (8/8)66%  (90/137)74%  (29/39)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BCJava100% (1/1)100% (8/8)66%  (90/137)74%  (29/39)
BCJava (): void 100% (1/1)100% (3/3)100% (2/2)
boot (boolean, Properties): void 100% (1/1)100% (13/13)100% (3/3)
newCacheable (CacheManager): Cacheable 100% (1/1)100% (4/4)100% (1/1)
newClassBuilder (ClassFactory, String, int, String, String): ClassBuilder 100% (1/1)100% (10/10)100% (1/1)
stop (): void 100% (1/1)100% (1/1)100% (1/1)
type (String): Type 100% (1/1)44%  (16/36)50%  (4/8)
vmType (BCMethodDescriptor): String 100% (1/1)55%  (17/31)62%  (5/8)
vmTypeId (String): short 100% (1/1)67%  (26/39)80%  (12/15)

1/*
2 
3   Derby - Class org.apache.derby.impl.services.bytecode.BCJava
4 
5   Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.services.bytecode;
22 
23import org.apache.derby.iapi.services.compiler.JavaFactory;
24import org.apache.derby.iapi.services.compiler.ClassBuilder;
25import org.apache.derby.iapi.services.compiler.MethodBuilder;
26import org.apache.derby.iapi.services.loader.ClassFactory;
27import org.apache.derby.iapi.services.classfile.ClassHolder;
28 
29import org.apache.derby.iapi.services.cache.Cacheable;
30import org.apache.derby.iapi.services.cache.CacheableFactory;
31 
32import org.apache.derby.iapi.services.cache.CacheFactory;
33import org.apache.derby.iapi.services.cache.CacheManager;
34 
35import org.apache.derby.iapi.services.monitor.Monitor;
36import org.apache.derby.iapi.services.monitor.ModuleControl;
37 
38import org.apache.derby.iapi.error.StandardException;
39 
40import org.apache.derby.iapi.services.sanity.SanityManager;
41 
42import org.apache.derby.iapi.services.classfile.VMDescriptor;
43 
44import java.util.Properties;
45import java.util.Hashtable;
46 
47/**
48        <p>
49        <b>Debugging problems with generated classes</b>
50        <p>
51        When the code has been generated incorrectly, all sorts of
52        odd things can go wrong.  This is one recommended approach to
53        finding the problem.
54        <p>
55        First, turn on ByteCodeGenInstr and DumpClassFile. Look
56        for missing files (right now they are consecutively numbered
57        by the activation class builder; later on they won't be, but
58        BytCodeGenInstr dumps messages about the classes it has).
59        Look at the log to make sure that all "GEN starting class/method"
60        messages are paired with a "GEN ending class/method" message.
61        If a file is missing or the pairing is missing, then something
62        went wrong when the system tried to generate the bytecodes.
63        Resort to your favorite debugging tool to step through
64        the faulty statement.
65        <p>
66        If you get class files but the system crashes on you (I had
67        an OS segmentation fault once) or you get funny messages like
68        JDBC Excpetion: ac5 where ac5 is just the name of a generated
69        class, then one of the following is likely:
70        <ul>
71        <li> you are calling INVOKEVIRTUAL when
72             you are supposed to call INVOKEINTERFACE
73        <li> you have an inexact match on a method argument or
74             return type.
75        <li> you are trying to get to a superclass's field using
76             a subclass.
77        </ul>
78        The best way to locate the problem here is to do this (replace
79        ac5.class with the name of your class file):
80        <ol>
81        <li> javap -c -v ac5 >ac5.gp<br>
82                 if javap reports "Class not found", and the file ac5.class does
83                 exist in the current directory, then the .class file is probably
84                 corrupt.  Try running mocha on it to see if that works. The
85                 problem will be in the code that generates the entries for
86                 the class file -- most likely the ConstantPool is bad, an
87                 attribute got created incorrectly, or
88                 perhaps the instruction streams are goofed up.
89        <li> java mocha.Decompiler ac5.class<br>
90             if mocha cannot create good java source, then you really
91             need to go back and examine the calls creating the java 
92             constructs; a parameter might have been null when it should
93             have, a call to turn an expression into a statement may be
94             missing, or something else may be wrong.
95        <li> mv ac5.mocha ac5.java
96        <li> vi ac5.java ; you will have to fix any new SQLBoolean(1, ...)
97             calls to be new SQLBoolean(true, ...).  Also mocha 
98             occasionally messes up other stuff too.  Just iterate on it
99             until it builds or you figure out what is wrong with
100             the generated code.
101        <li> javac ac5.java
102        <li> javap -v -c ac5 >ac5.jp
103        <li> sed '1,$s/#[0-9]* </# </' ac5.gp > ac5.gn
104        <li> sed '1,$s/#[0-9]* </# </' ac5.jp > ac5.jn<br>
105             These seds are to get rid of constant pool entry numbers,
106             which will be wildly different on the two files.
107        <li> vdiff32 ac5.gn ac5.jn<br>
108             this tool shows you side-by-side diffs.  If you change
109             to the window that interleaves the diffs, you can see the 
110             length of the line.  Look for places where there are
111             invokevirtual vs. invokeinterface differences, differences
112             in the class name of a field, differences in the class name
113             of a method parameter or return type.  The generated code
114             *will* have some unavoidable differences from the
115             compiled code, such as:
116             <ul>
117             <li> it will have goto's at the end of try blocks
118                  rather than return's.
119             <li> it will do a getstatic on a static final field
120                  rather than inlining the static final field's value
121             <li> it will have more checkcast's in it, since it
122                  doesn't see if the checkcast will always succeed
123                  and thus remove it.
124             </ul>
125             Once you find a diff, you need to track down where
126             the call was generated and modify it appropriately:
127             change newMethodCall to newInterfaceMethodCall;
128             add newCastExpression to get a argument into the right
129             type for the parameter; ensure the return type given for
130             the method is its declared return type.
131        </ol>
132        @see org.apache.derby.iapi.services.compiler.JavaFactory
133 
134        @author ames
135 */
136public class BCJava implements JavaFactory, CacheableFactory, ModuleControl {
137 
138        //////////////////////////////////////////////////////////////
139        //  
140        //        MEMBERS
141        //
142        //////////////////////////////////////////////////////////////
143 
144        /* Cache of Java class names versus VM type names */
145        private CacheManager        vmTypeIdCache;
146 
147        //
148        // class interface
149        //
150        public BCJava() {
151        }
152 
153        //
154        // ModuleControl interface
155        //
156        /**
157                Start this module. We need a read/write version of the class utilities
158 
159                @exception StandardException standard cloudscape policy
160         */
161        public void boot(boolean create, Properties properties) throws StandardException {
162 
163                CacheFactory cf =
164                        (CacheFactory) Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.CacheFactory);
165 
166                /*
167                ** The initial and maximum cache sizes are based on experiments
168                ** that I did with some of the language tests.  I found that
169                ** the size quickly grew to about 40, then continued to grow
170                ** slowly after that.
171                **
172                **                        -        Jeff
173                */
174                vmTypeIdCache =
175                        cf.newCacheManager(
176                                this,
177                                "VMTypeIdCache",
178                                64,
179                                256);
180        }
181 
182        /**
183                Stop this module.  In this case, nothing needs to be done.
184         */
185        public void stop() {
186        }
187 
188        //
189        // JavaFactory interface
190        //
191 
192        /**
193         * a class.  Once it is created, fields, methods,
194         * interfaces, static initialization code, 
195         * and constructors can be added to it.
196         * <verbatim>
197           Java: package #packageName;
198                   #modifiers #className extends #superClass { }
199                          // modifiers is the | of the JVM constants for
200                          // the modifiers such as static, public, etc.
201           </verbatim>
202         *
203         * See java.lang.reflect.Modifiers
204         * @param packageName the name of the package the class is in.
205         *        null if it is in the default package.
206         * @param modifiers the | of the Modifiers
207         *        constants representing the visibility and control of this
208         *        method.
209         * @param className the name of the class or interface
210         * @param superClass the name of the superclass or superinterface
211         *
212         * @return the class builder.
213         */
214        public ClassBuilder newClassBuilder(ClassFactory cf, String packageName,
215                int modifiers, String className, String superClass) {
216                
217                return new BCClass(cf, packageName, modifiers, className, superClass, this);
218        }
219 
220        /*
221        ** CacheableFactory interface
222        */
223        public Cacheable newCacheable(CacheManager cm) {
224                return new VMTypeIdCacheable();
225        }
226 
227        ///////////////////////////////////////////
228        //
229        // UTILITIES specific to this implementation
230        //
231        ////////////////////////////////////////////
232 
233        /**
234         * Get the VM Type ID that corresponds with the given java type name.
235         * This uses the cache of VM type ids.
236         *
237         * @param javaType        The java type name to translate to a java VM type id
238         *
239         * @return                The java VM type ID
240         */
241        Type type(String javaType) {
242 
243                Type retval;
244 
245                try {
246 
247                        VMTypeIdCacheable vtic = (VMTypeIdCacheable) vmTypeIdCache.find(javaType);
248 
249                        retval = (Type) vtic.descriptor();
250 
251                        vmTypeIdCache.release(vtic);
252 
253                        return retval;
254 
255                } catch (StandardException se) {
256                        if (SanityManager.DEBUG) {
257                                SanityManager.THROWASSERT("Unexpected exception " + se, se);
258                        }
259 
260                        /*
261                        ** If we're running a sane server, let's act as if the
262                        ** exception didn't happen, and just get the vmTypeId the
263                        ** slow way, without caching.
264                        */
265                        retval = new Type(javaType, ClassHolder.convertToInternalDescriptor(javaType));
266                }
267 
268                return retval;
269        }
270 
271        String vmType(BCMethodDescriptor md) {
272                String retval;
273 
274                try {
275 
276                        VMTypeIdCacheable vtic = (VMTypeIdCacheable) vmTypeIdCache.find(md);
277 
278                        retval = vtic.descriptor().toString();
279 
280                        vmTypeIdCache.release(vtic);
281 
282                } catch (StandardException se) {
283                        if (SanityManager.DEBUG) {
284                                SanityManager.THROWASSERT("Unexpected exception " + se, se);
285                        }
286 
287                        /*
288                        ** If we're running a sane server, let's act as if the
289                        ** exception didn't happen, and just get the vmTypeId the
290                        ** slow way, without caching.
291                        */
292                        retval = md.buildMethodDescriptor();
293                }
294 
295                return retval;
296        }
297        /**
298         * Map vm types as strings to vm types as the VM
299         * handles, with int ids. Used in mapping opcodes
300         * based on type of operand/stack entry available.
301         */
302        static short vmTypeId(String vmTypeS) {
303                char vmTypeC = vmTypeS.charAt(0);
304                switch(vmTypeC) {
305                        case VMDescriptor.C_CLASS : return BCExpr.vm_reference;
306                        case VMDescriptor.C_BYTE : return BCExpr.vm_byte;
307                        case VMDescriptor.C_CHAR : return BCExpr.vm_char;
308                        case VMDescriptor.C_DOUBLE : return BCExpr.vm_double;
309                        case VMDescriptor.C_FLOAT : return BCExpr.vm_float;
310                        case VMDescriptor.C_INT : return BCExpr.vm_int;
311                        case VMDescriptor.C_LONG : return BCExpr.vm_long;
312                        case VMDescriptor.C_SHORT : return BCExpr.vm_short;
313                        case VMDescriptor.C_BOOLEAN : return BCExpr.vm_int;
314                        case VMDescriptor.C_ARRAY : return BCExpr.vm_reference;
315                        case VMDescriptor.C_VOID : return BCExpr.vm_void;
316                        default: 
317                                if (SanityManager.DEBUG)
318                                SanityManager.THROWASSERT("No type match for "+vmTypeS);
319                }
320                return BCExpr.vm_void;
321        }
322}

[all classes][org.apache.derby.impl.services.bytecode]
EMMA 2.0.5312 (C) Vladimir Roubtsov