merged volatile memory barriers
authorsr <none@none>
Tue, 17 Nov 2009 07:40:45 +0000 (08:40 +0100)
committersr <none@none>
Tue, 17 Nov 2009 07:40:45 +0000 (08:40 +0100)
1  2 
src/native/jni.cpp
src/vm/jit/codegen-common.cpp
src/vm/jit/patcher-common.cpp
src/vm/jit/patcher-common.hpp
src/vm/jit/x86_64/arch.h

diff --combined src/native/jni.cpp
index 431b2c9bcab03833889a0835e59aee91e7622751,f6eb7082a502a5a70239897fd48a54549b198e89..6e850fd2bac0db539175b06ad3fe7c06ea6b6b8a
@@@ -2069,6 -2069,8 +2069,8 @@@ jobject _Jv_JNI_GetObjectField(JNIEnv *
  #define SET_FIELD(o,type,f,value) \
      *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
  
+ #define GET_FIELDINFO(f) ((fieldinfo*) (f))
  #define JNI_SET_FIELD(name, type, intern)                                  \
  void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID,  \
                                                          type value)                                  \
                                                                             \
        SET_FIELD(LLNI_DIRECT((java_handle_t *) obj), intern, fieldID, value); \
                                                                               \
-       LLNI_CRITICAL_START;                                                   \
+       LLNI_CRITICAL_END;                                                     \
+                                                                                                                                                  \
+       if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE)                      \
+               Atomic::memory_barrier();                                          \
  }
  
  JNI_SET_FIELD(Boolean, jboolean, s4)
@@@ -2102,6 -2107,9 +2107,9 @@@ void _Jv_JNI_SetObjectField(JNIEnv *env
        SET_FIELD(obj, java_handle_t*, fieldID, LLNI_UNWRAP((java_handle_t*) value));
  
        LLNI_CRITICAL_END;
+       if (GET_FIELDINFO(fieldID)->flags & ACC_VOLATILE)
+               Atomic::memory_barrier();
  }
  
  
@@@ -2439,6 -2447,9 +2447,9 @@@ void _Jv_JNI_SetStatic##name##Field(JNI
                        return;                                            \
                                                                 \
        f->value->field = value;                                   \
+                                                                                                                          \
+       if (f->flags & ACC_VOLATILE)                               \
+               Atomic::memory_barrier();                              \
  }
  
  JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
@@@ -2467,6 -2478,9 +2478,9 @@@ void _Jv_JNI_SetStaticObjectField(JNIEn
                        return;
  
        f->value->a = LLNI_UNWRAP((java_handle_t *) value);
+       if (f->flags & ACC_VOLATILE)
+               Atomic::memory_barrier();
  }
  
  
@@@ -2876,7 -2890,7 +2890,7 @@@ void _Jv_JNI_Release##name##ArrayElemen
  }
  
  JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
 -JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    int8_t)
 +JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
  JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
  JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
  JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
@@@ -2907,7 -2921,7 +2921,7 @@@ void _Jv_JNI_Get##name##ArrayRegion(JNI
  }
  
  JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
 -JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    int8_t)
 +JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
  JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
  JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
  JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
@@@ -2938,7 -2952,7 +2952,7 @@@ void _Jv_JNI_Set##name##ArrayRegion(JNI
  }
  
  JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
 -JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    int8_t)
 +JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
  JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
  JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
  JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
@@@ -2965,10 -2979,14 +2979,10 @@@ jint jni_RegisterNatives(JNIEnv* env, j
  
        classinfo* c = LLNI_classinfo_unwrap(clazz);
  
 -      /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
 -      if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
 -      */
 -
        NativeMethods& nm = VM::get_current()->get_nativemethods();
        nm.register_methods(c->name, methods, nMethods);
  
 -    return 0;
 +      return 0;
  }
  
  
