OSDN Git Service

x86 interpreter write barrier support
authorbuzbee <buzbee@google.com>
Thu, 15 Jul 2010 23:03:32 +0000 (16:03 -0700)
committerbuzbee <buzbee@google.com>
Thu, 22 Jul 2010 18:29:09 +0000 (11:29 -0700)
Fix for 2837703.  Also added support for new Dalvik volatile ops.

Change-Id: Ic2b8d31afc8806077c5bf27ec90c643f7e47591e

18 files changed:
vm/mterp/config-x86
vm/mterp/out/InterpAsm-x86.S
vm/mterp/out/InterpC-x86.c
vm/mterp/x86/OP_APUT_OBJECT.S
vm/mterp/x86/OP_FILLED_NEW_ARRAY.S
vm/mterp/x86/OP_IGET_OBJECT_VOLATILE.S [new file with mode: 0644]
vm/mterp/x86/OP_IGET_VOLATILE.S [new file with mode: 0644]
vm/mterp/x86/OP_IPUT_OBJECT.S
vm/mterp/x86/OP_IPUT_OBJECT_QUICK.S
vm/mterp/x86/OP_IPUT_OBJECT_VOLATILE.S [new file with mode: 0644]
vm/mterp/x86/OP_IPUT_QUICK.S
vm/mterp/x86/OP_IPUT_VOLATILE.S [new file with mode: 0644]
vm/mterp/x86/OP_SGET_OBJECT_VOLATILE.S [new file with mode: 0644]
vm/mterp/x86/OP_SGET_VOLATILE.S [new file with mode: 0644]
vm/mterp/x86/OP_SPUT.S
vm/mterp/x86/OP_SPUT_OBJECT.S
vm/mterp/x86/OP_SPUT_OBJECT_VOLATILE.S [new file with mode: 0644]
vm/mterp/x86/OP_SPUT_VOLATILE.S [new file with mode: 0644]

index 78ae1a0..627e06c 100644 (file)
@@ -35,14 +35,6 @@ import c/opcommon.c
 op-start x86
     # stub -- need native impl
     op OP_EXECUTE_INLINE_RANGE c
-    op OP_IGET_VOLATILE c
-    op OP_IPUT_VOLATILE c
-    op OP_SGET_VOLATILE c
-    op OP_SPUT_VOLATILE c
-    op OP_IGET_OBJECT_VOLATILE c
-    op OP_IPUT_OBJECT_VOLATILE c
-    op OP_SGET_OBJECT_VOLATILE c
-    op OP_SPUT_OBJECT_VOLATILE c
     op OP_IGET_WIDE_VOLATILE c
     op OP_IPUT_WIDE_VOLATILE c
     op OP_SGET_WIDE_VOLATILE c
index 914b1d1..5dd2601 100644 (file)
@@ -2221,12 +2221,10 @@ dvmAsmInstructionStart = .L_OP_NOP
     .balign 64
 .L_OP_IPUT_OBJECT: /* 0x5b */
 /* File: x86/OP_IPUT_OBJECT.S */
-/* File: x86/OP_IPUT.S */
-
     /*
-     * General 32-bit instance field put.
+     * Object field put.
      *
-     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     * for: iput-object
      */
     /* op vA, vB, field@CCCC */
     GET_GLUE(%ecx)
@@ -2246,7 +2244,6 @@ dvmAsmInstructionStart = .L_OP_NOP
     GET_GLUE(rIBASE)
     jmp     .LOP_IPUT_OBJECT_resolve
 
-
 /* ------------------------------ */
     .balign 64
 .L_OP_IPUT_BOOLEAN: /* 0x5c */
@@ -2560,7 +2557,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     /*
      * General 32-bit SPUT handler.
      *
-     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
      */
     /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
@@ -2609,28 +2606,21 @@ dvmAsmInstructionStart = .L_OP_NOP
     .balign 64
 .L_OP_SPUT_OBJECT: /* 0x69 */
 /* File: x86/OP_SPUT_OBJECT.S */
-/* File: x86/OP_SPUT.S */
     /*
-     * General 32-bit SPUT handler.
-     *
-     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+     * SPUT object handler.
      */
     /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
     movzwl    2(rPC),%eax                        # eax<- field ref BBBB
     movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
     movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
-    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
+    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
     testl     %eax,%eax                          # resolved entry null?
     je        .LOP_SPUT_OBJECT_resolve                # if not, make it so
 .LOP_SPUT_OBJECT_finish:     # field ptr in eax
     movzbl    rINST_HI,%ecx                      # ecx<- AA
     GET_VREG(%ecx,%ecx)
-    FETCH_INST_WORD(2)
-    movl      %ecx,offStaticField_value(%eax)
-    ADVANCE_PC(2)
-    GOTO_NEXT
-
+    jmp       .LOP_SPUT_OBJECT_continue
 
 /* ------------------------------ */
     .balign 64
@@ -2640,7 +2630,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     /*
      * General 32-bit SPUT handler.
      *
-     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
      */
     /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
@@ -2667,7 +2657,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     /*
      * General 32-bit SPUT handler.
      *
-     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
      */
     /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
@@ -2694,7 +2684,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     /*
      * General 32-bit SPUT handler.
      *
-     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
      */
     /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
@@ -2721,7 +2711,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     /*
      * General 32-bit SPUT handler.
      *
-     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
      */
     /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
@@ -5684,73 +5674,145 @@ dvmAsmInstructionStart = .L_OP_NOP
 /* ------------------------------ */
     .balign 64
 .L_OP_IGET_VOLATILE: /* 0xe3 */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_IGET_VOLATILE     # do the real work
