History log of /dalvik/vm/Jni.cpp
Revision Date Author Comments
66a6e44bafabc957eb4eaaddbbb21e5f130c8aad 06-Apr-2012 Elliott Hughes <enh@google.com> Throw ArrayStoreException instead of corrupting the heap.

Protect against bad calls to SetObjectArrayElement. Found while debugging
a Chrome crash. (This will make Chrome fail at the point where it does the
invalid operation rather than later, but we already merged the fix upstream.)

Change-Id: Ie7b2238d99f2ee4dde46342eb77cfec0495a30e7
b74e7190e86d559712747e5cdb31a0d390b7af7d 16-Feb-2012 Iliyan Malchev <malchev@google.com> Replace malloc() followed by memset() to zero with calloc()

Bionic's calloc() is smart enough to not zero out memory if it gets that memory
from an anonyous mmap. Thus, if we use malloc for large allocations, we cause
unnecessary memory duplication by following the malloc() with a memset().

An even better approach would be to replace the known large calloc() calls with
dvmAllocRegion() allocation.

Change-Id: Id308f541c9a040d5929bf991b6c2bfdefb823c3c
c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2ef 06-Jan-2012 Steve Block <steveblock@google.com> Rename (IF_)LOGE(_IF) to (IF_)ALOGE(_IF) DO NOT MERGE

See https://android-git.corp.google.com/g/#/c/157220

Also fix an occurrence of LOGW missed in an earlier change.

Bug: 5449033
Change-Id: I2e3b23839e6dcd09015d6402280e9300c75e3406
e8e1ddccd616e8226b7cc1e4e9fdb327429249e8 06-Jan-2012 Steve Block <steveblock@google.com> Rename (IF_)LOGW(_IF) to (IF_)ALOGW(_IF) DO NOT MERGE

See https://android-git.corp.google.com/g/157065

Bug: 5449033
Change-Id: Ia5d301248024df26c2a29dabdfe738e39ec87c82
4308417beec548c2b2c06ecec4f7f4a965b09fb2 04-Jan-2012 Steve Block <steveblock@google.com> Rename (IF_)LOGI(_IF) to (IF_)ALOGI(_IF) DO NOT MERGE

See https://android-git.corp.google.com/g/156801

Bug: 5449033
Change-Id: Ic558031c75b3702d90eb78bd730501ae5d3c077b
062bf509a77fce9dfcb7e7b2e401cf2a124d83d5 20-Dec-2011 Steve Block <steveblock@google.com> Rename (IF_)LOGD(_IF) to (IF_)ALOGD(_IF) DO NOT MERGE

See https://android-git.corp.google.com/g/156016

Bug: 5449033
Change-Id: Ic663376d1ad6a6cb14bf81405ad9afd247cf2f60
de68817bdae0ca038d824ba79a70ac17cae405e6 03-Nov-2011 Elliott Hughes <enh@google.com> Knock ::self() out of the ParseXml profile.

New profile (>=0.6, which is where the original seems to have cut off):

