+
+/*
+ * Returns "true" if the return-void instructions in this method should
+ * be converted to return-void-barrier.
+ *
+ * This is needed to satisfy a Java Memory Model requirement regarding
+ * the construction of objects with final fields. (This does not apply
+ * to <clinit> or static fields, since appropriate barriers are guaranteed
+ * by the class initialization process.)
+ */
+static bool needsReturnBarrier(Method* method)
+{
+ if (!gDvm.dexOptForSmp)
+ return false;
+ if (strcmp(method->name, "<init>") != 0)
+ return false;
+
+ /*
+ * Check to see if the class has any final fields. If not, we don't
+ * need to generate a barrier instruction.
+ */
+ const ClassObject* clazz = method->clazz;
+ int idx = clazz->ifieldCount;
+ while (--idx >= 0) {
+ if (dvmIsFinalField(&clazz->ifields[idx].field))
+ break;
+ }
+ if (idx < 0)
+ return false;
+
+ /*
+ * In theory, we only need to do this if the method actually modifies
+ * a final field. In practice, non-constructor methods are allowed
+ * to modify final fields by the VM, and there are tools that rely on
+ * this behavior. (The compiler does not allow it.)
+ *
+ * If we alter the verifier to restrict final-field updates to
+ * constructors, we can tighten this up as well.
+ */
+
+ return true;
+}
+
+/*
+ * Convert a return-void to a return-void-barrier.
+ */
+static void rewriteReturnVoid(Method* method, u2* insns)
+{
+ assert((insns[0] & 0xff) == OP_RETURN_VOID);
+ updateOpCode(method, insns, OP_RETURN_VOID_BARRIER);
+}