diff options
| author | 2010-07-15 15:52:48 -0700 | |
|---|---|---|
| committer | 2010-07-15 15:52:48 -0700 | |
| commit | 527e9c8f0471666b5b1c461f1a8a710192208e70 (patch) | |
| tree | 9a48fe24dce2bd9ba44fa0a5cb7e0221cc9ecb23 | |
| parent | f96c2719c3cb4878e899b6fe0753b4f4b8aea8b7 (diff) | |
| parent | 703e5d3c7fbeb8ca0978045db01d40318f838612 (diff) | |
am 703e5d3c: StrictMode: avoid an allocation in common case
Merge commit '703e5d3c7fbeb8ca0978045db01d40318f838612' into gingerbread-plus-aosp
* commit '703e5d3c7fbeb8ca0978045db01d40318f838612':
StrictMode: avoid an allocation in common case
| -rw-r--r-- | core/java/android/os/Parcel.java | 1 | ||||
| -rw-r--r-- | core/java/android/os/StrictMode.java | 39 |
2 files changed, 31 insertions, 9 deletions
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index bfe3b600ddc7..b9c9565a3977 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -1202,6 +1202,7 @@ public final class Parcel { code = EX_ILLEGAL_STATE; } writeInt(code); + StrictMode.clearGatheredViolations(); if (code == 0) { if (e instanceof RuntimeException) { throw (RuntimeException) e; diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 312bca11b895..dc9259078152 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -80,6 +80,8 @@ public final class StrictMode { * our offending stack traces to the caller to ultimately handle * in the originating process. * + * This must be kept in sync with the constant in libs/binder/Parcel.cpp + * * @hide */ public static final int PENALTY_GATHER = 0x100; @@ -98,7 +100,10 @@ public final class StrictMode { private static ThreadLocal<ArrayList<ApplicationErrorReport.CrashInfo>> gatheredViolations = new ThreadLocal<ArrayList<ApplicationErrorReport.CrashInfo>>() { @Override protected ArrayList<ApplicationErrorReport.CrashInfo> initialValue() { - return new ArrayList<ApplicationErrorReport.CrashInfo>(1); + // Starts null to avoid unnecessary allocations when + // checking whether there are any violations or not in + // hasGatheredViolations() below. + return null; } }; @@ -308,7 +313,10 @@ public final class StrictMode { if ((policy & PENALTY_GATHER) != 0) { ArrayList<ApplicationErrorReport.CrashInfo> violations = gatheredViolations.get(); - if (violations.size() >= 5) { + if (violations == null) { + violations = new ArrayList<ApplicationErrorReport.CrashInfo>(1); + gatheredViolations.set(violations); + } else if (violations.size() >= 5) { // Too many. In a loop or something? Don't gather them all. return; } @@ -393,7 +401,16 @@ public final class StrictMode { * Called from Parcel.writeNoException() */ /* package */ static boolean hasGatheredViolations() { - return !gatheredViolations.get().isEmpty(); + return gatheredViolations.get() != null; + } + + /** + * Called from Parcel.writeException(), so we drop this memory and + * don't incorrectly attribute it to the wrong caller on the next + * Binder call on this thread. + */ + /* package */ static void clearGatheredViolations() { + gatheredViolations.set(null); } /** @@ -401,13 +418,17 @@ public final class StrictMode { */ /* package */ static void writeGatheredViolationsToParcel(Parcel p) { ArrayList<ApplicationErrorReport.CrashInfo> violations = gatheredViolations.get(); - p.writeInt(violations.size()); - for (int i = 0; i < violations.size(); ++i) { - violations.get(i).writeToParcel(p, 0 /* unused flags? */); + if (violations == null) { + p.writeInt(0); + } else { + p.writeInt(violations.size()); + for (int i = 0; i < violations.size(); ++i) { + violations.get(i).writeToParcel(p, 0 /* unused flags? */); + } + if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); + violations.clear(); // somewhat redundant, as we're about to null the threadlocal } - - if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); - violations.clear(); + gatheredViolations.set(null); } private static class LogStackTrace extends Exception {} |