+/* File: x86/OP_IGET_VOLATILE.S */
+/* File: x86/OP_IGET.S */
+    /*
+     * General 32-bit instance field get.
+     *
+     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     */
+    /* op vA, vB, field@CCCC */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
-    GOTO_NEXT
+    SPILL(rIBASE)                                 # need another reg
+    movzwl  2(rPC),rIBASE                         # rIBASE<- 0000CCCC
+    movl    offGlue_methodClassDex(%ecx),%eax     # eax<- DvmDex
+    movzbl  rINST_HI,%ecx                         # ecx<- BA
+    sarl    $4,%ecx                              # ecx<- B
+    movl    offDvmDex_pResFields(%eax),%eax       # eax<- pDvmDex->pResFields
+    movzbl  rINST_HI,rINST_FULL                   # rINST_FULL<- BA
+    andb    $0xf,rINST_LO                        # rINST_FULL<- A
+    GET_VREG(%ecx,%ecx)                           # ecx<- fp[B], the object ptr
+    movl    (%eax,rIBASE,4),%eax                  # resolved entry
+    testl   %eax,%eax                             # is resolved entry null?
+    jne     .LOP_IGET_VOLATILE_finish                    # no, already resolved
+    movl    rIBASE,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
+    GET_GLUE(rIBASE)
+    jmp     .LOP_IGET_VOLATILE_resolve
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_IPUT_VOLATILE: /* 0xe4 */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_IPUT_VOLATILE     # do the real work
+/* File: x86/OP_IPUT_VOLATILE.S */
+/* File: x86/OP_IPUT.S */
+
+    /*
+     * General 32-bit instance field put.
+     *
+     * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+     */
+    /* op vA, vB, field@CCCC */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
-    GOTO_NEXT
+    SPILL(rIBASE)                                 # need another reg
+    movzwl  2(rPC),rIBASE                         # rIBASE<- 0000CCCC
+    movl    offGlue_methodClassDex(%ecx),%eax     # eax<- DvmDex
+    movzbl  rINST_HI,%ecx                         # ecx<- BA
+    sarl    $4,%ecx                              # ecx<- B
+    movl    offDvmDex_pResFields(%eax),%eax       # eax<- pDvmDex->pResFields
+    movzbl  rINST_HI,rINST_FULL                   # rINST_FULL<- BA
+    andb    $0xf,rINST_LO                        # rINST_FULL<- A
+    GET_VREG(%ecx,%ecx)                           # ecx<- fp[B], the object ptr
+    movl    (%eax,rIBASE,4),%eax                  # resolved entry
+    testl   %eax,%eax                             # is resolved entry null?
+    jne     .LOP_IPUT_VOLATILE_finish                    # no, already resolved
+    movl    rIBASE,OUT_ARG1(%esp)
+    GET_GLUE(rIBASE)
+    jmp     .LOP_IPUT_VOLATILE_resolve
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SGET_VOLATILE: /* 0xe5 */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_SGET_VOLATILE     # do the real work
+/* File: x86/OP_SGET_VOLATILE.S */
+/* File: x86/OP_SGET.S */
+    /*
+     * General 32-bit SGET handler.
+     *
+     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     */
+    /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
+    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
+    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
+    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
+    testl     %eax,%eax                          # resolved entry null?
+    je        .LOP_SGET_VOLATILE_resolve                # if not, make it so
+.LOP_SGET_VOLATILE_finish:     # field ptr in eax
+    movl      offStaticField_value(%eax),%eax
+    movzbl    rINST_HI,%ecx                      # ecx<- AA
+    FETCH_INST_WORD(2)
+    ADVANCE_PC(2)
+    SET_VREG(%eax,%ecx)
     GOTO_NEXT
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SPUT_VOLATILE: /* 0xe6 */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_SPUT_VOLATILE     # do the real work
+/* File: x86/OP_SPUT_VOLATILE.S */
+/* File: x86/OP_SPUT.S */
+    /*
+     * General 32-bit SPUT handler.
+     *
+     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+     */
+    /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
+    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
+    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
+    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
+    testl     %eax,%eax                          # resolved entry null?
+    je        .LOP_SPUT_VOLATILE_resolve                # if not, make it so
+.LOP_SPUT_VOLATILE_finish:     # field ptr in eax
+    movzbl    rINST_HI,%ecx                      # ecx<- AA
+    GET_VREG(%ecx,%ecx)
+    FETCH_INST_WORD(2)
+    movl      %ecx,offStaticField_value(%eax)
+    ADVANCE_PC(2)
     GOTO_NEXT
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_IGET_OBJECT_VOLATILE: /* 0xe7 */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_IGET_OBJECT_VOLATILE     # do the real work
+/* File: x86/OP_IGET_OBJECT_VOLATILE.S */
+/* File: x86/OP_IGET.S */
+    /*
+     * General 32-bit instance field get.
+     *
+     * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+     */
+    /* op vA, vB, field@CCCC */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
-    GOTO_NEXT
+    SPILL(rIBASE)                                 # need another reg
+    movzwl  2(rPC),rIBASE                         # rIBASE<- 0000CCCC
+    movl    offGlue_methodClassDex(%ecx),%eax     # eax<- DvmDex
+    movzbl  rINST_HI,%ecx                         # ecx<- BA
+    sarl    $4,%ecx                              # ecx<- B
+    movl    offDvmDex_pResFields(%eax),%eax       # eax<- pDvmDex->pResFields
+    movzbl  rINST_HI,rINST_FULL                   # rINST_FULL<- BA
+    andb    $0xf,rINST_LO                        # rINST_FULL<- A
+    GET_VREG(%ecx,%ecx)                           # ecx<- fp[B], the object ptr
+    movl    (%eax,rIBASE,4),%eax                  # resolved entry
+    testl   %eax,%eax                             # is resolved entry null?
+    jne     .LOP_IGET_OBJECT_VOLATILE_finish                    # no, already resolved
+    movl    rIBASE,OUT_ARG1(%esp)                 # needed by dvmResolveInstField
+    GET_GLUE(rIBASE)
+    jmp     .LOP_IGET_OBJECT_VOLATILE_resolve
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_IGET_WIDE_VOLATILE: /* 0xe8 */
@@ -5968,7 +6030,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     .balign 64
 .L_OP_IPUT_QUICK: /* 0xf5 */
 /* File: x86/OP_IPUT_QUICK.S */
-    /* For: iput-quick, iput-object-quick */
+    /* For: iput-quick */
     /* op vA, vB, offset@CCCC */
     movzbl    rINST_HI,%ecx             # ecx<- BA
     sarl      $4,%ecx                  # ecx<- B
@@ -6011,8 +6073,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     .balign 64
 .L_OP_IPUT_OBJECT_QUICK: /* 0xf7 */
 /* File: x86/OP_IPUT_OBJECT_QUICK.S */