47 11.0070 dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)
30 7.0258 dvmChangeStatus(Thread*, ThreadStatus)
29 6.7916 addLocalReference(Thread*, Object*)
26 6.0890 dexDecodeDebugInfo(DexFile const*, DexCode const*, char const*, unsigned int, unsigned int, int (*)(void*, unsigned int, unsigned int), void (*)(void*, unsigned short, unsigned int, unsigned int, char const*, char const*, char const*), void*)
22 5.1522 dalvik_inst
15 3.5129 lockMonitor(Thread*, Monitor*)
14 3.2787 dvmLineNumFromPC
13 3.0445 javaLangString_equals(unsigned int, unsigned int, unsigned int, unsigned int, JValue*)
13 3.0445 scanObject(Object const*, GcMarkContext*)
12 2.8103 ScopedJniThreadState::ScopedJniThreadState(_JNIEnv*)
12 2.8103 common_invokeMethodNoRange
12 2.8103 dvmDecodeIndirectRef(Thread*, _jobject*)
9 2.1077 IndirectRefTable::add(unsigned int, Object*)
9 2.1077 ReleasePrimitiveArrayCritical(_JNIEnv*, _jarray*, void*, int)
9 2.1077 markObjectNonNull(Object const*, GcMarkContext*, bool)
9 2.1077 unpinPrimitiveArray(ArrayObject*)
8 1.8735 getCodeAddrCommon(unsigned short const*, bool)
7 1.6393 dexStringByTypeIdx(DexFile const*, unsigned int)
7 1.6393 dvmHeapSourceAlloc(unsigned int)
6 1.4052 GetPrimitiveArrayCritical(_JNIEnv*, _jarray*, unsigned char*)
6 1.4052 dvmPlatformInvoke
6 1.4052 pinPrimitiveArray(ArrayObject*)
6 1.4052 readUnsignedLeb128(unsigned char const**)
6 1.4052 scanFields(Object const*, GcMarkContext*)
5 1.1710 IndirectRefTable::get(void*) const
5 1.1710 dvmFindInReferenceTable(ReferenceTable const*, Object**, Object*)
4 0.9368 common_returnFromMethod
4 0.9368 dvmAddToReferenceTable(ReferenceTable*, Object*)
4 0.9368 dvmHeapBitmapScanWalk(HeapBitmap*, void (*)(Object*, void*, void*), void*)
4 0.9368 dvmInterpret(Thread*, Method const*, JValue*)
4 0.9368 dvmLockObject
4 0.9368 dvmMalloc(unsigned int, int)
4 0.9368 findPackedSwitchIndex(unsigned short const*, int, int)
4 0.9368 readStringIdx(DexFile const*, unsigned char const**)
4 0.9368 unlockMonitor(Thread*, Monitor*)
3 0.7026 dvmSetFinalizable

Change-Id: Ic5c36859f6810413bd0b48aad1d99da7daa6e8ba
68ecde1134a8d05803552fcd82994053ada3e80d 27-Oct-2011 Jeff Brown <jeffbrown@google.com> DO NOT MERGE: Optimize IndirectRefTable.

Removed unused debugging code that maintained pointers to the
4 previous objects in each slot.

Promoted the serial number property of a slot to be first class.
This is a sufficiently cheap and useful check to perform that we
might as well always do it.

Changed get() and remove() so they check the validity of the
references at the same time as they retrieve them. They're
also a bit smarter about checking the reference kind given
that they can assume that the table will only contain references
of one kind. The checks are now much more consistent.
For example, remove() used to check whether an index was
stale only in the case where it was not removing the top entry
(now it always checks).

Made add() return NULL instead of dvmAbort()'ing in the case
where the table overflowed and ensure we don't blow away the
table in that cases. This change resolves an issue with
TestIndirectRefTable.cpp which deliberately overflows the table
and expects add() to return NULL (as documented!). As it
happens, the add() method is called in exactly 3 places in
Jni.cpp. In each of those cases, the code was written to
handle a NULL result and only in the case of adding a weak
global reference did it not abort. Fixed the weak global
reference case to be consistent with the others.

Changed the signature of contains() to take an Object* since
that's what we're actually looking for inside the table.

Added a couple of calls to dump() in TestIndirectRefTable.cpp
for visual inspection of its correctness.

Performance as measured by TestIndirectRefTable on same hardware.

Old implementation:
- Add/remove 100 objects FIFO order, 100000 iterations, 0.023ms / iteration
- Add/remove 100 objects LIFO order, 100000 iterations, 0.020ms / iteration
- Get 100 objects, 100000 iterations, 0.009ms / iteration

New implementation:
- Add/remove 100 objects FIFO order, 100000 iterations, 0.010ms / iteration
- Add/remove 100 objects LIFO order, 100000 iterations, 0.009ms / iteration
- Get 100 objects, 100000 iterations, 0.002ms / iteration

Cherry-pick from master.

Conflicts:

vm/IndirectRefTable.cpp

