int _arrayOffset() {
return 0;
}
+
+ /**
+ * For direct buffers, the effective address of the data. This is set
+ * on first use. If the field is zero, this is either not a direct
+ * buffer or the field has not been initialized, and you need to issue
+ * the getEffectiveAddress() call and use the result of that.
+ *
+ * This is strictly an optimization.
+ */
+ int effectiveDirectAddress = 0;
// END android-added
/**
public PlatformAddress getEffectiveAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ // BEGIN android-changed
+ PlatformAddress addr = ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
} else {
assert false : byteBuffer;
return null;
* previously.
*/
public final PlatformAddress getEffectiveAddress() {
- return getBaseAddress().offsetBytes(offset);
+ // BEGIN android-changed
+ PlatformAddress addr = getBaseAddress().offsetBytes(offset);
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
}
/**
public PlatformAddress getEffectiveAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ // BEGIN android-changed
+ PlatformAddress addr = ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
} else {
assert false : byteBuffer;
return null;
public PlatformAddress getEffectiveAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ // BEGIN android-changed
+ PlatformAddress addr = ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
} else {
assert false : byteBuffer;
return null;
public PlatformAddress getEffectiveAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ // BEGIN android-changed
+ PlatformAddress addr = ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
} else {
assert false : byteBuffer;
return null;
public PlatformAddress getEffectiveAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ // BEGIN android-changed
+ PlatformAddress addr = ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
} else {
assert false : byteBuffer;
return null;
}
public PlatformAddress getEffectiveAddress() {
- return ((DirectBuffer) this.wrapped).getEffectiveAddress();
+ // BEGIN android-changed
+ PlatformAddress addr = ((DirectBuffer) this.wrapped).getEffectiveAddress();
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
}
public float getFloat() {
public PlatformAddress getEffectiveAddress() {
if (byteBuffer instanceof DirectBuffer) {
- return ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ // BEGIN android-changed
+ PlatformAddress addr = ((DirectBuffer)byteBuffer).getEffectiveAddress();
+ effectiveDirectAddress = addr.toInt();
+ return addr;
+ // END android-changed
} else {
assert false : byteBuffer;
return null;
Method* methOrgApacheHarmonyLuniPlatformPlatformAddress_on;
Method* methOrgApacheHarmonyNioInternalDirectBuffer_getEffectiveAddress;
int offJavaNioBuffer_capacity;
+ int offJavaNioBuffer_effectiveDirectAddress;
int offOrgApacheHarmonyLuniPlatformPlatformAddress_osaddr;
int voffOrgApacheHarmonyLuniPlatformPlatformAddress_toLong;
return false;
}
+ gDvm.offJavaNioBuffer_effectiveDirectAddress =
+ dvmFindFieldOffset(bufferClass, "effectiveDirectAddress", "I");
+ if (gDvm.offJavaNioBuffer_effectiveDirectAddress < 0) {
+ LOGE("Unable to find Buffer.effectiveDirectAddress\n");
+ return false;
+ }
+
return true;
}
Object* bufObj = (Object*) buf;
Thread* self = _self /*dvmThreadSelf()*/;
- Object* platformAddr;
- JValue callResult;
- void* result = NULL;
+ void* result;
+
+ /*
+ * All Buffer objects have an effectiveDirectAddress field. If it's
+ * nonzero, we can just return that value. If not, we have to call
+ * through DirectBuffer.getEffectiveAddress(), which as a side-effect
+ * will set the effectiveDirectAddress field for direct buffers (and
+ * things that wrap direct buffers).
+ */
+ result = (void*) dvmGetFieldInt(bufObj,
+ gDvm.offJavaNioBuffer_effectiveDirectAddress);
+ if (result != NULL) {
+ //LOGI("fast path for %p\n", buf);
+ goto bail;
+ }
/*
* Start by determining if the object supports the DirectBuffer
*
* If this isn't a direct buffer, the result will be NULL and/or an
* exception will have been thrown.
- *
- * TODO: eliminate the getEffectiveAddress() method call.
*/
+ JValue callResult;
const Method* meth = dvmGetVirtualizedMethod(bufObj->clazz,
gDvm.methOrgApacheHarmonyNioInternalDirectBuffer_getEffectiveAddress);
dvmCallMethodA(self, meth, bufObj, &callResult, NULL);
callResult.l = NULL;
}
- platformAddr = callResult.l;
+ Object* platformAddr = callResult.l;
if (platformAddr == NULL) {
- LOGD("Got request for address of non-direct buffer\n");
+ LOGV("Got request for address of non-direct buffer\n");
goto bail;
}
result = (void*) dvmGetFieldInt(platformAddr,
gDvm.offOrgApacheHarmonyLuniPlatformPlatformAddress_osaddr);
+ //LOGI("slow path for %p --> %p\n", buf, result);
+
bail:
JNI_EXIT();
return result;