Support for JNI local reference cookie.
This also fixes a cross compilation bug in reseting the top of the
indirect reference table following a down call.
Change-Id: I40d913a6f86dadfe87b58d6d13a1ff3613f270ac
diff --git a/src/indirect_reference_table.cc b/src/indirect_reference_table.cc
index f1e903c..e78b362 100644
--- a/src/indirect_reference_table.cc
+++ b/src/indirect_reference_table.cc
@@ -18,6 +18,7 @@
#include "jni_internal.h"
#include "reference_table.h"
#include "runtime.h"
+#include "thread.h"
#include "utils.h"
#include <cstdlib>
@@ -148,6 +149,10 @@
table_[topIndex++] = obj;
segment_state_.parts.topIndex = topIndex;
}
+ if (false) {
+ LOG(INFO) << "+++ added at " << ExtractIndex(result) << " top=" << segment_state_.parts.topIndex
+ << " holes=" << segment_state_.parts.numHoles;
+ }
DCHECK(result != NULL);
return result;
@@ -173,7 +178,8 @@
int idx = ExtractIndex(iref);
if (idx >= topIndex) {
/* bad -- stale reference? */
- LOG(ERROR) << "JNI ERROR (app bug): accessed stale " << kind_ << " " << iref << " (index " << idx << " in a table of size " << topIndex << ")";
+ LOG(ERROR) << "JNI ERROR (app bug): accessed stale " << kind_ << " "
+ << iref << " (index " << idx << " in a table of size " << topIndex << ")";
AbortMaybe();
return false;
}
@@ -230,6 +236,11 @@
int idx = ExtractIndex(iref);
JavaVMExt* vm = Runtime::Current()->GetJavaVM();
+ if (GetIndirectRefKind(iref) == kSirtOrInvalid &&
+ Thread::Current()->SirtContains(reinterpret_cast<jobject>(iref))) {
+ LOG(WARNING) << "Attempt to remove local SIRT entry from IRT, ignoring";
+ return true;
+ }
if (GetIndirectRefKind(iref) == kSirtOrInvalid || vm->work_around_app_jni_bugs) {
idx = LinearScan(iref, bottomIndex, topIndex, table_);
if (idx == -1) {
@@ -240,12 +251,14 @@
if (idx < bottomIndex) {
/* wrong segment */
- LOG(INFO) << "Attempt to remove index outside index area (" << idx << " vs " << bottomIndex << "-" << topIndex << ")";
+ LOG(INFO) << "Attempt to remove index outside index area (" << idx
+ << " vs " << bottomIndex << "-" << topIndex << ")";
return false;
}
if (idx >= topIndex) {
/* bad -- stale reference? */
- LOG(INFO) << "Attempt to remove invalid index " << idx << " (bottom=" << bottomIndex << " top=" << topIndex << ")";
+ LOG(INFO) << "Attempt to remove invalid index " << idx
+ << " (bottom=" << bottomIndex << " top=" << topIndex << ")";
return false;
}
@@ -260,18 +273,25 @@
int numHoles = segment_state_.parts.numHoles - prevState.parts.numHoles;
if (numHoles != 0) {
while (--topIndex > bottomIndex && numHoles != 0) {
- //LOG(INFO) << "+++ checking for hole at " << topIndex-1 << " (cookie=" << cookie << ") val=" << table_[topIndex-1];
+ if (false) {
+ LOG(INFO) << "+++ checking for hole at " << topIndex-1
+ << " (cookie=" << cookie << ") val=" << table_[topIndex - 1];
+ }
if (table_[topIndex-1] != NULL) {
break;
}
- //LOG(INFO) << "+++ ate hole at " << (topIndex-1);
+ if (false) {
+ LOG(INFO) << "+++ ate hole at " << (topIndex - 1);
+ }
numHoles--;
}
segment_state_.parts.numHoles = numHoles + prevState.parts.numHoles;
segment_state_.parts.topIndex = topIndex;
} else {
segment_state_.parts.topIndex = topIndex-1;
- //LOG(INFO) << "+++ ate last entry " << topIndex-1;
+ if (false) {
+ LOG(INFO) << "+++ ate last entry " << topIndex - 1;
+ }
}
} else {
/*
@@ -289,7 +309,9 @@
table_[idx] = NULL;
segment_state_.parts.numHoles++;
- //LOG(INFO) << "+++ left hole at " << idx << ", holes=" << segment_state_.parts.numHoles;
+ if (false) {
+ LOG(INFO) << "+++ left hole at " << idx << ", holes=" << segment_state_.parts.numHoles;
+ }
}
return true;