am bb175384: Add resize to the support library makefile.

* commit 'bb1753843bfa0cd28451cfdaaac250abfbb788c9':
  Add resize to the support library makefile.
diff --git a/v4/java/android/support/v4/app/FragmentManager.java b/v4/java/android/support/v4/app/FragmentManager.java
index cf509d5..39d2209 100644
--- a/v4/java/android/support/v4/app/FragmentManager.java
+++ b/v4/java/android/support/v4/app/FragmentManager.java
@@ -869,6 +869,7 @@
                 case Fragment.INITIALIZING:
                     if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
                     if (f.mSavedFragmentState != null) {
+                        f.mSavedFragmentState.setClassLoader(mActivity.getClassLoader());
                         f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
                                 FragmentManagerImpl.VIEW_STATE_TAG);
                         f.mTarget = getFragment(f.mSavedFragmentState,
diff --git a/v4/java/android/support/v4/util/LruCache.java b/v4/java/android/support/v4/util/LruCache.java
index 66aebf6..524e985 100644
--- a/v4/java/android/support/v4/util/LruCache.java
+++ b/v4/java/android/support/v4/util/LruCache.java
@@ -53,6 +53,22 @@
     }
 
     /**
+     * Sets the size of the cache.
+     *
+     * @param maxSize The new maximum size.
+     */
+    public void resize(int maxSize) {
+        if (maxSize <= 0) {
+            throw new IllegalArgumentException("maxSize <= 0");
+        }
+
+        synchronized (this) {
+            this.maxSize = maxSize;
+        }
+        trimToSize(maxSize);
+    }
+
+    /**
      * Returns the value for {@code key} if it exists in the cache or can be
      * created by {@code #create}. If a value was returned, it is moved to the
      * head of the queue. This returns null if a value is not cached and cannot
@@ -274,7 +290,8 @@
     }
 
     /**
-     * Returns the number of times {@link #get} returned a value.
+     * Returns the number of times {@link #get} returned a value that was
+     * already present in the cache.
      */
     public synchronized final int hitCount() {
         return hitCount;
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java b/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
index 5f64696..8b17aab 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/Allocation.java
@@ -195,6 +195,9 @@
      *
      */
     public int getBytesSize() {
+        if (mType.mDimYuv != 0) {
+            return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
+        }
         return mType.getCount() * mType.getElement().getBytesSize();
     }
 
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/BaseObj.java b/v8/renderscript/java/src/android/support/v8/renderscript/BaseObj.java
index b9ed367..b9d3ef4 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/BaseObj.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/BaseObj.java
@@ -17,6 +17,7 @@
 package android.support.v8.renderscript;
 
 import android.util.Log;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 /**
  * BaseObj is the base class for all RenderScript objects owned by a RS context.
@@ -50,12 +51,6 @@
      */
     int getID(RenderScript rs) {
         mRS.validate();
-        if (rs.isNative) {
-            RenderScriptThunker rst = (RenderScriptThunker)rs;
-            if (getNObj() != null) {
-                return getNObj().hashCode();
-            }
-        }
         if (mDestroyed) {
             throw new RSInvalidStateException("using a destroyed object.");
         }
@@ -82,17 +77,31 @@
     private boolean mDestroyed;
     RenderScript mRS;
 
-    protected void finalize() throws Throwable {
-        if (!mDestroyed) {
-            if(mID != 0 && mRS.isAlive()) {
+    private void helpDestroy() {
+        boolean shouldDestroy = false;
+        synchronized(this) {
+            if (!mDestroyed) {
+                shouldDestroy = true;
+                mDestroyed = true;
+            }
+        }
+
+        if (shouldDestroy) {
+            // must include nObjDestroy in the critical section
+            ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
+            rlock.lock();
+            if(mRS.isAlive()) {
                 mRS.nObjDestroy(mID);
             }
+            rlock.unlock();
             mRS = null;
             mID = 0;
-            mDestroyed = true;
-            //Log.v(RenderScript.LOG_TAG, getClass() +
-            // " auto finalizing object without having released the RS reference.");
         }
+    }
+
+
+    protected void finalize() throws Throwable {
+        helpDestroy();
         super.finalize();
     }
 
@@ -101,12 +110,11 @@
      * primary use is to force immediate cleanup of resources when it is
      * believed the GC will not respond quickly enough.
      */
-    synchronized public void destroy() {
+    public void destroy() {
         if(mDestroyed) {
             throw new RSInvalidStateException("Object already destroyed.");
         }
-        mDestroyed = true;
-        mRS.nObjDestroy(mID);
+        helpDestroy();
     }
 
     /**
@@ -132,10 +140,18 @@
         if (this == obj)
             return true;
 
+        if (obj == null) {
+            return false;
+        }
+
         if (getClass() != obj.getClass()) {
             return false;
         }
 
+        if (mRS.isNative) {
+            return ((RenderScriptThunker)mRS).equals((Object)this, obj);
+        }
+
         BaseObj b = (BaseObj) obj;
         return mID == b.mID;
     }
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/FieldPacker.java b/v8/renderscript/java/src/android/support/v8/renderscript/FieldPacker.java
index eb51076..ffdb66f 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/FieldPacker.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/FieldPacker.java
@@ -29,14 +29,14 @@
  *
  **/
 public class FieldPacker {
-    private android.renderscript.FieldPacker mN;
+    private FieldPackerThunker mN;
 
     public FieldPacker(int len) {
         mPos = 0;
         mLen = len;
         mData = new byte[len];
         if (RenderScript.shouldThunk()) {
-            mN = new android.renderscript.FieldPacker(len);
+            mN = new FieldPackerThunker(len);
         }
     }
 
@@ -209,11 +209,7 @@
 
     public void addObj(BaseObj obj) {
         if (RenderScript.shouldThunk()) {
-            if (obj != null) {
-                mN.addObj(obj.getNObj());
-            } else {
-                mN.addObj(null);
-            }
+            mN.addObj(obj);
             return;
         }
         if (obj != null) {
@@ -225,7 +221,7 @@
 
     public void addF32(Float2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addF32(new android.renderscript.Float2(v.x, v.y));
+            mN.addF32(v);
             return;
         }
         addF32(v.x);
@@ -233,7 +229,7 @@
     }
     public void addF32(Float3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addF32(new android.renderscript.Float3(v.x, v.y, v.z));
+            mN.addF32(v);
             return;
         }
         addF32(v.x);
@@ -242,7 +238,7 @@
     }
     public void addF32(Float4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addF32(new android.renderscript.Float4(v.x, v.y, v.z, v.w));
+            mN.addF32(v);
             return;
         }
         addF32(v.x);
@@ -253,7 +249,7 @@
 
     public void addF64(Double2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addF64(new android.renderscript.Double2(v.x, v.y));
+            mN.addF64(v);
             return;
         }
         addF64(v.x);
@@ -261,7 +257,7 @@
     }
     public void addF64(Double3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addF64(new android.renderscript.Double3(v.x, v.y, v.z));
+            mN.addF64(v);
             return;
         }
         addF64(v.x);
@@ -270,7 +266,7 @@
     }
     public void addF64(Double4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addF64(new android.renderscript.Double4(v.x, v.y, v.z, v.w));
+            mN.addF64(v);
             return;
         }
         addF64(v.x);
@@ -281,7 +277,7 @@
 
     public void addI8(Byte2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI8(new android.renderscript.Byte2(v.x, v.y));
+            mN.addI8(v);
             return;
         }
         addI8(v.x);
@@ -289,7 +285,7 @@
     }
     public void addI8(Byte3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI8(new android.renderscript.Byte3(v.x, v.y, v.z));
+            mN.addI8(v);
             return;
         }
         addI8(v.x);
@@ -298,7 +294,7 @@
     }
     public void addI8(Byte4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI8(new android.renderscript.Byte4(v.x, v.y, v.z, v.w));
+            mN.addI8(v);
             return;
         }
         addI8(v.x);
@@ -309,7 +305,7 @@
 
     public void addU8(Short2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU8(new android.renderscript.Short2(v.x, v.y));
+            mN.addU8(v);
             return;
         }
         addU8(v.x);
@@ -317,7 +313,7 @@
     }
     public void addU8(Short3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU8(new android.renderscript.Short3(v.x, v.y, v.z));
+            mN.addU8(v);
             return;
         }
         addU8(v.x);
@@ -326,7 +322,7 @@
     }
     public void addU8(Short4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU8(new android.renderscript.Short4(v.x, v.y, v.z, v.w));
+            mN.addU8(v);
             return;
         }
         addU8(v.x);
@@ -337,7 +333,7 @@
 
     public void addI16(Short2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI16(new android.renderscript.Short2(v.x, v.y));
+            mN.addI16(v);
             return;
         }
         addI16(v.x);
@@ -345,7 +341,7 @@
     }
     public void addI16(Short3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI16(new android.renderscript.Short3(v.x, v.y, v.z));
+            mN.addI16(v);
             return;
         }
         addI16(v.x);