-/* File: x86/OP_IPUT_QUICK.S */
-    /* For: iput-quick, iput-object-quick */
+    /* For: iput-object-quick */
     /* op vA, vB, offset@CCCC */
     movzbl    rINST_HI,%ecx             # ecx<- BA
     sarl      $4,%ecx                  # ecx<- B
@@ -6021,13 +6082,11 @@ dvmAsmInstructionStart = .L_OP_NOP
     andb      $0xf,rINST_LO            # rINST_FULL<- A
     GET_VREG(rINST_FULL,rINST_FULL)     # rINST_FULL<- v[A]
     movzwl    2(rPC),%eax               # eax<- field byte offset
-    testl     %ecx,%ecx                  # is object null?
+    testl     %ecx,%ecx                 # is object null?
     je        common_errNullObject
     movl      rINST_FULL,(%ecx,%eax,1)
-    FETCH_INST_WORD(2)
-    ADVANCE_PC(2)
-    GOTO_NEXT
-
+    GET_GLUE(%eax)
+    jmp       .LOP_IPUT_OBJECT_QUICK_finish
 
 /* ------------------------------ */
     .balign 64
@@ -6142,45 +6201,81 @@ dvmAsmInstructionStart = .L_OP_NOP
 /* ------------------------------ */
     .balign 64
 .L_OP_IPUT_OBJECT_VOLATILE: /* 0xfc */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_IPUT_OBJECT_VOLATILE     # do the real work
+/* File: x86/OP_IPUT_OBJECT_VOLATILE.S */
+/* File: x86/OP_IPUT_OBJECT.S */
+    /*
+     * Object field put.
+     *
+     * for: iput-object
+     */
+    /* op vA, vB, field@CCCC */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
-    GOTO_NEXT
+    SPILL(rIBASE)                                 # need another reg
+    movzwl  2(rPC),rIBASE                         # rIBASE<- 0000CCCC
+    movl    offGlue_methodClassDex(%ecx),%eax     # eax<- DvmDex
+    movzbl  rINST_HI,%ecx                         # ecx<- BA
+    sarl    $4,%ecx                              # ecx<- B
+    movl    offDvmDex_pResFields(%eax),%eax       # eax<- pDvmDex->pResFields
+    movzbl  rINST_HI,rINST_FULL                   # rINST_FULL<- BA
+    andb    $0xf,rINST_LO                        # rINST_FULL<- A
+    GET_VREG(%ecx,%ecx)                           # ecx<- fp[B], the object ptr
+    movl    (%eax,rIBASE,4),%eax                  # resolved entry
+    testl   %eax,%eax                             # is resolved entry null?
+    jne     .LOP_IPUT_OBJECT_VOLATILE_finish                    # no, already resolved
+    movl    rIBASE,OUT_ARG1(%esp)
+    GET_GLUE(rIBASE)
+    jmp     .LOP_IPUT_OBJECT_VOLATILE_resolve
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SGET_OBJECT_VOLATILE: /* 0xfd */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_SGET_OBJECT_VOLATILE     # do the real work
+/* File: x86/OP_SGET_OBJECT_VOLATILE.S */
+/* File: x86/OP_SGET.S */
+    /*
+     * General 32-bit SGET handler.
+     *
+     * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+     */
+    /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
+    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
+    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
+    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField ptr
+    testl     %eax,%eax                          # resolved entry null?
+    je        .LOP_SGET_OBJECT_VOLATILE_resolve                # if not, make it so
+.LOP_SGET_OBJECT_VOLATILE_finish:     # field ptr in eax
+    movl      offStaticField_value(%eax),%eax
+    movzbl    rINST_HI,%ecx                      # ecx<- AA
+    FETCH_INST_WORD(2)
+    ADVANCE_PC(2)
+    SET_VREG(%eax,%ecx)
     GOTO_NEXT
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_SPUT_OBJECT_VOLATILE: /* 0xfe */
-    /* (stub) */
-    GET_GLUE(%ecx)
-    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
-    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
-    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
-    call      dvmMterp_OP_SPUT_OBJECT_VOLATILE     # do the real work
+/* File: x86/OP_SPUT_OBJECT_VOLATILE.S */
+/* File: x86/OP_SPUT_OBJECT.S */
+    /*
+     * SPUT object handler.
+     */
+    /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
-    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
-    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
-    FETCH_INST()
-    GOTO_NEXT
+    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
+    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
+    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
+    testl     %eax,%eax                          # resolved entry null?
+    je        .LOP_SPUT_OBJECT_VOLATILE_resolve                # if not, make it so
+.LOP_SPUT_OBJECT_VOLATILE_finish:     # field ptr in eax
+    movzbl    rINST_HI,%ecx                      # ecx<- AA
+    GET_VREG(%ecx,%ecx)
+    jmp       .LOP_SPUT_OBJECT_VOLATILE_continue
+
+
 /* ------------------------------ */
     .balign 64
 .L_OP_UNUSED_FF: /* 0xff */
@@ -6570,6 +6665,7 @@ dvmAsmSisterStart:
     movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
     movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
     movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
+    GET_GLUE(%eax)
     cmpb    $'I',%cl                             # supported?
     je      1f
     cmpb    $'L',%cl
@@ -6577,6 +6673,7 @@ dvmAsmSisterStart:
     cmpb    $'[',%cl
     jne      .LOP_FILLED_NEW_ARRAY_notimpl                  # no, not handled yet
 1:
+    movl    %ecx,offGlue_retval+4(%eax)           # save type
     .if      (!0)
     SPILL_TMP(rINST_FULL)                         # save copy, need "B" later
     sarl    $4,rINST_FULL
@@ -6610,7 +6707,9 @@ dvmAsmSisterStart:
     FETCH_INST_WORD(3)
     rep
     movsd
+    GET_GLUE(%ecx)
     UNSPILL(rIBASE)
+    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
     UNSPILL(rFP)
     .else
     testl  rINST_FULL,rINST_FULL
@@ -6629,10 +6728,19 @@ dvmAsmSisterStart:
     sub    $1,rINST_FULL
     jne    3b
 4:
+    GET_GLUE(%ecx)
     UNSPILL(rPC)