index a44c52fb3b6da56571e88a9262d095303d62a255,9dc00a90bc10f91ff7d1d637f16b88be837bd65c..5536ba819c29871a28a64885a8905814e161f586
@@@ -1356,13 -1356,9 +1356,13 @@@ bool codegen_emit(jitdata *jd
                        case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2    */
                        case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant    */
                                              /* sx.val.i = constant                      */
 +                      case ICMD_IMULPOW2:   /* ..., value  ==> ..., value * (2 ^ constant) */
 +                                            /* sx.val.i = constant                      */
                        case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2    */
                        case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant    */
                                              /* sx.val.l = constant                      */
 +                      case ICMD_LMULPOW2:   /* ..., value  ==> ..., value * (2 ^ constant) */
 +                                            /* sx.val.l = constant                      */
                        case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2    */
                        case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2    */
                        case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant   */
  #if defined(__I386__)
                                // Generate architecture specific instructions.
                                codegen_emit_instruction(jd, iptr);
+                               break;
  #else
+                       {
+                               fieldinfo* fi;
+                               patchref_t* pr;
                                if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                        unresolved_field* uf = iptr->sx.s23.s3.uf;
                                        fieldtype = uf->fieldref->parseddesc.fd->type;
                                        disp      = dseg_add_unique_address(cd, 0);
  
-                                       patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
+                                       pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
                                }
                                else {
-                                       fieldinfo* fi = iptr->sx.s23.s3.fmiref->p.field;
+                                       fi        = iptr->sx.s23.s3.fmiref->p.field;
                                        fieldtype = fi->type;
                                        disp      = dseg_add_address(cd, fi->value);
  
                                        }
                                }
  
+ #if defined(USES_PATCHABLE_MEMORY_BARRIER)
+                               codegen_emit_patchable_barrier(iptr, cd, pr, fi);
+ #endif
                                // XXX X86_64: Here We had this:
                                /* This approach is much faster than moving the field
                                   address inline into a register. */
  
 -                              // XXX ARM: M_DSEG_LOAD(REG_ITMP3, disp);
                                M_ALD_DSEG(REG_ITMP1, disp);
  
                                switch (fieldtype) {
                                        break;
                                }
                                emit_store_dst(jd, iptr, d);
- #endif
                                break;
+                       }
+ #endif
  
                        case ICMD_PUTSTATIC:  /* ..., value  ==> ...                      */
  
  #if defined(__I386__)
                                // Generate architecture specific instructions.
                                codegen_emit_instruction(jd, iptr);
+                               break;
  #else
+                       {
+                               fieldinfo* fi;
+                               patchref_t* pr;
                                if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                        unresolved_field* uf = iptr->sx.s23.s3.uf;
                                        fieldtype = uf->fieldref->parseddesc.fd->type;
                                        disp      = dseg_add_unique_address(cd, 0);
  
-                                       patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
+                                       pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
                                }
                                else {
-                                       fieldinfo* fi = iptr->sx.s23.s3.fmiref->p.field;
+                                       fi = iptr->sx.s23.s3.fmiref->p.field;
                                        fieldtype = fi->type;
                                        disp      = dseg_add_address(cd, fi->value);
  
                                /* This approach is much faster than moving the field
                                   address inline into a register. */
  
 -                              // XXX ARM: M_DSEG_LOAD(REG_ITMP3, disp);
                                M_ALD_DSEG(REG_ITMP1, disp);
  
                                switch (fieldtype) {
                                        M_DST(s1, REG_ITMP1, 0);
                                        break;
                                }
+ #if defined(USES_PATCHABLE_MEMORY_BARRIER)
+                               codegen_emit_patchable_barrier(iptr, cd, pr, fi);
  #endif
                                break;
+                       }
+ #endif
  
                        /* branch operations **********************************************/
  
  
                                REPLACEMENT_POINT_RETURN(cd, iptr);
                                s1 = emit_load_s1(jd, iptr, REG_FRESULT);
 -                              // XXX ARM: Here this was M_CAST_F2I(s1, REG_RESULT);
 +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                emit_fmove(cd, s1, REG_FRESULT);
 +#else
 +                              M_CAST_F2I(s1, REG_RESULT);
 +#endif
                                goto nowperformreturn;
  
                        case ICMD_DRETURN:    /* ..., retvalue ==> ...                    */
  
                                REPLACEMENT_POINT_RETURN(cd, iptr);
                                s1 = emit_load_s1(jd, iptr, REG_FRESULT);
 -                              // XXX ARM: Here this was M_CAST_D2L(s1, REG_RESULT_PACKED);
 +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                emit_dmove(cd, s1, REG_FRESULT);
 +#else
 +                              M_CAST_D2L(s1, REG_LRESULT);
 +#endif
                                goto nowperformreturn;
  
  nowperformreturn:
