+ * Extracts the value of a static field. Provides appropriate barriers
+ * for volatile fields.
+ *
+ * Sub-32-bit values are sign- or zero-extended to fill out 32 bits.
+ */
+static void getStaticFieldValue(const StaticField* sfield, JValue* value)
+{
+ if (!dvmIsVolatileField(&sfield->field)) {
+ /* just copy the whole thing */
+ *value = sfield->value;
+ } else {
+ /* need memory barriers and/or 64-bit atomic ops */
+ switch (sfield->field.signature[0]) {
+ case 'Z':
+ value->i = dvmGetStaticFieldBooleanVolatile(sfield);
+ break;
+ case 'B':
+ value->i = dvmGetStaticFieldByteVolatile(sfield);
+ break;
+ case 'S':
+ value->i = dvmGetStaticFieldShortVolatile(sfield);
+ break;
+ case 'C':
+ value->i = dvmGetStaticFieldCharVolatile(sfield);
+ break;
+ case 'I':
+ value->i = dvmGetStaticFieldIntVolatile(sfield);
+ break;
+ case 'F':
+ value->f = dvmGetStaticFieldFloatVolatile(sfield);
+ break;
+ case 'J':
+ value->j = dvmGetStaticFieldLongVolatile(sfield);
+ break;
+ case 'D':
+ value->d = dvmGetStaticFieldDoubleVolatile(sfield);
+ break;
+ case 'L':
+ case '[':
+ value->l = dvmGetStaticFieldObjectVolatile(sfield);
+ break;
+ default:
+ LOGE("Unhandled field signature '%s'\n", sfield->field.signature);
+ dvmAbort();
+ }
+ }
+}
+
+/*
+ * Extracts the value of an instance field. Provides appropriate barriers
+ * for volatile fields.
+ *
+ * Sub-32-bit values are sign- or zero-extended to fill out 32 bits.
+ */
+static void getInstFieldValue(const InstField* ifield, Object* obj,
+ JValue* value)
+{
+ if (!dvmIsVolatileField(&ifield->field)) {
+ /* use type-specific get; really just 32-bit vs. 64-bit */
+ switch (ifield->field.signature[0]) {
+ case 'Z':
+ value->i = dvmGetFieldBoolean(obj, ifield->byteOffset);
+ break;
+ case 'B':
+ value->i = dvmGetFieldByte(obj, ifield->byteOffset);
+ break;
+ case 'S':
+ value->i = dvmGetFieldShort(obj, ifield->byteOffset);
+ break;
+ case 'C':
+ value->i = dvmGetFieldChar(obj, ifield->byteOffset);
+ break;
+ case 'I':
+ value->i = dvmGetFieldInt(obj, ifield->byteOffset);
+ break;
+ case 'F':
+ value->f = dvmGetFieldFloat(obj, ifield->byteOffset);
+ break;
+ case 'J':
+ value->j = dvmGetFieldLong(obj, ifield->byteOffset);
+ break;
+ case 'D':
+ value->d = dvmGetFieldDouble(obj, ifield->byteOffset);
+ break;
+ case 'L':
+ case '[':
+ value->l = dvmGetFieldObject(obj, ifield->byteOffset);
+ break;
+ default:
+ LOGE("Unhandled field signature '%s'\n", ifield->field.signature);
+ dvmAbort();
+ }
+ } else {
+ /* need memory barriers and/or 64-bit atomic ops */
+ switch (ifield->field.signature[0]) {
+ case 'Z':
+ value->i = dvmGetFieldBooleanVolatile(obj, ifield->byteOffset);
+ break;
+ case 'B':
+ value->i = dvmGetFieldByteVolatile(obj, ifield->byteOffset);
+ break;
+ case 'S':
+ value->i = dvmGetFieldShortVolatile(obj, ifield->byteOffset);
+ break;
+ case 'C':
+ value->i = dvmGetFieldCharVolatile(obj, ifield->byteOffset);
+ break;
+ case 'I':
+ value->i = dvmGetFieldIntVolatile(obj, ifield->byteOffset);
+ break;
+ case 'F':
+ value->f = dvmGetFieldFloatVolatile(obj, ifield->byteOffset);
+ break;
+ case 'J':
+ value->j = dvmGetFieldLongVolatile(obj, ifield->byteOffset);
+ break;
+ case 'D':
+ value->d = dvmGetFieldDoubleVolatile(obj, ifield->byteOffset);
+ break;
+ case 'L':
+ case '[':
+ value->l = dvmGetFieldObjectVolatile(obj, ifield->byteOffset);
+ break;
+ default:
+ LOGE("Unhandled field signature '%s'\n", ifield->field.signature);
+ dvmAbort();
+ }
+ }
+}
+
+/*
+ * Copies the value of the static or instance field into "*value".
+ */
+static void getFieldValue(const Field* field, Object* obj, JValue* value)
+{
+ if (dvmIsStaticField(field)) {
+ return getStaticFieldValue((const StaticField*) field, value);
+ } else {
+ return getInstFieldValue((const InstField*) field, obj, value);
+ }
+}
+
+/*
+ * Sets the value of a static field. Provides appropriate barriers
+ * for volatile fields.
+ */
+static void setStaticFieldValue(StaticField* sfield, const JValue* value)
+{
+ if (!dvmIsVolatileField(&sfield->field)) {
+ switch (sfield->field.signature[0]) {
+ case 'L':
+ case '[':
+ dvmSetStaticFieldObject(sfield, value->l);
+ break;
+ default:
+ /* just copy the whole thing */
+ sfield->value = *value;
+ break;
+ }
+ } else {
+ /* need memory barriers and/or 64-bit atomic ops */
+ switch (sfield->field.signature[0]) {
+ case 'Z':
+ dvmSetStaticFieldBooleanVolatile(sfield, value->z);
+ break;
+ case 'B':
+ dvmSetStaticFieldByteVolatile(sfield, value->b);
+ break;
+ case 'S':
+ dvmSetStaticFieldShortVolatile(sfield, value->s);
+ break;
+ case 'C':
+ dvmSetStaticFieldCharVolatile(sfield, value->c);
+ break;
+ case 'I':
+ dvmSetStaticFieldIntVolatile(sfield, value->i);
+ break;
+ case 'F':
+ dvmSetStaticFieldFloatVolatile(sfield, value->f);
+ break;
+ case 'J':
+ dvmSetStaticFieldLongVolatile(sfield, value->j);
+ break;
+ case 'D':
+ dvmSetStaticFieldDoubleVolatile(sfield, value->d);
+ break;
+ case 'L':
+ case '[':
+ dvmSetStaticFieldObjectVolatile(sfield, value->l);
+ break;
+ default:
+ LOGE("Unhandled field signature '%s'\n", sfield->field.signature);
+ dvmAbort();
+ }
+ }
+}
+
+/*
+ * Sets the value of an instance field. Provides appropriate barriers
+ * for volatile fields.
+ */
+static void setInstFieldValue(InstField* ifield, Object* obj,
+ const JValue* value)
+{
+ if (!dvmIsVolatileField(&ifield->field)) {
+ /* use type-specific set; really just 32-bit vs. 64-bit */
+ switch (ifield->field.signature[0]) {
+ case 'Z':
+ dvmSetFieldBoolean(obj, ifield->byteOffset, value->z);
+ break;
+ case 'B':
+ dvmSetFieldByte(obj, ifield->byteOffset, value->b);
+ break;
+ case 'S':
+ dvmSetFieldShort(obj, ifield->byteOffset, value->s);
+ break;
+ case 'C':
+ dvmSetFieldChar(obj, ifield->byteOffset, value->c);
+ break;
+ case 'I':
+ dvmSetFieldInt(obj, ifield->byteOffset, value->i);
+ break;
+ case 'F':
+ dvmSetFieldFloat(obj, ifield->byteOffset, value->f);
+ break;
+ case 'J':
+ dvmSetFieldLong(obj, ifield->byteOffset, value->j);
+ break;
+ case 'D':
+ dvmSetFieldDouble(obj, ifield->byteOffset, value->d);
+ break;
+ case 'L':
+ case '[':
+ dvmSetFieldObject(obj, ifield->byteOffset, value->l);
+ break;
+ default:
+ LOGE("Unhandled field signature '%s'\n", ifield->field.signature);
+ dvmAbort();
+ }
+#if ANDROID_SMP != 0
+ /*
+ * Special handling for final fields on SMP systems. We need a
+ * store/store barrier here (JMM requirement).
+ */
+ if (dvmIsFinalField(&ifield->field)) {
+ ANDROID_MEMBAR_FULL(); /* TODO: replace full bar with store/store */
+ }
+#endif
+ } else {
+ /* need memory barriers and/or 64-bit atomic ops */
+ switch (ifield->field.signature[0]) {
+ case 'Z':
+ dvmSetFieldBooleanVolatile(obj, ifield->byteOffset, value->z);
+ break;
+ case 'B':
+ dvmSetFieldByteVolatile(obj, ifield->byteOffset, value->b);
+ break;
+ case 'S':
+ dvmSetFieldShortVolatile(obj, ifield->byteOffset, value->s);
+ break;
+ case 'C':
+ dvmSetFieldCharVolatile(obj, ifield->byteOffset, value->c);
+ break;
+ case 'I':
+ dvmSetFieldIntVolatile(obj, ifield->byteOffset, value->i);
+ break;
+ case 'F':
+ dvmSetFieldFloatVolatile(obj, ifield->byteOffset, value->f);
+ break;
+ case 'J':
+ dvmSetFieldLongVolatile(obj, ifield->byteOffset, value->j);
+ break;
+ case 'D':
+ dvmSetFieldDoubleVolatile(obj, ifield->byteOffset, value->d);
+ break;
+ case 'L':
+ case '[':
+ dvmSetFieldObjectVolatile(obj, ifield->byteOffset, value->l);
+ break;
+ default:
+ LOGE("Unhandled field signature '%s'\n", ifield->field.signature);
+ dvmAbort();
+ }
+ }
+}
+
+/*
+ * Copy "*value" into the static or instance field.
+ */
+static void setFieldValue(Field* field, Object* obj, const JValue* value)
+{
+ if (dvmIsStaticField(field)) {
+ return setStaticFieldValue((StaticField*) field, value);
+ } else {
+ return setInstFieldValue((InstField*) field, obj, value);
+ }
+}
+
+
+
+/*