+    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
     FETCH_INST_WORD(3)
     .endif
 
+    cmpb    $'I',%al                        # Int array?
+    je      5f                               # skip card mark if so
+    movl    offGlue_retval(%ecx),%eax        # eax<- object head
+    movl    offGlue_cardTable(%ecx),%ecx     # card table base
+    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
+    movb    %cl,(%ecx,%eax)                  # mark card
+5:
     ADVANCE_PC(3)
     GOTO_NEXT
 
@@ -6674,6 +6782,7 @@ dvmAsmSisterStart:
     movl    $ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
     movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
     movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
+    GET_GLUE(%eax)
     cmpb    $'I',%cl                             # supported?
     je      1f
     cmpb    $'L',%cl
@@ -6681,6 +6790,7 @@ dvmAsmSisterStart:
     cmpb    $'[',%cl
     jne      .LOP_FILLED_NEW_ARRAY_RANGE_notimpl                  # no, not handled yet
 1:
+    movl    %ecx,offGlue_retval+4(%eax)           # save type
     .if      (!1)
     SPILL_TMP(rINST_FULL)                         # save copy, need "B" later
     sarl    $4,rINST_FULL
@@ -6714,7 +6824,9 @@ dvmAsmSisterStart:
     FETCH_INST_WORD(3)
     rep
     movsd
+    GET_GLUE(%ecx)
     UNSPILL(rIBASE)
+    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
     UNSPILL(rFP)
     .else
     testl  rINST_FULL,rINST_FULL
@@ -6733,10 +6845,19 @@ dvmAsmSisterStart:
     sub    $1,rINST_FULL
     jne    3b
 4:
+    GET_GLUE(%ecx)
     UNSPILL(rPC)
+    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
     FETCH_INST_WORD(3)
     .endif
 
+    cmpb    $'I',%al                        # Int array?
+    je      5f                               # skip card mark if so
+    movl    offGlue_retval(%ecx),%eax        # eax<- object head
+    movl    offGlue_cardTable(%ecx),%ecx     # card table base
+    shrl    $GC_CARD_SHIFT,%eax             # convert to card num
+    movb    %cl,(%ecx,%eax)                  # mark card
+5:
     ADVANCE_PC(3)
     GOTO_NEXT
 
@@ -6838,7 +6959,15 @@ dvmAsmSisterStart:
     UNSPILL(rPC)
     UNSPILL_TMP(%ecx)
     testl     %eax,%eax
+    GET_GLUE(%eax)
     je        common_errArrayStore
+    movl      offGlue_cardTable(%eax),%eax   # get card table base
+    movl      rINST_FULL,(%ecx)
+    FETCH_INST_WORD(2)
+    shrl      $GC_CARD_SHIFT,%ecx           # convert addr to card number
+    movb      %al,(%eax,%ecx)                # mark card
+    ADVANCE_PC(2)
+    GOTO_NEXT
 
 .LOP_APUT_OBJECT_skip_check:
     movl      rINST_FULL,(%ecx)
@@ -7213,8 +7342,15 @@ dvmAsmSisterStart:
     UNSPILL(rIBASE)
     testl   %ecx,%ecx                            # object null?
     je      common_errNullObject                 # object was null
-    movl   rINST_FULL,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
+    movl    rINST_FULL,(%ecx,%eax)          # obj.field <- v[A](8/16/32 bits)
+    GET_GLUE(%eax)
+    testl   rINST_FULL,rINST_FULL                # stored a NULL?
+    movl    offGlue_cardTable(%eax),%eax         # get card table base
     FETCH_INST_WORD(2)
+    je      1f                                   # skip card mark if null store
+    shrl    $GC_CARD_SHIFT,%ecx                 # object head to card number
+    movb    %al,(%eax,%ecx)                      # mark card
+1:
     ADVANCE_PC(2)
     GOTO_NEXT
 
@@ -7544,9 +7680,20 @@ dvmAsmSisterStart:
 
 /* continuation for OP_SPUT_OBJECT */
 
-    /*
-     * Go resolve the field
-     */
+
+.LOP_SPUT_OBJECT_continue:
+    movl      %ecx,offStaticField_value(%eax)
+    testl     %ecx,%ecx
+    GET_GLUE(%ecx)
+    FETCH_INST_WORD(2)
+    je        1f
+    movl      offGlue_cardTable(%ecx),%ecx       # get card table base
+    shrl      $GC_CARD_SHIFT,%eax               # head to card number
+    movb      %cl,(%ecx,%eax)                    # mark card
+1:
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
 .LOP_SPUT_OBJECT_resolve:
     GET_GLUE(%ecx)
     movzwl   2(rPC),%eax                        # eax<- field ref BBBB
@@ -8319,6 +8466,156 @@ dvmAsmSisterStart:
     ADVANCE_PC(2)
     GOTO_NEXT
 