@@@ -1962,36 -1972,36 +1980,36 @@@ gen_method
                                                continue;
  
                                        if (!md->params[i].inmemory) {
 -                                              assert(ARG_CNT > 0);
 -                                              s1 = emit_load(jd, iptr, var, d);
 -
                                                switch (var->type) {
                                                case TYPE_ADR:
                                                case TYPE_INT:
 -                                                      assert(INT_ARG_CNT > 0);
 +                                                      s1 = emit_load(jd, iptr, var, d);
                                                        emit_imove(cd, s1, d);
                                                        break;
  
 -#if 0 //XXX For ARM:
 -if (!md->params[s3].inmemory) {
 -      s1 = emit_load(jd, iptr, var, REG_FTMP1);
 -      if (IS_2_WORD_TYPE(var->type))
 -              M_CAST_D2L(s1, d);
 -      else
 -              M_CAST_F2I(s1, d);
 -}
 -#endif //XXX End of ARM!
 -
                                                case TYPE_LNG:
 +                                                      s1 = emit_load(jd, iptr, var, d);
                                                        emit_lmove(cd, s1, d);
                                                        break;
  
                                                case TYPE_FLT:
 +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
 +                                                      s1 = emit_load(jd, iptr, var, d);
                                                        emit_fmove(cd, s1, d);
 +#else
 +                                                      s1 = emit_load(jd, iptr, var, REG_FTMP1);
 +                                                      M_CAST_F2I(s1, d);
 +#endif
                                                        break;
  
                                                case TYPE_DBL:
 +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
 +                                                      s1 = emit_load(jd, iptr, var, d);
                                                        emit_dmove(cd, s1, d);
 +#else
 +                                                      s1 = emit_load(jd, iptr, var, REG_FTMP1);
 +                                                      M_CAST_D2L(s1, d);
 +#endif
                                                        break;
                                                }
                                        }
                                        emit_store_dst(jd, iptr, s1);
                                        break;
  
 -#if 0 //XXX For ARM!!!
 -#if !defined(ENABLE_SOFTFLOAT)
 -                              } else {
 -                                      s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
 -                                      if (IS_2_WORD_TYPE(d))
 -                                              M_CAST_L2D(REG_RESULT_PACKED, s1);
 -                                      else
 -                                              M_CAST_I2F(REG_RESULT, s1);
 -                              }
 -#endif /* !defined(ENABLE_SOFTFLOAT) */
 -#endif //XXX End of ARM
 -
                                case TYPE_FLT:
 +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
                                        emit_fmove(cd, REG_FRESULT, s1);
 +#else
 +                                      s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
 +                                      M_CAST_I2F(REG_RESULT, s1);
 +#endif
                                        emit_store_dst(jd, iptr, s1);
                                        break;
  
                                case TYPE_DBL:
 +#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
                                        emit_dmove(cd, REG_FRESULT, s1);
 +#else
 +                                      s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
 +                                      M_CAST_L2D(REG_LRESULT, s1);
 +#endif
                                        emit_store_dst(jd, iptr, s1);
                                        break;
  
index c364646be172ee8b249bb4c4fcc860c6b581c741,dcafac7b7eedad04c3333d23124af04a9e970710..6acd9687c493440c8548b4509a9c584a8642b4d6
@@@ -45,7 -45,6 +45,7 @@@
  
  #include "vm/breakpoint.hpp"
  #include "vm/exceptions.hpp"
 +#include "vm/hook.hpp"
  #include "vm/initialize.hpp"
  #include "vm/options.h"
  #include "vm/os.hpp"
@@@ -210,34 -209,37 +210,37 @@@ void patcher_list_show(codeinfo *code
  
     Appends a new patcher reference to the list of patching positions.
  
+    Returns a pointer to the newly created patchref_t.
  *******************************************************************************/
  
void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
patchref_t *patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
  {
-       codegendata *cd;
-       codeinfo    *code;
-       s4           patchmpc;
-       cd       = jd->cd;
-       code     = jd->code;
-       patchmpc = cd->mcodeptr - cd->mcodebase;
+       codegendata *cd   = jd->cd;
+       codeinfo    *code = jd->code;
  
  #if defined(ALIGN_PATCHER_TRAP)
        emit_patcher_alignment(cd);
-       patchmpc = cd->mcodeptr - cd->mcodebase;
  #endif
  
+       int32_t patchmpc = cd->mcodeptr - cd->mcodebase;
  #if !defined(NDEBUG)
        if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
                os::abort("patcher_add_patch_ref: different patchers at same position.");
  #endif
  
+ #if defined(USES_PATCHABLE_MEMORY_BARRIER)
+       PATCHER_NOPS;
+ #endif
        // Set patcher information (mpc is resolved later).
        patchref_t pr;
  
        pr.mpc     = patchmpc;
        pr.datap   = 0;
        pr.disp    = disp;
+       pr.disp_mb = 0;
        pr.patcher = patcher;
        pr.ref     = ref;
        pr.mcode   = 0;
  
        cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
  #endif
+       return &code->patchers->back();
  }
  
  
@@@ -356,7 -360,7 +361,7 @@@ static int patcher_depth = 0
  #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
  #endif /* !defined(NDEBUG) */
  
 -java_handle_t *patcher_handler(u1 *pc)
 +bool patcher_handler(u1 *pc)
  {
        codeinfo      *code;
        patchref_t    *pr;
                }
  #endif
                code->patchers->unlock();
 -              return NULL;
 +              return true;
        }
  
  #if !defined(NDEBUG)
        }
  #endif
  
 -      // Check for return value and exit accordingly.
 -      if (result == false) {
 -              // Mangle the pending exception.
 +      // Check return value and mangle the pending exception.
 +      if (result == false)
                resolve_handle_pending_exception(true);
  
 -              // Get the exception and return it.
 -              java_handle_t* e = exceptions_get_and_clear_exception();
 -
 -              code->patchers->unlock();
 -
 -              return e;
 -      }
 -
 -      pr->done = true; /* XXX this is only preliminary to prevent double-patching */
 +      // XXX This is only preliminary to prevent double-patching.
 +      else
 +              pr->done = true;
  
        code->patchers->unlock();
  
 -      return NULL;
 +      return result;
  }
  
  