Change-Id: I157f3c1ba598137222878b8e6a5890efb744fe76
5552e62455d486d19e5986a67ae2545411d50fbe 27-Oct-2011 Jeff Brown <jeffbrown@google.com> Optimize IndirectRefTable.

Removed unused debugging code that maintained pointers to the
4 previous objects in each slot.

Promoted the serial number property of a slot to be first class.
This is a sufficiently cheap and useful check to perform that we
might as well always do it.

Changed get() and remove() so they check the validity of the
references at the same time as they retrieve them. They're
also a bit smarter about checking the reference kind given
that they can assume that the table will only contain references
of one kind. The checks are now much more consistent.
For example, remove() used to check whether an index was
stale only in the case where it was not removing the top entry
(now it always checks).

Made add() return NULL instead of dvmAbort()'ing in the case
where the table overflowed and ensure we don't blow away the
table in that cases. This change resolves an issue with
TestIndirectRefTable.cpp which deliberately overflows the table
and expects add() to return NULL (as documented!). As it
happens, the add() method is called in exactly 3 places in
Jni.cpp. In each of those cases, the code was written to
handle a NULL result and only in the case of adding a weak
global reference did it not abort. Fixed the weak global
reference case to be consistent with the others.

Changed the signature of contains() to take an Object* since
that's what we're actually looking for inside the table.

Added a couple of calls to dump() in TestIndirectRefTable.cpp
for visual inspection of its correctness.

Performance as measured by TestIndirectRefTable on same hardware.

Old implementation:
- Add/remove 100 objects FIFO order, 100000 iterations, 0.023ms / iteration
- Add/remove 100 objects LIFO order, 100000 iterations, 0.020ms / iteration
- Get 100 objects, 100000 iterations, 0.009ms / iteration

New implementation:
- Add/remove 100 objects FIFO order, 100000 iterations, 0.010ms / iteration
- Add/remove 100 objects LIFO order, 100000 iterations, 0.009ms / iteration
- Get 100 objects, 100000 iterations, 0.002ms / iteration

Change-Id: I1c904eb03bc8dd9822e6d9cce702c696e976974e
92c1f6f1b4249e4e379452ee7b49f027052bf4ce 20-Oct-2011 Steve Block <steveblock@google.com> Rename (IF_)LOGV(_IF) to (IF_)ALOGV(_IF) DO NOT MERGE

See https://android-git.corp.google.com/g/#/c/143865

Bug: 5449033
Change-Id: I8bd96961e369a08e86ff78b82d90f20f42787eb1
8bc8bf71a52e17d483021b4c9dc8e735d9bce3ed 20-Jul-2011 Elliott Hughes <enh@google.com> Don't use dvmIsValidObject outside the GC.

Use dvmIsHeapPointer outside the GC. (This still isn't safe because there's
no synchronization when dealing with the HeapSource.)

Bug: 5049447
Change-Id: Ie0b325ef0a92687ea1eaf1491a4bb832298893c5
259a8a5154c63a793ea0ee438d146acda7d990b6 12-Jul-2011 Elliott Hughes <enh@google.com> Fix the jweak implementation.

We need to distinguish between "cleared weak global" and "deleted weak global".
Previously we used NULL for both. Now we add a magic value for cleared weak
globals. I've also switched the GC over to using iterators, so IndirectRefTable
itself becomes responsible for not showing bad pointers to the GC.

I've also improved the reference table dumping to cope with the new scheme and
to be a bit easier to read (through extra indentation).

Bug: 4260055
Change-Id: I26af301fb2b46d014c6f6b0915a8f8a7fb6d7c5b
ea333384b92db9c400be1b4c8cb6992d9ba5f14d 11-Jul-2011 Elliott Hughes <enh@google.com> Add JNI app bug workarounds.

Specifically, this hands out direct pointers for all local references,
and lets you use a JNIEnv* on the wrong thread. This is off by default,
but enabled for apps that don't have ICS as their targetSdkVersion.