@@ -354,7 +350,7 @@
     }
     public void addI16(Short4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI16(new android.renderscript.Short4(v.x, v.y, v.z, v.w));
+            mN.addI16(v);
             return;
         }
         addI16(v.x);
@@ -365,7 +361,7 @@
 
     public void addU16(Int2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU16(new android.renderscript.Int2(v.x, v.y));
+            mN.addU16(v);
             return;
         }
         addU16(v.x);
@@ -373,7 +369,7 @@
     }
     public void addU16(Int3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU16(new android.renderscript.Int3(v.x, v.y, v.z));
+            mN.addU16(v);
             return;
         }
         addU16(v.x);
@@ -382,7 +378,7 @@
     }
     public void addU16(Int4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU16(new android.renderscript.Int4(v.x, v.y, v.z, v.w));
+            mN.addU16(v);
             return;
         }
         addU16(v.x);
@@ -393,7 +389,7 @@
 
     public void addI32(Int2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI32(new android.renderscript.Int2(v.x, v.y));
+            mN.addI32(v);
             return;
         }
         addI32(v.x);
@@ -401,7 +397,7 @@
     }
     public void addI32(Int3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI32(new android.renderscript.Int3(v.x, v.y, v.z));
+            mN.addI32(v);
             return;
         }
         addI32(v.x);
