1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/*
17 * Common subroutines and data.
18 */
19
20/*
21 * Common code when a backwards branch is taken
22 *
23 * On entry:
24 *   ebx (a.k.a. rINST_FULL) -> PC adjustment in 16-bit words
25 */
26common_backwardBranch:
27    GET_GLUE(%ecx)
28    call   common_periodicChecks  # Note: expects rPC to be preserved
29    ADVANCE_PC_INDEXED(rINST_FULL)
30    FETCH_INST()
31    GOTO_NEXT
32
33
34
35/*
36 * Common code for method invocation with range.
37 *
38 * On entry:
39 *   eax = Method* methodToCall
40 *   rINST trashed, must reload
41 */
42
43common_invokeMethodRange:
44.LinvokeNewRange:
45
46   /*
47    * prepare to copy args to "outs" area of current frame
48    */
49
50    movzbl      1(rPC),rINST_FULL       # rINST_FULL<- AA
51    movzwl      4(rPC), %ecx            # %ecx<- CCCC
52    SPILL(rPC)
53    SAVEAREA_FROM_FP(%edx,rFP)          # %edx<- &StackSaveArea
54    test        rINST_FULL, rINST_FULL
55    movl        rINST_FULL, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
56    jz          .LinvokeArgsDone        # no args; jump to args done
57
58
59   /*
60    * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, %edx=&outs (&stackSaveArea)
61    * (very few methods have > 10 args; could unroll for common cases)
62    */
63
64    movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
65    lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
66    shll        $$2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
67    subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
68    shrl        $$2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
691:
70    movl        (%ecx), %ebx            # %ebx<- vCCCC
71    lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
72    subl        $$1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
73    movl        %ebx, (%edx)            # *outs<- vCCCC
74    lea         4(%edx), %edx           # outs++
75    jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
76    movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
77    jmp         .LinvokeArgsDone        # continue
78
79   /*
80    * %eax is "Method* methodToCall", the method we're trying to call
81    * prepare to copy args to "outs" area of current frame
82    */
83
84common_invokeMethodNoRange:
85.LinvokeNewNoRange:
86    movzbl      1(rPC),rINST_FULL       # rINST_FULL<- BA
87    SPILL(rPC)
88    movl        rINST_FULL, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
89    shrl        $$4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
90    je          .LinvokeArgsDone        # no args; jump to args done
91    movzwl      4(rPC), %ecx            # %ecx<- GFED
92    SAVEAREA_FROM_FP(%edx,rFP)          # %edx<- &StackSaveArea
93
94   /*
95    * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
96    */
97
98.LinvokeNonRange:
99    cmp         $$2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
100    movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
101    jl          1f                      # handle 1 arg
102    je          2f                      # handle 2 args
103    cmp         $$4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
104    jl          3f                      # handle 3 args
105    je          4f                      # handle 4 args
1065:
107    andl        $$15, rINST_FULL        # rINST<- A
108    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
109    movl        (rFP, rINST_FULL, 4), %ecx # %ecx<- vA
110    movl        %ecx, (%edx)            # *outs<- vA
111    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
1124:
113    shr         $$12, %ecx              # %ecx<- G
114    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
115    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
116    movl        %ecx, (%edx)            # *outs<- vG
117    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
1183:
119    and         $$0x0f00, %ecx          # %ecx<- 0F00
120    shr         $$8, %ecx               # %ecx<- F
121    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
122    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
123    movl        %ecx, (%edx)            # *outs<- vF
124    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
1252:
126    and         $$0x00f0, %ecx          # %ecx<- 00E0
127    shr         $$4, %ecx               # %ecx<- E
128    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
129    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
130    movl        %ecx, (%edx)            # *outs<- vE
131    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
1321:
133    and         $$0x000f, %ecx          # %ecx<- 000D
134    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
135    movl        %ecx, -4(%edx)          # *--outs<- vD
1360:
137
138   /*
139    * %eax is "Method* methodToCall", the method we're trying to call
140    * find space for the new stack frame, check for overflow
141    */
142
143.LinvokeArgsDone:
144    movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
145    movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
146    movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
147    shl         $$2, %edx               # %edx<- update offset
148    SAVEAREA_FROM_FP(%eax,rFP)          # %eax<- &StackSaveArea
149    subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
150    GET_GLUE(%edx)                      # %edx<- pMterpGlue
151    movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
152    subl        $$sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
153    movl        offGlue_interpStackEnd(%edx), %edx # %edx<- glue->interpStackEnd
154    movl        %edx, LOCAL2_OFFSET(%ebp)       # LOCAL2_OFFSET<- glue->interpStackEnd
155    shl         $$2, %ecx               # %ecx<- update offset for outsSize
156    movl        %eax, %edx              # %edx<- newSaveArea
157    sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
158    cmp         LOCAL2_OFFSET(%ebp), %eax       # compare interpStackEnd and bottom
159    movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
160    jl          .LstackOverflow         # handle frame overflow
161
162   /*
163    * set up newSaveArea
164    */
165
166#ifdef EASY_GDB
167    SAVEAREA_FROM_FP(%ecx,rFP)          # %ecx<- &StackSaveArea
168    movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
169#endif
170    movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
171    movl        rPC_SPILL(%ebp), %ecx
172    movl        %ecx, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
173    testl       $$ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
174    movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
175    jne         .LinvokeNative          # handle native call
176
177   /*
178    * Update "glue" values for the new method
179    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
180    */
181
182    movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
183    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
184    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
185    movl        %eax, offGlue_method(%ecx) # glue->method<- methodToCall
186    movl        %edx, offGlue_methodClassDex(%ecx) # glue->methodClassDex<- method->clazz->pDvmDex
187    movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
188    movl        offGlue_self(%ecx), %eax # %eax<- glue->self
189    movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
190    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- newFP
191    FETCH_INST()
192    GOTO_NEXT                           # jump to methodToCall->insns
193
194   /*
195    * Prep for the native call
196    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea
197    */
198
199.LinvokeNative:
200    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
201    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
202    movl        offGlue_self(%ecx), %ecx        # %ecx<- glue->self
203    movl        offThread_jniLocal_topCookie(%ecx), %eax # %eax<- self->localRef->...
204    movl        %eax, offStackSaveArea_localRefCookie(%edx) # newSaveArea->localRefCookie<- top
205    movl        %edx, OUT_ARG4(%esp)    # save newSaveArea
206    movl        LOCAL1_OFFSET(%ebp), %edx # %edx<- newFP
207    movl        %edx, offThread_curFrame(%ecx)  # glue->self->curFrame<- newFP
208    movl        %ecx, OUT_ARG3(%esp)    # save glue->self
209    movl        %ecx, OUT_ARG2(%esp)    # push parameter glue->self
210    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
211    movl        OUT_ARG1(%esp), %eax    # %eax<- methodToCall
212    lea         offGlue_retval(%ecx), %ecx # %ecx<- &retval
213    movl        %ecx, OUT_ARG0(%esp)    # push parameter pMterpGlue
214    push        %edx                    # push parameter newFP
215
216    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
217    lea         4(%esp), %esp
218    movl        OUT_ARG4(%esp), %ecx    # %ecx<- newSaveArea
219    movl        OUT_ARG3(%esp), %eax    # %eax<- glue->self
220    movl        offStackSaveArea_localRefCookie(%ecx), %edx # %edx<- old top
221    cmp         $$0, offThread_exception(%eax) # check for exception
222    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
223    movl        %edx, offThread_jniLocal_topCookie(%eax) # new top <- old top
224    UNSPILL(rPC)
225    jne         common_exceptionThrown  # handle exception
226    FETCH_INST_WORD(3)
227    ADVANCE_PC(3)
228    GOTO_NEXT                           # jump to next instruction
229
230.LstackOverflow:    # eax=methodToCall
231    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
232    GET_GLUE(%eax)                      # %eax<- pMterpGlue
233    movl        offGlue_self(%eax), %eax # %eax<- glue->self
234    movl        %eax, OUT_ARG0(%esp)    # push parameter self
235    call        dvmHandleStackOverflow  # call: (Thread* self, Method* meth)
236    UNSPILL(rPC)                        # return: void
237    jmp         common_exceptionThrown  # handle exception
238
239
240/*
241 * Common invoke code (old-style).
242 * TUNING:  Rewrite along lines of new armv5 code?
243 *
244 * On entry:
245 *   eax = Method* methodToCall
246 *   ecx = bool methodCallRange
247 *   rINST trashed, must reload
248 */
249common_invokeOld:
250    movl     %ecx,OUT_ARG1(%esp)     # arg1<- methodCallRange
251    GET_GLUE(%ecx)
252    movzwl  (rPC),rINST_FULL         # recover rINST
253    movl     %eax,OUT_ARG2(%esp)     # arg2<- method
254    movzwl   4(rPC),%eax             # eax<- GFED or CCCC
255    SAVE_PC_TO_GLUE(%ecx)
256    SAVE_FP_TO_GLUE(%ecx)
257    movzbl   rINST_HI,rINST_FULL
258    movl     rINST_FULL,OUT_ARG3(%esp)# arg3<- AA
259    movl     %ecx,OUT_ARG0(%esp)     # arg0<- GLUE
260    movl     %eax,OUT_ARG4(%esp)     # arg4<- GFED/CCCC
261    call     dvmMterp_invokeMethod
262    jmp      common_resumeAfterGlueCall
263
264
265/*
266 * Do we need the thread to be suspended or have debugger/profiling activity?
267 *
268 * On entry:
269 *   ebx  -> PC adjustment in 16-bit words (must be preserved)
270 *   ecx  -> GLUE pointer
271 *   reentry type, e.g. kInterpEntryInstr stored in rGLUE->entryPoint
272 *
273 * Note: A call will normally kill %eax, rPC/%edx and %ecx.  To
274 *       streamline the normal case, this routine will preserve rPC and
275 *       %ecx in addition to the normal caller save regs.  The save/restore
276 *       is a bit ugly, but will happen in the relatively uncommon path.
277 * TODO: Basic-block style Jit will need a hook here as well.  Fold it into
278 *       the suspendCount check so we can get both in 1 shot.
279 */
280common_periodicChecks:
281    movl    offGlue_pSelfSuspendCount(%ecx),%eax    # eax <- &suspendCount
282    cmpl    $$0,(%eax)
283    jne     1f
284
2856:
286    movl   offGlue_pDebuggerActive(%ecx),%eax      # eax <- &DebuggerActive
287    movl   offGlue_pActiveProfilers(%ecx),%ecx     # ecx <- &ActiveProfilers
288    testl  %eax,%eax               # debugger enabled?
289    je     2f
290    movzbl (%eax),%eax             # get active count
2912:
292    orl    (%ecx),%eax             # eax <- debuggerActive | activeProfilers
293    GET_GLUE(%ecx)                 # restore rGLUE
294    jne    3f                      # one or both active - switch interp
295
2965:
297    ret
298
299    /* Check for suspend */
3001:
301    /*  At this point, the return pointer to the caller of
302     *  common_periodicChecks is on the top of stack.  We need to preserve
303     *  rPC(edx) and GLUE(ecx).  We'll spill rPC, and reload GLUE.
304     *  The outgoing profile is:
305     *      bool dvmCheckSuspendPending(Thread* self)
306     *  Because we reached here via a call, go ahead and build a new frame.
307     */
308    EXPORT_PC()                         # need for precise GC
309    movl    offGlue_self(%ecx),%eax      # eax<- glue->self
310    SPILL(rPC)                      # save edx
311    push    %ebp
312    movl    %esp,%ebp
313    subl    $$24,%esp
314    movl    %eax,OUT_ARG0(%esp)
315    call    dvmCheckSuspendPending
316    addl    $$24,%esp
317    pop     %ebp
318    UNSPILL(rPC)
319    GET_GLUE(%ecx)
320
321    /*
322     * Need to check to see if debugger or profiler flags got set
323     * while we were suspended.
324     */
325    jmp    6b
326
327    /* Switch interpreters */
328    /* Note: %ebx contains the 16-bit word offset to be applied to rPC to
329     * "complete" the interpretation of backwards branches.  In effect, we
330     * are completing the interpretation of the branch instruction here,
331     * and the new interpreter will resume interpretation at the branch
332     * target. However, a switch request recognized during the handling
333     * of a return from method instruction results in an immediate abort,
334     * and the new interpreter will resume by re-interpreting the return
335     * instruction.
336     */
3373:
338    leal    (rPC,%ebx,2),rPC       # adjust pc to show target
339    GET_GLUE(%ecx)                 # bail expect GLUE already loaded
340    movl    $$1,rINST_FULL         # set changeInterp to true
341    jmp     common_gotoBail
342
343
344/*
345 * Common code for handling a return instruction
346 */
347common_returnFromMethod:
348    GET_GLUE(%ecx)
349    /* Set entry mode in case we bail */
350    movb    $$kInterpEntryReturn,offGlue_entryPoint(%ecx)
351    xorl    rINST_FULL,rINST_FULL   # zero offset in case we switch interps
352    call    common_periodicChecks   # Note: expects %ecx to be preserved
353
354    SAVEAREA_FROM_FP(%eax,rFP)                    # eax<- saveArea (old)
355    movl    offStackSaveArea_prevFrame(%eax),rFP  # rFP<- prevFrame
356    movl    (offStackSaveArea_method-sizeofStackSaveArea)(rFP),rINST_FULL
357    cmpl    $$0,rINST_FULL                        # break?
358    je      common_gotoBail    # break frame, bail out completely
359
360    movl    offStackSaveArea_savedPc(%eax),rPC    # pc<- saveArea->savedPC
361    movl    offGlue_self(%ecx),%eax               # eax<- self
362    movl    rINST_FULL,offGlue_method(%ecx)  # glue->method = newSave->meethod
363    movl    rFP,offThread_curFrame(%eax)     # self->curFrame = fp
364    movl    offMethod_clazz(rINST_FULL),%eax # eax<- method->clazz
365    FETCH_INST_WORD(3)
366    movl    offClassObject_pDvmDex(%eax),%eax # eax<- method->clazz->pDvmDex
367    ADVANCE_PC(3)
368    movl    %eax,offGlue_methodClassDex(%ecx)
369    /* not bailing - restore entry mode to default */
370    movb    $$kInterpEntryInstr,offGlue_entryPoint(%ecx)
371    GOTO_NEXT
372
373/*
374 * Prepare to strip the current frame and "longjump" back to caller of
375 * dvmMterpStdRun.
376 *
377 * on entry:
378 *    rINST_FULL holds changeInterp
379 *    ecx holds glue pointer
380 *
381 * expected profile: dvmMterpStdBail(MterpGlue *glue, bool changeInterp)
382 */
383common_gotoBail:
384    SAVE_PC_TO_GLUE(%ecx)                # export state to glue
385    SAVE_FP_TO_GLUE(%ecx)
386    movl   %ecx,OUT_ARG0(%esp)           # glue in arg0
387    movl   rINST_FULL,OUT_ARG1(%esp)     # changeInterp in arg1
388    call    dvmMterpStdBail              # bail out....
389
390
391/*
392 * After returning from a "glued" function, pull out the updated values
393 * and start executing at the next instruction.
394 */
395 common_resumeAfterGlueCall:
396     GET_GLUE(%ecx)
397     LOAD_PC_FROM_GLUE(%ecx)
398     LOAD_FP_FROM_GLUE(%ecx)
399     FETCH_INST()
400     GOTO_NEXT
401
402/*
403 * Integer divide or mod by zero
404 */
405common_errDivideByZero:
406    EXPORT_PC()
407    movl    $$.LstrArithmeticException,%eax
408    movl    %eax,OUT_ARG0(%esp)
409    movl    $$.LstrDivideByZero,%eax
410    movl    %eax,OUT_ARG1(%esp)
411    SPILL(rPC)
412    call    dvmThrowException
413    UNSPILL(rPC)
414    jmp     common_exceptionThrown
415
416/*
417 * Attempt to allocate an array with a negative size.
418 */
419common_errNegativeArraySize:
420    EXPORT_PC()
421    movl    $$.LstrNegativeArraySizeException,%eax
422    movl    %eax,OUT_ARG0(%esp)
423    xorl    %eax,%eax
424    movl    %eax,OUT_ARG1(%esp)
425    SPILL(rPC)
426    call    dvmThrowException
427    UNSPILL(rPC)
428    jmp     common_exceptionThrown
429
430/*
431 * Attempt to allocate an array with a negative size.
432 */
433common_errNoSuchMethod:
434
435    EXPORT_PC()
436    movl    $$.LstrNoSuchMethodError,%eax
437    movl    %eax,OUT_ARG0(%esp)
438    xorl    %eax,%eax
439    movl    %eax,OUT_ARG1(%esp)
440    SPILL(rPC)
441    call    dvmThrowException
442    UNSPILL(rPC)
443    jmp     common_exceptionThrown
444
445/*
446 * Hit a null object when we weren't expecting one.  Export the PC, throw a
447 * NullPointerException and goto the exception processing code.
448 */
449common_errNullObject:
450    EXPORT_PC()
451    movl    $$.LstrNullPointerException,%eax
452    movl    %eax,OUT_ARG0(%esp)
453    xorl    %eax,%eax
454    movl    %eax,OUT_ARG1(%esp)
455    SPILL(rPC)
456    call    dvmThrowException
457    UNSPILL(rPC)
458    jmp     common_exceptionThrown
459
460/*
461 * Array index exceeds max.
462 */
463common_errArrayIndex:
464    EXPORT_PC()
465    movl    $$.LstrArrayIndexException,%eax
466    movl    %eax,OUT_ARG0(%esp)
467    xorl    %eax,%eax
468    movl    %eax,OUT_ARG1(%esp)
469    SPILL(rPC)
470    call    dvmThrowException
471    UNSPILL(rPC)
472    jmp     common_exceptionThrown
473/*
474 * Invalid array value.
475 */
476common_errArrayStore:
477    EXPORT_PC()
478    movl    $$.LstrArrayStoreException,%eax
479    movl    %eax,OUT_ARG0(%esp)
480    xorl    %eax,%eax
481    movl    %eax,OUT_ARG1(%esp)
482    SPILL(rPC)
483    call    dvmThrowException
484    UNSPILL(rPC)
485    jmp     common_exceptionThrown
486
487/*
488 * Somebody has thrown an exception.  Handle it.
489 *
490 * If the exception processing code returns to us (instead of falling
491 * out of the interpreter), continue with whatever the next instruction
492 * now happens to be.
493 *
494 * This does not return.
495 */
496common_exceptionThrown:
497    GET_GLUE(%ecx)
498    SAVE_PC_TO_GLUE(%ecx)
499    SAVE_FP_TO_GLUE(%ecx)
500    movl    %ecx,OUT_ARG0(%esp)
501    call    dvmMterp_exceptionThrown
502    jmp     common_resumeAfterGlueCall
503
504common_abort:
505    movl    $$0xdeadf00d,%eax
506    call     *%eax
507
508
509/*
510 * Strings
511 */
512
513    .section     .rodata
514.LstrNullPointerException:
515    .asciz    "Ljava/lang/NullPointerException;"
516.LstrArithmeticException:
517    .asciz  "Ljava/lang/ArithmeticException;"
518.LstrDivideByZero:
519    .asciz  "divide by zero"
520.LstrArrayIndexException:
521    .asciz  "Ljava/lang/ArrayIndexOutOfBoundsException;"
522.LstrArrayStoreException:
523    .asciz  "Ljava/lang/ArrayStoreException;"
524.LstrNegativeArraySizeException:
525    .asciz  "Ljava/lang/NegativeArraySizeException;"
526.LstrInstantiationError:
527    .asciz  "Ljava/lang/InstantiationError;"
528.LstrClassCastException:
529    .asciz  "Ljava/lang/ClassCastException;"
530.LstrNoSuchMethodError:
531    .asciz  "Ljava/lang/NoSuchMethodError;"
532.LstrInternalError:
533    .asciz  "Ljava/lang/InternalError;"
534.LstrFilledNewArrayNotImpl:
535    .asciz  "filled-new-array only implemented for 'int'"
536