+/* continuation for OP_IGET_VOLATILE */
+
+
+.LOP_IGET_VOLATILE_resolve:
+    EXPORT_PC()
+    SPILL(rPC)
+    movl    offGlue_method(rIBASE),rPC            # rPC<- current method
+    UNSPILL(rIBASE)
+    movl    offMethod_clazz(rPC),rPC              # rPC<- method->clazz
+    SPILL_TMP(%ecx)                               # save object pointer across call
+    movl    rPC,OUT_ARG0(%esp)                    # pass in method->clazz
+    call    dvmResolveInstField                   #  ... to dvmResolveInstField
+    UNSPILL_TMP(%ecx)
+    UNSPILL(rPC)
+    testl   %eax,%eax                             #  ... which returns InstrField ptr
+    jne     .LOP_IGET_VOLATILE_finish
+    jmp     common_exceptionThrown
+
+.LOP_IGET_VOLATILE_finish:
+    /*
+     * Currently:
+     *   eax holds resolved field
+     *   ecx holds object
+     *   rIBASE is scratch, but needs to be unspilled
+     *   rINST_FULL holds A
+     */
+    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
+    UNSPILL(rIBASE)
+    testl   %ecx,%ecx                            # object null?
+    je      common_errNullObject                 # object was null
+    movl   (%ecx,%eax,1),%ecx                   # ecx<- obj.field (8/16/32 bits)
+    movl    rINST_FULL,%eax                      # eax<- A
+    FETCH_INST_WORD(2)
+    SET_VREG(%ecx,%eax)
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
+/* continuation for OP_IPUT_VOLATILE */
+
+
+.LOP_IPUT_VOLATILE_resolve:
+    EXPORT_PC()
+    SPILL(rPC)
+    movl    offGlue_method(rIBASE),rPC            # rPC<- current method
+    UNSPILL(rIBASE)
+    movl    offMethod_clazz(rPC),rPC              # rPC<- method->clazz
+    SPILL_TMP(%ecx)                               # save object pointer across call
+    movl    rPC,OUT_ARG0(%esp)                    # pass in method->clazz
+    call    dvmResolveInstField                   #  ... to dvmResolveInstField
+    UNSPILL_TMP(%ecx)
+    UNSPILL(rPC)
+    testl   %eax,%eax                             #  ... which returns InstrField ptr
+    jne     .LOP_IPUT_VOLATILE_finish
+    jmp     common_exceptionThrown
+
+.LOP_IPUT_VOLATILE_finish:
+    /*
+     * Currently:
+     *   eax holds resolved field
+     *   ecx holds object
+     *   rIBASE is scratch, but needs to be unspilled
+     *   rINST_FULL holds A
+     */
+    GET_VREG(rINST_FULL,rINST_FULL)              # rINST_FULL<- v[A]
+    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
+    UNSPILL(rIBASE)
+    testl   %ecx,%ecx                            # object null?
+    je      common_errNullObject                 # object was null
+    movl   rINST_FULL,(%ecx,%eax,1)            # obj.field <- v[A](8/16/32 bits)
+    FETCH_INST_WORD(2)
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
+/* continuation for OP_SGET_VOLATILE */
+
+    /*
+     * Go resolve the field
+     */
+.LOP_SGET_VOLATILE_resolve:
+    GET_GLUE(%ecx)
+    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
+    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
+    EXPORT_PC()                                 # could throw, need to export
+    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
+    SPILL(rPC)
+    movl     %eax,OUT_ARG1(%esp)
+    movl     %ecx,OUT_ARG0(%esp)
+    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
+    UNSPILL(rPC)
+    testl    %eax,%eax
+    jne      .LOP_SGET_VOLATILE_finish                 # success, continue
+    jmp      common_exceptionThrown             # no, handle exception
+
+/* continuation for OP_SPUT_VOLATILE */
+
+    /*
+     * Go resolve the field
+     */
+.LOP_SPUT_VOLATILE_resolve:
+    GET_GLUE(%ecx)
+    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
+    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
+    EXPORT_PC()                                 # could throw, need to export
+    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
+    SPILL(rPC)
+    movl     %eax,OUT_ARG1(%esp)
+    movl     %ecx,OUT_ARG0(%esp)
+    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
+    UNSPILL(rPC)
+    testl    %eax,%eax
+    jne      .LOP_SPUT_VOLATILE_finish                 # success, continue
+    jmp      common_exceptionThrown             # no, handle exception
+
+/* continuation for OP_IGET_OBJECT_VOLATILE */
+
+
+.LOP_IGET_OBJECT_VOLATILE_resolve:
+    EXPORT_PC()
+    SPILL(rPC)
+    movl    offGlue_method(rIBASE),rPC            # rPC<- current method
+    UNSPILL(rIBASE)
+    movl    offMethod_clazz(rPC),rPC              # rPC<- method->clazz
+    SPILL_TMP(%ecx)                               # save object pointer across call
+    movl    rPC,OUT_ARG0(%esp)                    # pass in method->clazz
+    call    dvmResolveInstField                   #  ... to dvmResolveInstField
+    UNSPILL_TMP(%ecx)
+    UNSPILL(rPC)
+    testl   %eax,%eax                             #  ... which returns InstrField ptr
+    jne     .LOP_IGET_OBJECT_VOLATILE_finish
+    jmp     common_exceptionThrown
+
+.LOP_IGET_OBJECT_VOLATILE_finish:
+    /*
+     * Currently:
+     *   eax holds resolved field
+     *   ecx holds object
+     *   rIBASE is scratch, but needs to be unspilled
+     *   rINST_FULL holds A
+     */
+    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
+    UNSPILL(rIBASE)
+    testl   %ecx,%ecx                            # object null?
+    je      common_errNullObject                 # object was null
+    movl   (%ecx,%eax,1),%ecx                   # ecx<- obj.field (8/16/32 bits)
+    movl    rINST_FULL,%eax                      # eax<- A
+    FETCH_INST_WORD(2)
+    SET_VREG(%ecx,%eax)
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
 /* continuation for OP_EXECUTE_INLINE */
 
 .LOP_EXECUTE_INLINE_continue:
@@ -8361,6 +8658,113 @@ dvmAsmSisterStart:
     jmp       *gDvmInlineOpsTable(%eax)
     # will return to caller of .LOP_EXECUTE_INLINE_continue
 