Bug: 4772166
Change-Id: I20c403a8e63481a35d579d2bd3b121c80ec08f89
7aa9563279627b2ff5413bc895381fc170df9f12 07-Jul-2011 Doug Kwan <dougkwan@google.com> Remove dead code/unused variables to avoid gcc-4.6 warnings.

Change-Id: I291fd42e91085c51772f560d424334874bef8add
03ad7826711ac4e7af6a81ba6f833741444ee621 07-Jul-2011 Elliott Hughes <enh@google.com> Improve a comment.

Change-Id: If6636879dcdc15a33a083a19284de5fe8056e797
ddbd6f44af283415162ea7bb1b4e7ef77c8de492 06-Jul-2011 Elliott Hughes <enh@google.com> Don't abort when a weak global's referent is cleared.

This also makes us less likely to output spurious warnings when
dealing with nulled-out weak globals, and lets us provide more
helpful warnings when warnings are called for.

Bug: 4991942
Change-Id: I99b88e66e07f79562da2cd9d594b93bff218d595
a6e94ff55517438569d207e3ed552c8c127bcac9 30-Jun-2011 Elliott Hughes <enh@google.com> Fix native method logging to show local references rather than direct pointers.

This is necessary (but not sufficient) for debugging third-party JNI bugs.
It's the second half of the logging story, but still doesn't address the
question of "how does the developer turn on the logging?".

This removes the variant JNI bridges at the cost of adding a couple of
booleans to struct Method. Performance is about the same, except synchronized
native methods are quite a bit faster after the change.

Before:
benchmark ns linear runtime
_emptyJniMethod0 333 ==========
_emptyJniMethod6 367 ===========
_emptyJniMethod6L 921 ==============================
_emptyJniStaticMethod0 259 ========
_emptyJniStaticMethod6 287 =========
_emptyJniStaticMethod6L 873 ============================
_emptyJniStaticSynchronizedMethod0 404 =============
_emptyJniSynchronizedMethod0 452 ==============

After:
benchmark ns linear runtime
_emptyJniMethod0 344 ==========
_emptyJniMethod6 348 ==========
_emptyJniMethod6L 969 ==============================
_emptyJniStaticMethod0 265 ========
_emptyJniStaticMethod6 293 =========
_emptyJniStaticMethod6L 968 =============================
_emptyJniStaticSynchronizedMethod0 265 ========
_emptyJniSynchronizedMethod0 323 ==========

A better optimization for the case where there are reference arguments
would be to keep a list of argument indexes in the struct Method, so we
could iterate directly over those arguments that need converting to
local references. That would also let us do something about the overhead
of repeatedly looking up which local reference table and cookie to use.

But now is not the time.

Change-Id: Ie32daca1b31be057a44f1ed4b5d28d1634380e1d
3f04fa049734772a945243d64d6ce9a34b39b730 30-Jun-2011 Elliott Hughes <enh@google.com> Add two new JNI debugging options.

The alwaysCheckThread option provides some backwards compatibility for apps
that misuse JNIEnv*s across threads. The logThirdPartyJni is a step towards
making it easier for third-party developers to debug their JNI errors.

Change-Id: I134374da0fe94f3fbc6b6d5aef52e3eef658aff9
5719d5c79558ffdbbb863ddcf61836221aba922d 22-Jun-2011 Elliott Hughes <enh@google.com> Improve -verbose:jni.

The old output just told you what functions were being called and made no
attempt to show you their arguments. The new output was sufficient to debug
an actual problem with an app we don't have the source to.

Still to do:
0. an easier way for third-party developers to enable this.
1. the primitive type arguments to SetIntField and so forth.
2. return values.

A few examples of the new output...

A decoded jclass:
JNI: libcore.io.Posix.readBytes called IsInstanceOf((JNIEnv*)0x9618470, 0x28100015, java.lang.Class<byte[]>)

A decoded jfieldID:
JNI: libcore.io.Posix.ioctlInt called GetIntField((JNIEnv*)0x9618470, 0x5cb00011, java.io.FileDescriptor.descriptor)