@@ -410,7 +406,7 @@
     }
     public void addI32(Int4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI32(new android.renderscript.Int4(v.x, v.y, v.z, v.w));
+            mN.addI32(v);
             return;
         }
         addI32(v.x);
@@ -421,7 +417,7 @@
 
     public void addU32(Long2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU32(new android.renderscript.Long2(v.x, v.y));
+            mN.addU32(v);
             return;
         }
         addU32(v.x);
@@ -429,7 +425,7 @@
     }
     public void addU32(Long3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU32(new android.renderscript.Long3(v.x, v.y, v.z));
+            mN.addU32(v);
             return;
         }
         addU32(v.x);
@@ -438,7 +434,7 @@
     }
     public void addU32(Long4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU32(new android.renderscript.Long4(v.x, v.y, v.z, v.w));
+            mN.addU32(v);
             return;
         }
         addU32(v.x);
@@ -449,7 +445,7 @@
 
     public void addI64(Long2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI64(new android.renderscript.Long2(v.x, v.y));
+            mN.addI64(v);
             return;
         }
         addI64(v.x);
@@ -457,7 +453,7 @@
     }
     public void addI64(Long3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI64(new android.renderscript.Long3(v.x, v.y, v.z));
+            mN.addI64(v);
             return;
         }
         addI64(v.x);
@@ -466,7 +462,7 @@
     }
     public void addI64(Long4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addI64(new android.renderscript.Long4(v.x, v.y, v.z, v.w));
+            mN.addI64(v);
             return;
         }
         addI64(v.x);
@@ -477,7 +473,7 @@
 
     public void addU64(Long2 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU64(new android.renderscript.Long2(v.x, v.y));
+            mN.addU64(v);
             return;
         }
         addU64(v.x);
@@ -485,7 +481,7 @@
     }
     public void addU64(Long3 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU64(new android.renderscript.Long3(v.x, v.y, v.z));
+            mN.addU64(v);
             return;
         }
         addU64(v.x);