+/* continuation for OP_IPUT_OBJECT_QUICK */
+
+.LOP_IPUT_OBJECT_QUICK_finish:
+    testl     rINST_FULL,rINST_FULL         # did we store null?
+    FETCH_INST_WORD(2)
+    movl      offGlue_cardTable(%eax),%eax  # get card table base
+    je        1f                            # skip card mark if null store
+    shrl      $GC_CARD_SHIFT,%ecx          # object head to card number
+    movb      %al,(%eax,%ecx)               # mark card
+1:
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
+/* continuation for OP_IPUT_OBJECT_VOLATILE */
+
+
+.LOP_IPUT_OBJECT_VOLATILE_resolve:
+    EXPORT_PC()
+    SPILL(rPC)
+    movl    offGlue_method(rIBASE),rPC            # rPC<- current method
+    UNSPILL(rIBASE)
+    movl    offMethod_clazz(rPC),rPC              # rPC<- method->clazz
+    SPILL_TMP(%ecx)                               # save object pointer across call
+    movl    rPC,OUT_ARG0(%esp)                    # pass in method->clazz
+    call    dvmResolveInstField                   #  ... to dvmResolveInstField
+    UNSPILL_TMP(%ecx)
+    UNSPILL(rPC)
+    testl   %eax,%eax                             #  ... which returns InstrField ptr
+    jne     .LOP_IPUT_OBJECT_VOLATILE_finish
+    jmp     common_exceptionThrown
+
+.LOP_IPUT_OBJECT_VOLATILE_finish:
+    /*
+     * Currently:
+     *   eax holds resolved field
+     *   ecx holds object
+     *   rIBASE is scratch, but needs to be unspilled
+     *   rINST_FULL holds A
+     */
+    GET_VREG(rINST_FULL,rINST_FULL)              # rINST_FULL<- v[A]
+    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
+    UNSPILL(rIBASE)
+    testl   %ecx,%ecx                            # object null?
+    je      common_errNullObject                 # object was null
+    movl    rINST_FULL,(%ecx,%eax)          # obj.field <- v[A](8/16/32 bits)
+    GET_GLUE(%eax)
+    testl   rINST_FULL,rINST_FULL                # stored a NULL?
+    movl    offGlue_cardTable(%eax),%eax         # get card table base
+    FETCH_INST_WORD(2)
+    je      1f                                   # skip card mark if null store
+    shrl    $GC_CARD_SHIFT,%ecx                 # object head to card number
+    movb    %al,(%eax,%ecx)                      # mark card
+1:
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
+/* continuation for OP_SGET_OBJECT_VOLATILE */
+
+    /*
+     * Go resolve the field
+     */
+.LOP_SGET_OBJECT_VOLATILE_resolve:
+    GET_GLUE(%ecx)
+    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
+    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
+    EXPORT_PC()                                 # could throw, need to export
+    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
+    SPILL(rPC)
+    movl     %eax,OUT_ARG1(%esp)
+    movl     %ecx,OUT_ARG0(%esp)
+    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
+    UNSPILL(rPC)
+    testl    %eax,%eax
+    jne      .LOP_SGET_OBJECT_VOLATILE_finish                 # success, continue
+    jmp      common_exceptionThrown             # no, handle exception
+
+/* continuation for OP_SPUT_OBJECT_VOLATILE */
+
+
+.LOP_SPUT_OBJECT_VOLATILE_continue:
+    movl      %ecx,offStaticField_value(%eax)
+    testl     %ecx,%ecx
+    GET_GLUE(%ecx)
+    FETCH_INST_WORD(2)
+    je        1f
+    movl      offGlue_cardTable(%ecx),%ecx       # get card table base
+    shrl      $GC_CARD_SHIFT,%eax               # head to card number
+    movb      %cl,(%ecx,%eax)                    # mark card
+1:
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
+.LOP_SPUT_OBJECT_VOLATILE_resolve:
+    GET_GLUE(%ecx)
+    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
+    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
+    EXPORT_PC()                                 # could throw, need to export
+    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
+    SPILL(rPC)
+    movl     %eax,OUT_ARG1(%esp)
+    movl     %ecx,OUT_ARG0(%esp)
+    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
+    UNSPILL(rPC)
+    testl    %eax,%eax
+    jne      .LOP_SPUT_OBJECT_VOLATILE_finish                 # success, continue
+    jmp      common_exceptionThrown             # no, handle exception
+
     .size   dvmAsmSisterStart, .-dvmAsmSisterStart
     .global dvmAsmSisterEnd
 dvmAsmSisterEnd:
index 142d7c9..1ce0302 100644 (file)
@@ -1201,26 +1201,6 @@ GOTO_TARGET_DECL(exceptionThrown);
     }                                                                       \
     FINISH(2);
 