A decoded jmethodID (the FileDescriptor constructor):
JNI: libcore.io.Posix.open called NewObject((JNIEnv*)0x9780480, java.lang.Class<java.io.FileDescriptor>, java.io.FileDescriptor.<init>()V, ...)

A const char*:
JNI: libcore.io.Posix.getsockoptLinger called NewStringUTF((JNIEnv*)0x9618470, "getsockopt")

A jint release mode:
JNI: libcore.io.Posix.writeBytes called ReleaseByteArrayElements((JNIEnv*)0x9780480, 0x2700009, (void*) 0xf5f623c4, JNI_ABORT)

The -verbose:jni option now turns on a bit more output about JNI_OnLoad calls
but no longer causes any logging of calls to JNIEnv or JavaVM functions. The
old -Xjnitrace: option has been extended to enable this new tracing for the
native methods that it covers. They go very well together for debugging
purposes.

I've also made us a bit more verbose if we fail to initialize. In the longer
term I think we want to just abort if we hit any failure during startup, but
my extra logging will save us a bit of time next time we have one of these
failures (this one was caused for me by only having one half of the finalizer
watchdog change; I was missing the libcore side).

(Cherry pick of 6734b8224fb869c94e42e704ec03f2ce8483af2b from dalvik-dev.)

Change-Id: I69b7620b20620e9f06576da244520d9d83f89ab8
a8b4a0eec5e3ab181b3d26223c84c556bead06c8 24-Jun-2011 Elliott Hughes <enh@google.com> Throw NullPointerExceptions with detail messages.

Bug: 4905110
Change-Id: Iebcc45049c1ea14ceef6d44a19dd8cb618392101
eba95c1c0b552d5dd18a7520e3dcc081cfac621c 23-Jun-2011 Elliott Hughes <enh@google.com> Fix native methods that weren't registered via RegisterNatives.

Cherry pick of a64af4aabf261d34eac8b5a9d92992ee70051829.

Change-Id: I43df4e33e39ccaf9e26c842f22da3391cfa17e2b
1a87dec67db6c5a37442c1338d9b8c626c95a545 23-Jun-2011 Elliott Hughes <enh@google.com> Fix native methods that weren't registered via RegisterNatives.

Cherry pick of a64af4aabf261d34eac8b5a9d92992ee70051829.

Change-Id: I43df4e33e39ccaf9e26c842f22da3391cfa17e2b
ce0968340f9ddd54f20e38d4946bfd2ef8f1f343 21-Jun-2011 Elliott Hughes <enh@google.com> Clean up IndirectRefTable a bit.

The main purpose here was to have slightly less unclear warnings for
JNI local reference abuse.

Change-Id: I2c6378dd0a94d8afb96a8e409f7460205e3cd315
d8a3f9fa1951e552f5f65c2914689083cc0c46c2 18-Jun-2011 Elliott Hughes <enh@google.com> Make some of the StringObject functions member functions.

Change-Id: I72ed13c16f0cb24498772c453ba268a0f65f208a
8c8d1594ae9c7b588bb990e7407f4baa6185ecb9 15-Jun-2011 Elliott Hughes <enh@google.com> Better comments for yesterday's change.

Change-Id: I1e05fb0e209d44874101b5ca8b7c8efec6810d5f
65852761e37f938409b85a901a0fb1d98d361023 14-Jun-2011 Elliott Hughes <enh@google.com> Allow native methods to declare they don't need a JNIEnv*.

Bug: 3069458
Change-Id: Ic9a6c562c5abf9607dd4c8a71b0d1e389e6d340b
00feda9a6a12b3a894fbe10876636973d2a03ac2 10-Jun-2011 Carl Shapiro <cshapiro@google.com> Fix an issue regarding FindClass and threads without native methods.

Chapter 4 of the JNI specification states that when FindClass is called
through the Invocation Interface and there is no associated method, the
result of ClassLoader.getBaseClassLoader() is used as the class loader.