@@ -494,7 +490,7 @@
     }
     public void addU64(Long4 v) {
         if (RenderScript.shouldThunk()) {
-            mN.addU64(new android.renderscript.Long4(v.x, v.y, v.z, v.w));
+            mN.addU64(v);
             return;
         }
         addU64(v.x);
@@ -505,7 +501,7 @@
 
     public void addMatrix(Matrix4f v) {
         if (RenderScript.shouldThunk()) {
-            mN.addMatrix(new android.renderscript.Matrix4f(v.getArray()));
+            mN.addMatrix(v);
             return;
         }
         for (int i=0; i < v.mMat.length; i++) {
@@ -515,7 +511,7 @@
 
     public void addMatrix(Matrix3f v) {
         if (RenderScript.shouldThunk()) {
-            mN.addMatrix(new android.renderscript.Matrix3f(v.getArray()));
+            mN.addMatrix(v);
             return;
         }
         for (int i=0; i < v.mMat.length; i++) {
@@ -525,7 +521,7 @@
 
     public void addMatrix(Matrix2f v) {
         if (RenderScript.shouldThunk()) {
-            mN.addMatrix(new android.renderscript.Matrix2f(v.getArray()));
+            mN.addMatrix(v);
             return;
         }
         for (int i=0; i < v.mMat.length; i++) {
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/FieldPackerThunker.java b/v8/renderscript/java/src/android/support/v8/renderscript/FieldPackerThunker.java
new file mode 100644
index 0000000..3e990f6
--- /dev/null
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/FieldPackerThunker.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v8.renderscript;
+
+import android.os.SystemProperties;
+import android.support.v8.renderscript.RenderScript;
+
+/**
+ * Utility class for packing arguments and structures from Android system objects to
+ * RenderScript objects.
+ *
+ * This class is only intended to be used to support the
+ * reflected code generated by the RS tool chain.  It should not
+ * be called directly.
+ *
+ **/
+public class FieldPackerThunker {
+    private android.renderscript.FieldPacker mN;
+
+    public FieldPackerThunker(int len) {
+        mN = new android.renderscript.FieldPacker(len);
+    }
+
+    void align(int v) {
+        mN.align(v);
+    }
+
+    void reset() {
+        mN.reset();
+    }
+
+    void reset(int i) {
+        mN.reset(i);
+    }
+
+    public void skip(int i) {
+        mN.skip(i);
+    }
+
+    public void addI8(byte v) {
+        mN.addI8(v);
+    }
+
+    public void addI16(short v) {
+        mN.addI16(v);
+    }
+
+    public void addI32(int v) {
+        mN.addI32(v);
+    }
+
+    public void addI64(long v) {
+        mN.addI64(v);
+    }
+
+    public void addU8(short v) {
+        mN.addU8(v);
+    }
+
+    public void addU16(int v) {
+        mN.addU16(v);
+    }
+
+    public void addU32(long v) {
+        mN.addU32(v);
+    }
+
+    public void addU64(long v) {
+        mN.addU64(v);
+    }
+
+    public void addF32(float v) {
+        mN.addF32(v);
+    }
+
+    public void addF64(double v) {
+        mN.addF64(v);
+    }
+
+    public void addObj(BaseObj obj) {
+        if (obj != null) {
+            mN.addObj(obj.getNObj());
+        } else {
+            mN.addObj(null);
+        }
+    }
+
+    public void addF32(Float2 v) {
+        mN.addF32(new android.renderscript.Float2(v.x, v.y));
+    }
+    public void addF32(Float3 v) {
+        mN.addF32(new android.renderscript.Float3(v.x, v.y, v.z));
+    }
+    public void addF32(Float4 v) {
+        mN.addF32(new android.renderscript.Float4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addF64(Double2 v) {
+        mN.addF64(new android.renderscript.Double2(v.x, v.y));
+    }
+    public void addF64(Double3 v) {
+        mN.addF64(new android.renderscript.Double3(v.x, v.y, v.z));
+    }
+    public void addF64(Double4 v) {
+        mN.addF64(new android.renderscript.Double4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addI8(Byte2 v) {
+        mN.addI8(new android.renderscript.Byte2(v.x, v.y));
+    }
+    public void addI8(Byte3 v) {
+        mN.addI8(new android.renderscript.Byte3(v.x, v.y, v.z));
+    }
+    public void addI8(Byte4 v) {
+        mN.addI8(new android.renderscript.Byte4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addU8(Short2 v) {
+        mN.addU8(new android.renderscript.Short2(v.x, v.y));
+    }
+    public void addU8(Short3 v) {
+        mN.addU8(new android.renderscript.Short3(v.x, v.y, v.z));
+    }
+    public void addU8(Short4 v) {
+        mN.addU8(new android.renderscript.Short4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addI16(Short2 v) {
+        mN.addI16(new android.renderscript.Short2(v.x, v.y));
+    }
+    public void addI16(Short3 v) {
+        mN.addI16(new android.renderscript.Short3(v.x, v.y, v.z));
+    }
+    public void addI16(Short4 v) {
+        mN.addI16(new android.renderscript.Short4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addU16(Int2 v) {
+        mN.addU16(new android.renderscript.Int2(v.x, v.y));
+    }
+    public void addU16(Int3 v) {
+        mN.addU16(new android.renderscript.Int3(v.x, v.y, v.z));
+    }
+    public void addU16(Int4 v) {
+        mN.addU16(new android.renderscript.Int4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addI32(Int2 v) {
+        mN.addI32(new android.renderscript.Int2(v.x, v.y));
+    }
+    public void addI32(Int3 v) {
+        mN.addI32(new android.renderscript.Int3(v.x, v.y, v.z));
+    }
+    public void addI32(Int4 v) {
+        mN.addI32(new android.renderscript.Int4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addU32(Long2 v) {
+        mN.addU32(new android.renderscript.Long2(v.x, v.y));
+    }
+    public void addU32(Long3 v) {
+        mN.addU32(new android.renderscript.Long3(v.x, v.y, v.z));
+    }
+    public void addU32(Long4 v) {
+        mN.addU32(new android.renderscript.Long4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addI64(Long2 v) {
+        mN.addI64(new android.renderscript.Long2(v.x, v.y));
+    }
+    public void addI64(Long3 v) {
+        mN.addI64(new android.renderscript.Long3(v.x, v.y, v.z));
+    }
+    public void addI64(Long4 v) {
+        mN.addI64(new android.renderscript.Long4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addU64(Long2 v) {
+        mN.addU64(new android.renderscript.Long2(v.x, v.y));
+    }
+    public void addU64(Long3 v) {
+        mN.addU64(new android.renderscript.Long3(v.x, v.y, v.z));
+    }
+    public void addU64(Long4 v) {
+        mN.addU64(new android.renderscript.Long4(v.x, v.y, v.z, v.w));
+    }
+
+    public void addMatrix(Matrix4f v) {
+        mN.addMatrix(new android.renderscript.Matrix4f(v.getArray()));
+    }
+
+    public void addMatrix(Matrix3f v) {
+        mN.addMatrix(new android.renderscript.Matrix3f(v.getArray()));
+    }
+
+    public void addMatrix(Matrix2f v) {
+        mN.addMatrix(new android.renderscript.Matrix2f(v.getArray()));
+    }
+
+    public void addBoolean(boolean v) {
+        mN.addBoolean(v);
+    }
+
+    public final byte[] getData() {
+        return mN.getData();
+    }
+}
+
+
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
index f8ff073..7efbed2 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
@@ -19,6 +19,7 @@
 import java.io.File;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -76,21 +77,71 @@
 
     static boolean isNative = false;
 
-    private static int thunk = 0;
+    static private int sThunk = -1;
+    static private int sSdkVersion = -1;
+
+    static boolean shouldThunk() {
+        if (sThunk == -1) {
+            throw new RSRuntimeException("Can't use RS classes before setting up a RenderScript context");
+        } else if (sThunk == 1) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Determines whether or not we should be thunking into the native
      * RenderScript layer or actually using the compatibility library.
      */
-    static boolean shouldThunk() {
-        if (thunk == 0) {
-            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2
-                    && SystemProperties.getInt("debug.rs.forcecompat", 0) == 0) {
-                thunk = 1;
+    static private boolean setupThunk(int sdkVersion, Context ctx) {
+        if (sThunk == -1) {
+            // use compat on Jelly Bean MR2 if we're requesting SDK 19+
+            if (android.os.Build.VERSION.SDK_INT == 18 && sdkVersion >= 19) {
+                sThunk = 0;
+            }
+            else if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
+                && (SystemProperties.getInt("debug.rs.forcecompat", 0) == 0)) {
+                sThunk = 1;
             } else {
-                thunk = -1;
+                sThunk = 0;
+            }
+
+
+            if (sThunk == 1) {
+                // Workarounds that may disable thunking go here
+                ApplicationInfo info;
+                try {
+                    info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
+                                                                      PackageManager.GET_META_DATA);
+                } catch (PackageManager.NameNotFoundException e) {
+                    // assume no workarounds needed
+                    return true;
+                }
+                long minorVersion = 0;
+
+                // load minorID from reflection
+                try {
+                    Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
+                    Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
+                    minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
+                } catch (Exception e) {
+                    // minor version remains 0 on devices with no possible WARs
+                }
+
+                if (info.metaData != null) {
+                    // asynchronous teardown: minor version 1+
+                    if (info.metaData.getBoolean("com.android.support.v8.renderscript.EnableAsyncTeardown") == true) {
+                        if (minorVersion == 0) {
+                            sThunk = 0;
+                        }
+                    }
+
+                }
+                // end of workarounds
             }
         }
-        if (thunk == 1) {
+
+        if (sThunk == 1) {
             return true;
         }
         return false;
@@ -155,7 +206,18 @@
     native void rsnContextDestroy(int con);
     synchronized void nContextDestroy() {
         validate();
-        rsnContextDestroy(mContext);
+
+        // take teardown lock
+        // teardown lock can only be taken when no objects are being destroyed
+        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
+        wlock.lock();
+
+        int curCon = mContext;
+        // context is considered dead as of this point
+        mContext = 0;
+
+        wlock.unlock();
+        rsnContextDestroy(curCon);
     }
     native void rsnContextSetPriority(int con, int p);
     synchronized void nContextSetPriority(int p) {
@@ -179,8 +241,9 @@
         rsnContextSendMessage(mContext, id, data);
     }
 
+    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
     native void rsnObjDestroy(int con, int id);
-    synchronized void nObjDestroy(int id) {
+    void nObjDestroy(int id) {
         // There is a race condition here.  The calling code may be run
         // by the gc while teardown is occuring.  This protects againts
         // deleting dead objects.
@@ -584,8 +647,10 @@
 
 
 
+
     int     mDev;
     int     mContext;
+    ReentrantReadWriteLock mRWLock;
     @SuppressWarnings({"FieldCanBeLocal"})
     MessageThread mMessageThread;
 
@@ -703,16 +768,7 @@
         mMessageCallback = msg;
         if (isNative) {
             RenderScriptThunker rst = (RenderScriptThunker) this;
-            android.renderscript.RenderScript.RSMessageHandler newmsg =
-                new android.renderscript.RenderScript.RSMessageHandler() {
-                    public void run()  {
-                        mMessageCallback.mData = mData;
-                        mMessageCallback.mID = mID;
-                        mMessageCallback.mLength = mLength;
-                        mMessageCallback.run();
-                    }
-                };
-            rst.mN.setMessageHandler(newmsg);
+            rst.setMessageHandler(msg);
         }
     }
     public RSMessageHandler getMessageHandler() {
@@ -758,15 +814,7 @@
         mErrorCallback = msg;
         if (isNative) {
             RenderScriptThunker rst = (RenderScriptThunker) this;
-            android.renderscript.RenderScript.RSErrorHandler newmsg =
-                new android.renderscript.RenderScript.RSErrorHandler() {
-                    public void run()  {
-                        mErrorCallback.mErrorMessage = mErrorMessage;
-                        mErrorCallback.mErrorNum = mErrorNum;
-                        mErrorCallback.run();
-                    }
-                };
-            rst.mN.setErrorHandler(newmsg);
+            rst.setErrorHandler(msg);
         }
     }
     public RSErrorHandler getErrorHandler() {
@@ -891,6 +939,7 @@
         if (ctx != null) {
             mApplicationContext = ctx.getApplicationContext();
         }
+        mRWLock = new ReentrantReadWriteLock();
     }
 
     /**
@@ -919,9 +968,15 @@
     public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
         RenderScript rs = new RenderScript(ctx);
 
-        if (shouldThunk()) {
+        if (sSdkVersion == -1) {
+            sSdkVersion = sdkVersion;
+        } else if (sSdkVersion != sdkVersion) {
+            throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
+        }
+
+        if (setupThunk(sSdkVersion, ctx)) {
             android.util.Log.v(LOG_TAG, "RS native mode");
-            return RenderScriptThunker.create(ctx, sdkVersion);
+            return RenderScriptThunker.create(ctx, sSdkVersion);
         }
         synchronized(lock) {
             if (sInitialized == false) {
@@ -1009,6 +1064,7 @@
      */
     public void destroy() {
         validate();
+        nContextFinish();
         nContextDeinitToClient(mContext);
         mMessageThread.mRun = false;
         try {
@@ -1017,8 +1073,6 @@
         }
 
         nContextDestroy();
-        mContext = 0;
-
         nDeviceDestroy(mDev);
         mDev = 0;
     }
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScriptThunker.java b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScriptThunker.java
index daf0b26..d4a3a98 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScriptThunker.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScriptThunker.java
@@ -85,4 +85,47 @@
         }
 
     }
+
+    public void setMessageHandler(RSMessageHandler msg) {
+        mMessageCallback = msg;
+        try {
+            android.renderscript.RenderScript.RSMessageHandler handler =
+                new android.renderscript.RenderScript.RSMessageHandler() {
+                    public void run() {
+                        mMessageCallback.mData = mData;
+                        mMessageCallback.mID = mID;
+                        mMessageCallback.mLength = mLength;
+                        mMessageCallback.run();
+                    }
+                };
+            mN.setMessageHandler(handler);
+        } catch (android.renderscript.RSRuntimeException e) {
+            throw ExceptionThunker.convertException(e);
+        }
+    }
+
+    public void setErrorHandler(RSErrorHandler msg) {
+        mErrorCallback = msg;
+        try {
+            android.renderscript.RenderScript.RSErrorHandler handler =
+                new android.renderscript.RenderScript.RSErrorHandler() {
+                    public void run() {
+                        mErrorCallback.mErrorMessage = mErrorMessage;
+                        mErrorCallback.mErrorNum = mErrorNum;
+                        mErrorCallback.run();
+                    }
+                };
+            mN.setErrorHandler(handler);
+        } catch (android.renderscript.RSRuntimeException e) {
+            throw ExceptionThunker.convertException(e);
+        }
+    }
+
+
+    boolean equals(Object obj1, Object obj2) {
+        if (obj2 instanceof android.support.v8.renderscript.BaseObj) {
+            return ((android.renderscript.BaseObj)obj1).equals(((android.support.v8.renderscript.BaseObj)obj2).getNObj());
+        }
+        return false;
+    }
 }
diff --git a/v8/renderscript/jni/Android.mk b/v8/renderscript/jni/Android.mk
index 9a4a262..073adeb 100644
--- a/v8/renderscript/jni/Android.mk
+++ b/v8/renderscript/jni/Android.mk
@@ -1,6 +1,9 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_CLANG := true
+LOCAL_SDK_VERSION := 8
+
 LOCAL_SRC_FILES:= \
     android_renderscript_RenderScript.cpp
 
@@ -9,17 +12,16 @@
         libjnigraphics
 
 LOCAL_STATIC_LIBRARIES := \
-        libcutils \
-        liblog
+        libcutils
 
-rs_generated_include_dir := $(call intermediates-dir-for,SHARED_LIBRARIES,libRSSupport,,)
+rs_generated_include_dir := $(call generated-sources-dir-for,SHARED_LIBRARIES,libRSSupport,,)
 
 LOCAL_C_INCLUDES += \
 	$(JNI_H_INCLUDE) \
 	frameworks/rs \
 	$(rs_generated_include_dir)
 
-LOCAL_CFLAGS +=
+LOCAL_CFLAGS += -Wno-unused-parameter -U_FORTIFY_SOURCE
 
 LOCAL_LDLIBS := -lpthread
 LOCAL_ADDITIONAL_DEPENDENCIES := $(addprefix $(rs_generated_include_dir)/,rsgApiFuncDecl.h)
@@ -27,5 +29,6 @@
 LOCAL_ADDITIONAL_DEPENDENCIES += $(rs_generated_source)
 LOCAL_MODULE_TAGS := optional
 LOCAL_REQUIRED_MODULES := libRSSupport
+LOCAL_32_BIT_ONLY := true
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/v8/renderscript/jni/android_renderscript_RenderScript.cpp b/v8/renderscript/jni/android_renderscript_RenderScript.cpp
index 36c43c8..8531347 100644
--- a/v8/renderscript/jni/android_renderscript_RenderScript.cpp
+++ b/v8/renderscript/jni/android_renderscript_RenderScript.cpp
@@ -171,8 +171,8 @@
                                  &receiveLen, sizeof(receiveLen),
                                  &subID, sizeof(subID));
     if (!id && receiveLen) {
-        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
-            "message receive buffer too small.  %zu", receiveLen);
+        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
+        //            "message receive buffer too small.  %zu", receiveLen);
     }
     return _env->NewStringUTF(buf);
 }
@@ -190,8 +190,8 @@
                                  &receiveLen, sizeof(receiveLen),
                                  &subID, sizeof(subID));
     if (!id && receiveLen) {
-        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
-            "message receive buffer too small.  %zu", receiveLen);
+        //        __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG,
+        //            "message receive buffer too small.  %zu", receiveLen);
     }
     _env->ReleaseIntArrayElements(data, ptr, 0);
     return id;
@@ -1086,12 +1086,12 @@
     jint result = -1;
 
     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
-            "ERROR: GetEnv failed\n");
+        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+        //            "ERROR: GetEnv failed\n");
         goto bail;
     }
     if (env == NULL) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
+        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: env == NULL");
         goto bail;
     }
 
@@ -1101,8 +1101,8 @@
     }
 
     if (env->RegisterNatives(clazz, methods, NELEM(methods)) < 0) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
-            "ERROR: MediaPlayer native registration failed\n");
+        //        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,
+        //            "ERROR: MediaPlayer native registration failed\n");
         goto bail;
     }
 
diff --git a/v8/renderscript/rs_support/Android.mk b/v8/renderscript/rs_support/Android.mk
index f3ea43e..a7ff352 100644
--- a/v8/renderscript/rs_support/Android.mk
+++ b/v8/renderscript/rs_support/Android.mk
@@ -38,12 +38,15 @@
 LOCAL_MODULE := libRSSupport
 LOCAL_SDK_VERSION := 8
 
+# TODO: remove this once we have 64-bit NDK libraries.
+LOCAL_32_BIT_ONLY := true
+
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-intermediates:= $(local-intermediates-dir)
+generated_sources_dir := $(call local-generated-sources-dir)
 
 # Generate custom headers
 
-GEN := $(addprefix $(intermediates)/, \
+GEN := $(addprefix $(generated_sources_dir)/, \
             rsgApiStructs.h \
             rsgApiFuncDecl.h \
         )
@@ -51,7 +54,7 @@
 $(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
 $(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR_SUPPORT) $< $@ <$(PRIVATE_PATH)/rs.spec
 $(GEN) : $(RSG_GENERATOR_SUPPORT) $(LOCAL_PATH)/rs.spec
-$(GEN): $(intermediates)/%.h : $(LOCAL_PATH)/%.h.rsg
+$(GEN): $(generated_sources_dir)/%.h : $(LOCAL_PATH)/%.h.rsg
 	$(transform-generated-source)
 
 # used in jni/Android.mk
@@ -60,7 +63,7 @@
 
 # Generate custom source files
 
-GEN := $(addprefix $(intermediates)/, \
+GEN := $(addprefix $(generated_sources_dir)/, \
             rsgApi.cpp \
             rsgApiReplay.cpp \
         )
@@ -68,7 +71,7 @@
 $(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
 $(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR_SUPPORT) $< $@ <$(PRIVATE_PATH)/rs.spec
 $(GEN) : $(RSG_GENERATOR_SUPPORT) $(LOCAL_PATH)/rs.spec
-$(GEN): $(intermediates)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg
+$(GEN): $(generated_sources_dir)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg
 	$(transform-generated-source)
 
 # used in jni/Android.mk
@@ -126,17 +129,20 @@
 	cpu_ref/rsCpuRuntimeMathFuncs.cpp
 
 ifeq ($(ARCH_ARM_HAVE_ARMV7A),true)
-LOCAL_CFLAGS += -DARCH_ARM_HAVE_VFP
-LOCAL_ASFLAGS := -mfpu=neon
-LOCAL_SRC_FILES += \
-	cpu_ref/rsCpuIntrinsics_neon.S \
-	cpu_ref/rsCpuIntrinsics_neon_ColorMatrix.S
+LOCAL_CFLAGS_arm := -DARCH_ARM_HAVE_VFP
+LOCAL_ASFLAGS_arm := -mfpu=neon
+LOCAL_SRC_FILES_arm := \
+        cpu_ref/rsCpuIntrinsics_neon_3DLUT.S \
+	cpu_ref/rsCpuIntrinsics_neon_ColorMatrix.S \
+        cpu_ref/rsCpuIntrinsics_neon_Blend.S \
+        cpu_ref/rsCpuIntrinsics_neon_Blur.S \
+	cpu_ref/rsCpuIntrinsics_neon_Convolve.S \
+        cpu_ref/rsCpuIntrinsics_neon_YuvToRGB.S
 endif
 
 LOCAL_LDFLAGS += -llog -ldl
 LOCAL_NDK_STL_VARIANT := stlport_static
 
-LOCAL_C_INCLUDES += external/clang/lib/Headers
 LOCAL_C_INCLUDES += frameworks/compile/libbcc/include
 
 
@@ -146,4 +152,7 @@
 LOCAL_MODULE:= libRSSupport
 LOCAL_MODULE_TAGS := optional
 
+# TODO: why isn't this picked up from the host GLOBAL_CFLAGS?
+LOCAL_CFLAGS += -D__STDC_FORMAT_MACROS
+
 include $(BUILD_SHARED_LIBRARY)