-/* File: c/OP_IGET_VOLATILE.c */
-HANDLE_IGET_X(OP_IGET_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_IPUT_VOLATILE.c */
-HANDLE_IPUT_X(OP_IPUT_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_SGET_VOLATILE.c */
-HANDLE_SGET_X(OP_SGET_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_SPUT_VOLATILE.c */
-HANDLE_SPUT_X(OP_SPUT_VOLATILE,         "-volatile", IntVolatile, )
-OP_END
-
-/* File: c/OP_IGET_OBJECT_VOLATILE.c */
-HANDLE_IGET_X(OP_IGET_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
 /* File: c/OP_IGET_WIDE_VOLATILE.c */
 HANDLE_IGET_X(OP_IGET_WIDE_VOLATILE,    "-wide-volatile", LongVolatile, _WIDE)
 OP_END
@@ -1282,18 +1262,6 @@ HANDLE_OPCODE(OP_EXECUTE_INLINE_RANGE /*{vCCCC..v(CCCC+AA-1)}, inline@BBBB*/)
     FINISH(3);
 OP_END
 
-/* File: c/OP_IPUT_OBJECT_VOLATILE.c */
-HANDLE_IPUT_X(OP_IPUT_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
-/* File: c/OP_SGET_OBJECT_VOLATILE.c */
-HANDLE_SGET_X(OP_SGET_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
-/* File: c/OP_SPUT_OBJECT_VOLATILE.c */
-HANDLE_SPUT_X(OP_SPUT_OBJECT_VOLATILE,  "-object-volatile", ObjectVolatile, _AS_OBJECT)
-OP_END
-
 /* File: c/gotoTargets.c */
 /*
  * C footer.  This has some common code shared by the various targets.
index 2069950..d2ec565 100644 (file)
     UNSPILL(rPC)
     UNSPILL_TMP(%ecx)
     testl     %eax,%eax
+    GET_GLUE(%eax)
     je        common_errArrayStore
+    movl      offGlue_cardTable(%eax),%eax   # get card table base
+    movl      rINST_FULL,(%ecx)
+    FETCH_INST_WORD(2)
+    shrl      $$GC_CARD_SHIFT,%ecx           # convert addr to card number
+    movb      %al,(%eax,%ecx)                # mark card
+    ADVANCE_PC(2)
+    GOTO_NEXT
 
 .L${opcode}_skip_check:
     movl      rINST_FULL,(%ecx)
index a98f6b9..b990aeb 100644 (file)
@@ -48,6 +48,7 @@
     movl    $$ALLOC_DONT_TRACK,OUT_ARG2(%esp)     # arg2<- flags
     movzbl  1(%ecx),%ecx                          # ecx<- descriptor[1]
     movl    %eax,OUT_ARG0(%esp)                   # arg0<- arrayClass
+    GET_GLUE(%eax)
     cmpb    $$'I',%cl                             # supported?
     je      1f
     cmpb    $$'L',%cl
@@ -55,6 +56,7 @@
     cmpb    $$'[',%cl
     jne      .L${opcode}_notimpl                  # no, not handled yet
 1:
+    movl    %ecx,offGlue_retval+4(%eax)           # save type
     .if      (!$isrange)
     SPILL_TMP(rINST_FULL)                         # save copy, need "B" later
     sarl    $$4,rINST_FULL
@@ -88,7 +90,9 @@
     FETCH_INST_WORD(3)
     rep
     movsd
+    GET_GLUE(%ecx)
     UNSPILL(rIBASE)
+    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
     UNSPILL(rFP)
     .else
     testl  rINST_FULL,rINST_FULL
     sub    $$1,rINST_FULL
     jne    3b
 4:
+    GET_GLUE(%ecx)
     UNSPILL(rPC)
+    movl    offGlue_retval+4(%ecx),%eax      # eax<- type
     FETCH_INST_WORD(3)
     .endif
 
+    cmpb    $$'I',%al                        # Int array?
+    je      5f                               # skip card mark if so
+    movl    offGlue_retval(%ecx),%eax        # eax<- object head
+    movl    offGlue_cardTable(%ecx),%ecx     # card table base
+    shrl    $$GC_CARD_SHIFT,%eax             # convert to card num
+    movb    %cl,(%ecx,%eax)                  # mark card
+5:
     ADVANCE_PC(3)
     GOTO_NEXT
 
diff --git a/vm/mterp/x86/OP_IGET_OBJECT_VOLATILE.S b/vm/mterp/x86/OP_IGET_OBJECT_VOLATILE.S
new file mode 100644 (file)
index 0000000..4576d39
--- /dev/null
@@ -0,0 +1,3 @@
+%verify "executed"
+%verify "negative value is sign-extended"
+%include "x86/OP_IGET.S"
diff --git a/vm/mterp/x86/OP_IGET_VOLATILE.S b/vm/mterp/x86/OP_IGET_VOLATILE.S
new file mode 100644 (file)
index 0000000..4576d39
--- /dev/null
@@ -0,0 +1,3 @@
+%verify "executed"
+%verify "negative value is sign-extended"
+%include "x86/OP_IGET.S"
index caf007e..39c64e7 100644 (file)
@@ -1,2 +1,70 @@
+%default { "sqnum":"0" }
 %verify "executed"
-%include "x86/OP_IPUT.S"
+%verify "null object"
+%verify "field already resolved"
+%verify "field not yet resolved"
+%verify "field cannot be resolved"
+    /*
+     * Object field put.
+     *
+     * for: iput-object
+     */
+    /* op vA, vB, field@CCCC */
+    GET_GLUE(%ecx)
+    SPILL(rIBASE)                                 # need another reg
+    movzwl  2(rPC),rIBASE                         # rIBASE<- 0000CCCC
+    movl    offGlue_methodClassDex(%ecx),%eax     # eax<- DvmDex
+    movzbl  rINST_HI,%ecx                         # ecx<- BA
+    sarl    $$4,%ecx                              # ecx<- B
+    movl    offDvmDex_pResFields(%eax),%eax       # eax<- pDvmDex->pResFields
+    movzbl  rINST_HI,rINST_FULL                   # rINST_FULL<- BA
+    andb    $$0xf,rINST_LO                        # rINST_FULL<- A
+    GET_VREG(%ecx,%ecx)                           # ecx<- fp[B], the object ptr
+    movl    (%eax,rIBASE,4),%eax                  # resolved entry
+    testl   %eax,%eax                             # is resolved entry null?
+    jne     .L${opcode}_finish                    # no, already resolved
+    movl    rIBASE,OUT_ARG1(%esp)
+    GET_GLUE(rIBASE)
+    jmp     .L${opcode}_resolve
+%break
+
+
+.L${opcode}_resolve:
+    EXPORT_PC()
+    SPILL(rPC)
+    movl    offGlue_method(rIBASE),rPC            # rPC<- current method
+    UNSPILL(rIBASE)
+    movl    offMethod_clazz(rPC),rPC              # rPC<- method->clazz
+    SPILL_TMP(%ecx)                               # save object pointer across call
+    movl    rPC,OUT_ARG0(%esp)                    # pass in method->clazz
+    call    dvmResolveInstField                   #  ... to dvmResolveInstField
+    UNSPILL_TMP(%ecx)
+    UNSPILL(rPC)
+    testl   %eax,%eax                             #  ... which returns InstrField ptr
+    jne     .L${opcode}_finish
+    jmp     common_exceptionThrown
+
+.L${opcode}_finish:
+    /*
+     * Currently:
+     *   eax holds resolved field
+     *   ecx holds object
+     *   rIBASE is scratch, but needs to be unspilled
+     *   rINST_FULL holds A
+     */
+    GET_VREG(rINST_FULL,rINST_FULL)              # rINST_FULL<- v[A]
+    movl    offInstField_byteOffset(%eax),%eax   # eax<- byte offset of field
+    UNSPILL(rIBASE)
+    testl   %ecx,%ecx                            # object null?
+    je      common_errNullObject                 # object was null
+    movl    rINST_FULL,(%ecx,%eax)          # obj.field <- v[A](8/16/32 bits)
+    GET_GLUE(%eax)
+    testl   rINST_FULL,rINST_FULL                # stored a NULL?
+    movl    offGlue_cardTable(%eax),%eax         # get card table base
+    FETCH_INST_WORD(2)
+    je      1f                                   # skip card mark if null store
+    shrl    $$GC_CARD_SHIFT,%ecx                 # object head to card number
+    movb    %al,(%eax,%ecx)                      # mark card
+1:
+    ADVANCE_PC(2)
+    GOTO_NEXT
index a8e851c..fb7205b 100644 (file)
@@ -1,2 +1,28 @@
 %verify "executed"
-%include "x86/OP_IPUT_QUICK.S"
+%verify "null object"
+    /* For: iput-object-quick */
+    /* op vA, vB, offset@CCCC */
+    movzbl    rINST_HI,%ecx             # ecx<- BA
+    sarl      $$4,%ecx                  # ecx<- B
+    GET_VREG(%ecx,%ecx)                 # vB (object we're operating on)
+    movzbl    rINST_HI,rINST_FULL
+    andb      $$0xf,rINST_LO            # rINST_FULL<- A
+    GET_VREG(rINST_FULL,rINST_FULL)     # rINST_FULL<- v[A]
+    movzwl    2(rPC),%eax               # eax<- field byte offset
+    testl     %ecx,%ecx                 # is object null?
+    je        common_errNullObject
+    movl      rINST_FULL,(%ecx,%eax,1)
+    GET_GLUE(%eax)
+    jmp       .L${opcode}_finish
+%break
+
+.L${opcode}_finish:
+    testl     rINST_FULL,rINST_FULL         # did we store null?
+    FETCH_INST_WORD(2)
+    movl      offGlue_cardTable(%eax),%eax  # get card table base
+    je        1f                            # skip card mark if null store
+    shrl      $$GC_CARD_SHIFT,%ecx          # object head to card number
+    movb      %al,(%eax,%ecx)               # mark card
+1:
+    ADVANCE_PC(2)
+    GOTO_NEXT
diff --git a/vm/mterp/x86/OP_IPUT_OBJECT_VOLATILE.S b/vm/mterp/x86/OP_IPUT_OBJECT_VOLATILE.S
new file mode 100644 (file)
index 0000000..3959c06
--- /dev/null
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "x86/OP_IPUT_OBJECT.S"
index 60d6fad..e62ec00 100644 (file)
@@ -1,6 +1,6 @@
 %verify "executed"
 %verify "null object"
-    /* For: iput-quick, iput-object-quick */
+    /* For: iput-quick */
     /* op vA, vB, offset@CCCC */
     movzbl    rINST_HI,%ecx             # ecx<- BA
     sarl      $$4,%ecx                  # ecx<- B
diff --git a/vm/mterp/x86/OP_IPUT_VOLATILE.S b/vm/mterp/x86/OP_IPUT_VOLATILE.S
new file mode 100644 (file)
index 0000000..caf007e
--- /dev/null
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "x86/OP_IPUT.S"
diff --git a/vm/mterp/x86/OP_SGET_OBJECT_VOLATILE.S b/vm/mterp/x86/OP_SGET_OBJECT_VOLATILE.S
new file mode 100644 (file)
index 0000000..3b3a492
--- /dev/null
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "x86/OP_SGET.S"
diff --git a/vm/mterp/x86/OP_SGET_VOLATILE.S b/vm/mterp/x86/OP_SGET_VOLATILE.S
new file mode 100644 (file)
index 0000000..3b3a492
--- /dev/null
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "x86/OP_SGET.S"
index 952ca87..440dcfb 100644 (file)
@@ -5,7 +5,7 @@
     /*
      * General 32-bit SPUT handler.
      *
-     * for: sput, sput-object, sput-boolean, sput-byte, sput-char, sput-short
+     * for: sput, sput-boolean, sput-byte, sput-char, sput-short
      */
     /* op vAA, field@BBBB */
     GET_GLUE(%ecx)
index ec0489f..f55d151 100644 (file)
@@ -1,2 +1,49 @@
 %verify "executed"
-%include "x86/OP_SPUT.S"
+%verify "field already resolved"
+%verify "field not yet resolved"
+%verify "field cannot be resolved"
+    /*
+     * SPUT object handler.
+     */
+    /* op vAA, field@BBBB */
+    GET_GLUE(%ecx)
+    movzwl    2(rPC),%eax                        # eax<- field ref BBBB
+    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- DvmDex
+    movl      offDvmDex_pResFields(%ecx),%ecx    # ecx<- dvmDex->pResFields
+    movl      (%ecx,%eax,4),%eax                 # eax<- resolved StaticField
+    testl     %eax,%eax                          # resolved entry null?
+    je        .L${opcode}_resolve                # if not, make it so
+.L${opcode}_finish:     # field ptr in eax
+    movzbl    rINST_HI,%ecx                      # ecx<- AA
+    GET_VREG(%ecx,%ecx)
+    jmp       .L${opcode}_continue
+%break
+
+
+.L${opcode}_continue:
+    movl      %ecx,offStaticField_value(%eax)
+    testl     %ecx,%ecx
+    GET_GLUE(%ecx)
+    FETCH_INST_WORD(2)
+    je        1f
+    movl      offGlue_cardTable(%ecx),%ecx       # get card table base
+    shrl      $$GC_CARD_SHIFT,%eax               # head to card number
+    movb      %cl,(%ecx,%eax)                    # mark card
+1:
+    ADVANCE_PC(2)
+    GOTO_NEXT
+
+.L${opcode}_resolve:
+    GET_GLUE(%ecx)
+    movzwl   2(rPC),%eax                        # eax<- field ref BBBB
+    movl     offGlue_method(%ecx),%ecx          # ecx<- current method
+    EXPORT_PC()                                 # could throw, need to export
+    movl     offMethod_clazz(%ecx),%ecx         # ecx<- method->clazz
+    SPILL(rPC)
+    movl     %eax,OUT_ARG1(%esp)
+    movl     %ecx,OUT_ARG0(%esp)
+    call     dvmResolveStaticField              # eax<- resolved StaticField ptr
+    UNSPILL(rPC)
+    testl    %eax,%eax
+    jne      .L${opcode}_finish                 # success, continue
+    jmp      common_exceptionThrown             # no, handle exception
diff --git a/vm/mterp/x86/OP_SPUT_OBJECT_VOLATILE.S b/vm/mterp/x86/OP_SPUT_OBJECT_VOLATILE.S
new file mode 100644 (file)
index 0000000..afc6668
--- /dev/null
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "x86/OP_SPUT_OBJECT.S"
diff --git a/vm/mterp/x86/OP_SPUT_VOLATILE.S b/vm/mterp/x86/OP_SPUT_VOLATILE.S
new file mode 100644 (file)
index 0000000..ec0489f
--- /dev/null
@@ -0,0 +1,2 @@
+%verify "executed"
+%include "x86/OP_SPUT.S"