Previously, the case where FindClass is called from a main thread was
special cased to ensure this behavior. However, threads which attach to
the VM but are not the main thread require similar treatment. With this
change those threads are similarly treated as a special case.

Change-Id: Idbe33e02a10d248262b9e9f089b033ffe05c4706
a7323974309c3b81cfe342db635d0bf30f36ff62 07-May-2011 Carl Shapiro <cshapiro@google.com> Establish a subclass relationships among the field types.

Change-Id: Id349b359489bb6b1bbb4ab78d29d85c0e6b33799
a62c3a0ab3fcdde37f47d16e9699a935ae7a8e88 04-May-2011 Carl Shapiro <cshapiro@google.com> Establish a subclass relationship between ArrayObject and Object.

Change-Id: I9f9fe52bd4ceebb6dde48251a89190ba6bb00ce4
92a3b69286a757afff76402d8a0d5ec04d7f177c 30-Apr-2011 Carl Shapiro <cshapiro@google.com> Type the reference member of JValue as an Object pointer.

Previously this had been a void pointer. To avoid adding lots of
casts from the logical Object subtypes to Object the RETURN_PTR macro
silently casts its argument to an Object* before performing an
assignment to the JValue return value. After an inheritance
relationship is established between Object and its subtypes this cast
can be removed.

Change-Id: Id05e5c11e57e2a9afd12bad0be095f1dfe9e1f51
d5c80e06a771bb34336c1ec5b0d9ce8a47ec4244 27-Apr-2011 Elliott Hughes <enh@google.com> Remove the old forcecopy in favor of the new.

Also remove some more half-baked multi-VM cruft, fix command-line
parsing (so -Xforcecopy-fuck-yeah won't work any more), and remove
an unused #define.

Bug: 3412449
Change-Id: If914e23dd3bbcf0ac113a445777e0f550ca05703
a5f3ed80b3b058b006ee2b09915d1400cebd0442 27-Apr-2011 Elliott Hughes <enh@google.com> Add -Xjniopts:forcecopy-unmap to catch more errors than forcecopy.

In particular, this spots the BreakIterator bug that forcecopy didn't.
It's about 2x slower than regular forcecopy mode, so I've added a new
option rather than just replace the fast-but-less-effective forcecopy.

Bug: 3412449
Change-Id: I1f226ceeab2508dff607ba25b0afee51cf9c3f83
30bc0d46ae730d78c42c39cfa56a59ba3025380b 22-Apr-2011 buzbee <buzbee@google.com> Consolidate curFrame fields in thread storage

We ended up with two locations in the Thread structure for saved
Dalvik frame pointer. This change consolidates them.

Change-Id: I78f288e4e57e232f29663be930101e775bfe370f
a4f4a73edf03cd08b5b2d775913bcac674a117bb 19-Apr-2011 Carl Shapiro <cshapiro@google.com> Remove dvmAllocObjectArray and all of its uses.

This replaces uses of dvmAllocObjectArray with equivalent but safer
calls to dvmAllocArrayByClass. dvmAllocObjectArray performed no type
checking of its arguments and was easy to use incorrectly.

Change-Id: Ia82fe73cb9d73bbb27f5961242ad5961f9f9924c
23ba9600c0207ef406513fce4c0278796e0b9415 16-Apr-2011 Elliott Hughes <enh@google.com> Start actually using C++ in the JNI implementation.

Change-Id: I9ed07e71d00de4caf314845c4e11201112bd65be
89383030aca8f77aeab73540404ba332ce5ac035 15-Apr-2011 Elliott Hughes <enh@google.com> More JNI implementation cleanup.

Change-Id: I5218c42df18eb5b8647fce073abd8434b40adb80
0647d294bab9312be67a9032adfa4f0b9ba0984a 15-Apr-2011 Elliott Hughes <enh@google.com> Switch the JNI code over to C++.

Change-Id: I82dbaf8931bda5a466fd5ad6b08f7f9b36d7ce37