@@@ -570,8 -581,13 +575,8 @@@ bool patcher_breakpoint(patchref_t *pr
        // Get stuff from the patcher reference.
        Breakpoint* breakp = (Breakpoint*) pr->ref;
  
 -#if defined(ENABLE_JVMTI)
 -      methodinfo* m = breakp->method;
 -      int32_t     l = breakp->location;
 -
 -      log_message_method("JVMTI: Reached breakpoint in method ", m);
 -      log_println("JVMTI: Reached breakpoint at location %d", l);
 -#endif
 +      // Hook point when a breakpoint was triggered.
 +      Hook::breakpoint(breakp);
  
        // In case the breakpoint wants to be kept active, we simply
        // fail to "patch" at this point.
index 3f488809e74e7e37e5cf46d8b294dd526654ba80,e51582d72eda21f94793df501417af814b576151..684b41c13a8c28f846aa398237af6ea390da78bd
@@@ -48,9 -48,10 +48,10 @@@ typedef struct patchref_t patchref_t
  *******************************************************************************/
  
  struct patchref_t {
-       ptrint       mpc;           /* absolute position in code segment          */
-       ptrint       datap;         /* absolute position in data segment          */
-       s4           disp;          /* displacement of ref in the data segment    */
+       uintptr_t    mpc;           /* absolute position in code segment          */
+       uintptr_t    datap;         /* absolute position in data segment          */
+       int32_t      disp;          /* displacement of ref in the data segment    */
+       int32_t      disp_mb;       /* auxiliary code displacement (for membar)   */
        functionptr  patcher;       /* patcher function to call                   */
        void*        ref;           /* reference passed                           */
        uint32_t     mcode;         /* machine code to be patched back in         */
@@@ -75,7 -76,7 +76,7 @@@ void patcher_list_free(codeinfo *code)
  void patcher_list_show(codeinfo *code);
  #endif
  
void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp);
patchref_t *patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp);
  
  void patcher_resolve(jitdata* jd);
  
@@@ -85,7 -86,7 +86,7 @@@ bool patcher_is_patched_at(void* pc)
  // MD function.
  bool patcher_is_valid_trap_instruction_at(void* pc);
  
 -java_handle_t *patcher_handler(u1 *pc);
 +bool patcher_handler(u1 *pc);
  
  
  /* empty patcher (just patches back original mcode) ***************************/
diff --combined src/vm/jit/x86_64/arch.h
index 7e8457cce12678f1684f6e821d8ae61c0d0f018f,ef425cb2148fa98812c8c205de464d3f913bd3f7..ff74f82bbc5847bc9f75646066230cba39778139
  
  #define STACKFRMAE_RA_BETWEEN_FRAMES              1
  #define STACKFRAME_RA_TOP_OF_FRAME                0
 +#define STACKFRAME_RA_LINKAGE_AREA                0
  #define STACKFRAME_LEAFMETHODS_RA_REGISTER        0
  #define STACKFRAME_SYNC_NEEDS_TWO_SLOTS           0
  
  
  #define CAS_PROVIDES_FULL_BARRIER        1
  
+ #define USES_PATCHABLE_MEMORY_BARRIER    1
  #endif /* _ARCH_H */
  
  
   * c-basic-offset: 4
   * tab-width: 4
   * End:
+  * vim:noexpandtab:sw=4:ts=4:
   */