Version 3.21.12

Fixed bitwise negation on x64. (Chromium issue 285355)

Dropped GetCurrentThreadId() and TerminateExecution(int) from  	the external API.

Fixed polymorphic INTERCEPTOR StoreICs on ARM/MIPS. (Chromium issue 284998)

Added check if timeout has expired after processing each sample. (issue 2814,v8:2871)

Removed obsolete global V8::has_been_fooed flags. (issue 2744)

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@16593 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index d39b110..7a498ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2013-09-09: Version 3.21.12
+
+        Fixed bitwise negation on x64.
+        (Chromium issue 285355)
+
+        Dropped GetCurrentThreadId() and TerminateExecution(int) from 
+	the external API.
+
+        Fixed polymorphic INTERCEPTOR StoreICs on ARM/MIPS.
+        (Chromium issue 284998)
+
+        Added check if timeout has expired after processing each sample.
+        (issue 2814,v8:2871)
+
+        Removed obsolete global V8::has_been_fooed flags.
+        (issue 2744)
+
+        Performance and stability improvements on all platforms.
+
+
 2013-09-05: Version 3.21.11
 
         Performance and stability improvements on all platforms.
diff --git a/include/v8.h b/include/v8.h
index ba4d19b..55a8ea6 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -120,7 +120,10 @@
 template <class T> class Handle;
 template <class T> class Local;
 template <class T> class Eternal;
-template <class T> class Persistent;
+template<class T> class NonCopyablePersistentTraits;
+template<class T,
+         class M = NonCopyablePersistentTraits<T> > class Persistent;
+template<class T, class P> class WeakCallbackObject;
 class FunctionTemplate;
 class ObjectTemplate;
 class Data;
@@ -142,6 +145,7 @@
 template<typename T> class CustomArguments;
 class PropertyCallbackArguments;
 class FunctionCallbackArguments;
+class GlobalHandles;
 }
 
 
@@ -169,27 +173,6 @@
   intptr_t data_;
 };
 
-
-// --- Weak Handles ---
-
-
-/**
- * A weak reference callback function.
- *
- * This callback should either explicitly invoke Dispose on |object| if
- * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak.
- *
- * \param object the weak global object to be reclaimed by the garbage collector
- * \param parameter the value passed in when making the weak global object
- */
-template<typename T, typename P>
-class WeakReferenceCallbacks {
- public:
-  typedef void (*Revivable)(Isolate* isolate,
-                            Persistent<T>* object,
-                            P* parameter);
-};
-
 // --- Handles ---
 
 #define TYPE_CHECK(T, S)                                       \
@@ -230,13 +213,6 @@
    */
   V8_INLINE(Handle()) : val_(0) {}
 
-#ifdef V8_USE_UNSAFE_HANDLES
-  /**
-   * Creates a new handle for the specified value.
-   */
-  V8_INLINE(explicit Handle(T* val)) : val_(val) {}
-#endif
-
   /**
    * Creates a handle for the contents of the specified handle.  This
    * constructor allows you to pass handles as arguments by value and
@@ -285,7 +261,6 @@
     return *a == *b;
   }
 
-#ifndef V8_USE_UNSAFE_HANDLES
   template <class S> V8_INLINE(
       bool operator==(const Persistent<S>& that) const) {
     internal::Object** a = reinterpret_cast<internal::Object**>(**this);
@@ -294,7 +269,6 @@
     if (b == 0) return false;
     return *a == *b;
   }
-#endif
 
   /**
    * Checks whether two handles are different.
@@ -306,12 +280,10 @@
     return !operator==(that);
   }
 
-#ifndef V8_USE_UNSAFE_HANDLES
   template <class S> V8_INLINE(
       bool operator!=(const Persistent<S>& that) const) {
     return !operator==(that);
   }
-#endif
 
   template <class S> V8_INLINE(static Handle<T> Cast(Handle<S> that)) {
 #ifdef V8_ENABLE_CHECKS
@@ -326,11 +298,9 @@
     return Handle<S>::Cast(*this);
   }
 
-#ifndef V8_USE_UNSAFE_HANDLES
   V8_INLINE(static Handle<T> New(Isolate* isolate, Handle<T> that)) {
     return New(isolate, that.val_);
   }
-  // TODO(dcarney): remove before cutover
   V8_INLINE(static Handle<T> New(Isolate* isolate, const Persistent<T>& that)) {
     return New(isolate, that.val_);
   }
@@ -343,11 +313,10 @@
    * Creates a new handle for the specified value.
    */
   V8_INLINE(explicit Handle(T* val)) : val_(val) {}
-#endif
 
  private:
   friend class Utils;
-  template<class F> friend class Persistent;
+  template<class F, class M> friend class Persistent;
   template<class F> friend class Local;
   template<class F> friend class FunctionCallbackInfo;
   template<class F> friend class PropertyCallbackInfo;
@@ -359,9 +328,7 @@
   friend class Context;
   friend class HandleScope;
 
-#ifndef V8_USE_UNSAFE_HANDLES
   V8_INLINE(static Handle<T> New(Isolate* isolate, T* that));
-#endif
 
   T* val_;
 };
@@ -374,7 +341,6 @@
  * handle scope are destroyed when the handle scope is destroyed.  Hence it
  * is not necessary to explicitly deallocate local handles.
  */
-// TODO(dcarney): deprecate entire class
 template <class T> class Local : public Handle<T> {
  public:
   V8_INLINE(Local());
@@ -389,10 +355,6 @@
   }
 
 
-#ifdef V8_USE_UNSAFE_HANDLES
-  template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { }
-#endif
-
   template <class S> V8_INLINE(static Local<T> Cast(Local<S> that)) {
 #ifdef V8_ENABLE_CHECKS
     // If we're going to perform the type check then we have to check
@@ -401,12 +363,10 @@
 #endif
     return Local<T>(T::Cast(*that));
   }
-#ifndef V8_USE_UNSAFE_HANDLES
   template <class S> V8_INLINE(Local(Handle<S> that))
       : Handle<T>(reinterpret_cast<T*>(*that)) {
     TYPE_CHECK(T, S);
   }
-#endif
 
   template <class S> V8_INLINE(Local<S> As()) {
     return Local<S>::Cast(*this);
@@ -419,21 +379,20 @@
    */
   V8_INLINE(static Local<T> New(Handle<T> that));
   V8_INLINE(static Local<T> New(Isolate* isolate, Handle<T> that));
-#ifndef V8_USE_UNSAFE_HANDLES
-  // TODO(dcarney): remove before cutover
-  V8_INLINE(static Local<T> New(Isolate* isolate, const Persistent<T>& that));
+  template<class M>
+  V8_INLINE(static Local<T> New(Isolate* isolate,
+                                const Persistent<T, M>& that));
 
 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
 
  private:
 #endif
   template <class S> V8_INLINE(Local(S* that) : Handle<T>(that)) { }
-#endif
 
  private:
   friend class Utils;
   template<class F> friend class Eternal;
-  template<class F> friend class Persistent;
+  template<class F, class M> friend class Persistent;
   template<class F> friend class Handle;
   template<class F> friend class FunctionCallbackInfo;
   template<class F> friend class PropertyCallbackInfo;
@@ -468,6 +427,61 @@
 };
 
 
+template<class T, class P>
+class WeakCallbackData {
+ public:
+  typedef void (*Callback)(const WeakCallbackData<T, P>& data);
+
+  V8_INLINE(Isolate* GetIsolate()) const { return isolate_; }
+  V8_INLINE(Local<T> GetValue()) const { return handle_; }
+  V8_INLINE(P* GetParameter()) const { return parameter_; }
+
+ private:
+  friend class internal::GlobalHandles;
+  WeakCallbackData(Isolate* isolate, Local<T> handle, P* parameter)
+    : isolate_(isolate), handle_(handle), parameter_(parameter) { }
+  Isolate* isolate_;
+  Local<T> handle_;
+  P* parameter_;
+};
+
+
+// TODO(dcarney): Remove this class.
+template<typename T,
+         typename P,
+         typename M = NonCopyablePersistentTraits<T> >
+class WeakReferenceCallbacks {
+ public:
+  typedef void (*Revivable)(Isolate* isolate,
+                            Persistent<T, M>* object,
+                            P* parameter);
+};
+
+
+/**
+ * Default traits for Persistent. This class does not allow
+ * use of the copy constructor or assignment operator.
+ * At present kResetInDestructor is not set, but that will change in a future
+ * version.
+ */
+template<class T>
+class NonCopyablePersistentTraits {
+ public:
+  typedef Persistent<T, NonCopyablePersistentTraits<T> > NonCopyablePersistent;
+  static const bool kResetInDestructor = false;
+  template<class S, class M>
+  V8_INLINE(static void Copy(const Persistent<S, M>& source,
+                             NonCopyablePersistent* dest)) {
+    Uncompilable<Object>();
+  }
+  // TODO(dcarney): come up with a good compile error here.
+  template<class O>
+  V8_INLINE(static void Uncompilable()) {
+    TYPE_CHECK(O, Primitive);
+  }
+};
+
+
 /**
  * An object reference that is independent of any handle scope.  Where
  * a Local handle only lives as long as the HandleScope in which it was
@@ -477,106 +491,84 @@
  * A persistent handle contains a reference to a storage cell within
  * the v8 engine which holds an object value and which is updated by
  * the garbage collector whenever the object is moved.  A new storage
- * cell can be created using Persistent::New and existing handles can
- * be disposed using Persistent::Dispose.  Since persistent handles
- * are passed by value you may have many persistent handle objects
- * that point to the same storage cell.  For instance, if you pass a
- * persistent handle as an argument to a function you will not get two
- * different storage cells but rather two references to the same
- * storage cell.
+ * cell can be created using the constructor or Persistent::Reset and
+ * existing handles can be disposed using Persistent::Reset.
+ *
+ * Copy, assignment and destructor bevavior is controlled by the traits
+ * class M.
  */
-template <class T> class Persistent // NOLINT
-#ifdef V8_USE_UNSAFE_HANDLES
-    : public Handle<T> {
-#else
-  { // NOLINT
-#endif
+template <class T, class M> class Persistent {
  public:
-#ifndef V8_USE_UNSAFE_HANDLES
-  V8_INLINE(Persistent()) : val_(0) { }
-  // TODO(dcarney): add this back before cutover.
-//  V8_INLINE(~Persistent()) {
-//  Dispose();
-//  }
-  V8_INLINE(bool IsEmpty() const) { return val_ == 0; }
-  // TODO(dcarney): remove somehow before cutover
-  // The handle should either be 0, or a pointer to a live cell.
-  V8_INLINE(void Clear()) { val_ = 0; }
-
   /**
-   * A constructor that creates a new global cell pointing to that. In contrast
-   * to the copy constructor, this creates a new persistent handle which needs
-   * to be separately disposed.
+   * A Persistent with no storage cell.
+   */
+  V8_INLINE(Persistent()) : val_(0) { }
+  /**
+   * Construct a Persistent from a Handle.
+   * When the Handle is non-empty, a new storage cell is created
+   * pointing to the same object, and no flags are set.
    */
   template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that))
-      : val_(New(isolate, *that)) { }
-
-  template <class S> V8_INLINE(Persistent(Isolate* isolate,
-                                          const Persistent<S>& that)) // NOLINT
-      : val_(New(isolate, *that)) { }
-
-#else
-  /**
-   * Creates an empty persistent handle that doesn't point to any
-   * storage cell.
-   */
-  V8_INLINE(Persistent()) : Handle<T>() { }
-
-  /**
-   * Creates a persistent handle for the same storage cell as the
-   * specified handle.  This constructor allows you to pass persistent
-   * handles as arguments by value and to assign between persistent
-   * handles.  However, attempting to assign between incompatible
-   * persistent handles, for instance from a Persistent<String> to a
-   * Persistent<Number> will cause a compile-time error.  Assigning
-   * between compatible persistent handles, for instance assigning a
-   * Persistent<String> to a variable declared as Persistent<Value>,
-   * is allowed as String is a subclass of Value.
-   */
-  template <class S> V8_INLINE(Persistent(Persistent<S> that))
-      : Handle<T>(reinterpret_cast<T*>(*that)) {
-    /**
-     * This check fails when trying to convert between incompatible
-     * handles. For example, converting from a Handle<String> to a
-     * Handle<Number>.
-     */
+      : val_(New(isolate, *that)) {
     TYPE_CHECK(T, S);
   }
-
-  template <class S> V8_INLINE(Persistent(S* that)) : Handle<T>(that) { }
-
   /**
-   * A constructor that creates a new global cell pointing to that. In contrast
-   * to the copy constructor, this creates a new persistent handle which needs
-   * to be separately disposed.
+   * Construct a Persistent from a Persistent.
+   * When the Persistent is non-empty, a new storage cell is created
+   * pointing to the same object, and no flags are set.
    */
-  template <class S> V8_INLINE(Persistent(Isolate* isolate, Handle<S> that))
-      : Handle<T>(New(isolate, that)) { }
-
+  template <class S, class M2>
+  V8_INLINE(Persistent(Isolate* isolate, const Persistent<S, M2>& that))
+    : val_(New(isolate, *that)) {
+    TYPE_CHECK(T, S);
+  }
   /**
-   * "Casts" a plain handle which is known to be a persistent handle
-   * to a persistent handle.
+   * The copy constructors and assignment operator create a Persistent
+   * exactly as the Persistent constructor, but the Copy function from the
+   * traits class is called, allowing the setting of flags based on the
+   * copied Persistent.
    */
-  template <class S> explicit V8_INLINE(Persistent(Handle<S> that))
-      : Handle<T>(*that) { }
-
-#endif
-
-#ifdef V8_USE_UNSAFE_HANDLES
-  template <class S> V8_INLINE(static Persistent<T> Cast(Persistent<S> that)) {
-#ifdef V8_ENABLE_CHECKS
-    // If we're going to perform the type check then we have to check
-    // that the handle isn't empty before doing the checked cast.
-    if (that.IsEmpty()) return Persistent<T>();
-#endif
-    return Persistent<T>(T::Cast(*that));
+  V8_INLINE(Persistent(const Persistent& that)) : val_(0) {
+    Copy(that);
+  }
+  template <class S, class M2>
+  V8_INLINE(Persistent(const Persistent<S, M2>& that)) : val_(0) {
+    Copy(that);
+  }
+  V8_INLINE(Persistent& operator=(const Persistent& that)) { // NOLINT
+    Copy(that);
+    return *this;
+  }
+  template <class S, class M2>
+  V8_INLINE(Persistent& operator=(const Persistent<S, M2>& that)) { // NOLINT
+    Copy(that);
+    return *this;
   }
 
-  template <class S> V8_INLINE(Persistent<S> As()) {
-    return Persistent<S>::Cast(*this);
-  }
+  /**
+   * If non-empty, destroy the underlying storage cell
+   * IsEmpty() will return true after this call.
+   */
+  V8_INLINE(void Reset());
+  template <class S>
+  /**
+   * If non-empty, destroy the underlying storage cell
+   * and create a new one with the contents of other if other is non empty
+   */
+  V8_INLINE(void Reset(Isolate* isolate, const Handle<S>& other));
+  /**
+   * If non-empty, destroy the underlying storage cell
+   * and create a new one with the contents of other if other is non empty
+   */
+  template <class S, class M2>
+  V8_INLINE(void Reset(Isolate* isolate, const Persistent<S, M2>& other));
+  // TODO(dcarney): deprecate
+  V8_INLINE(void Dispose()) { Reset(); }
+  V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Reset(); }
 
-#else
+  V8_INLINE(bool IsEmpty() const) { return val_ == 0; }
+
+  // TODO(dcarney): this is pretty useless, fix or remove
   template <class S>
   V8_INLINE(static Persistent<T>& Cast(Persistent<S>& that)) { // NOLINT
 #ifdef V8_ENABLE_CHECKS
@@ -587,20 +579,13 @@
     return reinterpret_cast<Persistent<T>&>(that);
   }
 
+  // TODO(dcarney): this is pretty useless, fix or remove
   template <class S> V8_INLINE(Persistent<S>& As()) { // NOLINT
     return Persistent<S>::Cast(*this);
   }
-#endif
 
-#ifdef V8_USE_UNSAFE_HANDLES
-  V8_DEPRECATED(static Persistent<T> New(Handle<T> that));
-  V8_INLINE(static Persistent<T> New(Isolate* isolate, Handle<T> that));
-  V8_INLINE(static Persistent<T> New(Isolate* isolate, Persistent<T> that));
-#endif
-
-#ifndef V8_USE_UNSAFE_HANDLES
-  template <class S> V8_INLINE(
-      bool operator==(const Persistent<S>& that) const) {
+  template <class S, class M2> V8_INLINE(
+      bool operator==(const Persistent<S, M2>& that) const) {
     internal::Object** a = reinterpret_cast<internal::Object**>(**this);
     internal::Object** b = reinterpret_cast<internal::Object**>(*that);
     if (a == 0) return b == 0;
@@ -616,52 +601,35 @@
     return *a == *b;
   }
 
-  template <class S> V8_INLINE(
-      bool operator!=(const Persistent<S>& that) const) {
+  template <class S, class M2> V8_INLINE(
+      bool operator!=(const Persistent<S, M2>& that) const) {
     return !operator==(that);
   }
 
   template <class S> V8_INLINE(bool operator!=(const Handle<S>& that) const) {
     return !operator==(that);
   }
-#endif
-
-  V8_INLINE(void Dispose());
-
-  /**
-   * Releases the storage cell referenced by this persistent handle.
-   * Does not remove the reference to the cell from any handles.
-   * This handle's reference, and any other references to the storage
-   * cell remain and IsEmpty will still return false.
-   */
-  V8_DEPRECATED(V8_INLINE(void Dispose(Isolate* isolate))) { Dispose(); }
-
-  /**
-   * Make the reference to this object weak.  When only weak handles
-   * refer to the object, the garbage collector will perform a
-   * callback to the given V8::NearDeathCallback function, passing
-   * it the object reference and the given parameters.
-   */
-  template<typename S, typename P>
-  V8_INLINE(void MakeWeak(
-      P* parameters,
-      typename WeakReferenceCallbacks<S, P>::Revivable callback));
 
   template<typename P>
-  V8_INLINE(void MakeWeak(
-      P* parameters,
-      typename WeakReferenceCallbacks<T, P>::Revivable callback));
+  V8_INLINE(void SetWeak(
+      P* parameter,
+      typename WeakCallbackData<T, P>::Callback callback));
 
   template<typename S, typename P>
-  V8_DEPRECATED(void MakeWeak(
-      Isolate* isolate,
-      P* parameters,
+  V8_INLINE(void SetWeak(
+      P* parameter,
+      typename WeakCallbackData<S, P>::Callback callback));
+
+  // TODO(dcarney): deprecate
+  template<typename S, typename P>
+  V8_INLINE(void MakeWeak(
+      P* parameter,
       typename WeakReferenceCallbacks<S, P>::Revivable callback));
 
+  // TODO(dcarney): deprecate
   template<typename P>
-  V8_DEPRECATED(void MakeWeak(
-      Isolate* isolate,
-      P* parameters,
+  V8_INLINE(void MakeWeak(
+      P* parameter,
       typename WeakReferenceCallbacks<T, P>::Revivable callback));
 
   V8_INLINE(void ClearWeak());
@@ -735,68 +703,35 @@
     return WrapperClassId();
   }
 
-  /**
-   * Disposes the current contents of the handle and replaces it.
-   */
-  V8_INLINE(void Reset(Isolate* isolate, const Handle<T>& other));
-
-#ifndef V8_USE_UNSAFE_HANDLES
-  V8_INLINE(void Reset(Isolate* isolate, const Persistent<T>& other));
-#endif
-
-  /**
-   * Returns the underlying raw pointer and clears the handle. The caller is
-   * responsible of eventually destroying the underlying object (by creating a
-   * Persistent handle which points to it and Disposing it). In the future,
-   * destructing a Persistent will also Dispose it. With this function, the
-   * embedder can let the Persistent go out of scope without it getting
-   * disposed.
-   */
+  // TODO(dcarney): remove
   V8_INLINE(T* ClearAndLeak());
 
-#ifndef V8_USE_UNSAFE_HANDLES
+  // TODO(dcarney): remove
+  V8_INLINE(void Clear()) { val_ = 0; }
 
- private:
-  // TODO(dcarney): make unlinkable before cutover
-  V8_INLINE(Persistent(const Persistent& that)) : val_(that.val_) {}
-  // TODO(dcarney): make unlinkable before cutover
-  V8_INLINE(Persistent& operator=(const Persistent& that)) {  // NOLINT
-    this->val_ = that.val_;
-    return *this;
-  }
-
- public:
+  // TODO(dcarney): remove
 #ifndef V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
 
  private:
 #endif
-  // TODO(dcarney): remove before cutover
   template <class S> V8_INLINE(Persistent(S* that)) : val_(that) { }
 
-  // TODO(dcarney): remove before cutover
   V8_INLINE(T* operator*() const) { return val_; }
 
  private:
-  // TODO(dcarney): remove before cutover
-  V8_INLINE(T* operator->() const) { return val_; }
- public:
-#endif
-
- private:
   friend class Utils;
   template<class F> friend class Handle;
   template<class F> friend class Local;
-  template<class F> friend class Persistent;
+  template<class F1, class F2> friend class Persistent;
   template<class F> friend class ReturnValue;
 
   V8_INLINE(static T* New(Isolate* isolate, T* that));
+  template<class S, class M2>
+  V8_INLINE(void Copy(const Persistent<S, M2>& that));
 
-#ifndef V8_USE_UNSAFE_HANDLES
   T* val_;
-#endif
 };
 
-
  /**
  * A stack-allocated class that governs a number of local handles.
  * After a handle scope has been created, all local handles will be
@@ -2361,11 +2296,129 @@
 };
 
 
+template<typename T>
+class ReturnValue {
+ public:
+  template <class S> V8_INLINE(ReturnValue(const ReturnValue<S>& that))
+      : value_(that.value_) {
+    TYPE_CHECK(T, S);
+  }
+  // Handle setters
+  template <typename S> V8_INLINE(void Set(const Persistent<S>& handle));
+  template <typename S> V8_INLINE(void Set(const Handle<S> handle));
+  // Fast primitive setters
+  V8_INLINE(void Set(bool value));
+  V8_INLINE(void Set(double i));
+  V8_INLINE(void Set(int32_t i));
+  V8_INLINE(void Set(uint32_t i));
+  // Fast JS primitive setters
+  V8_INLINE(void SetNull());
+  V8_INLINE(void SetUndefined());
+  V8_INLINE(void SetEmptyString());
+  // Convenience getter for Isolate
+  V8_INLINE(Isolate* GetIsolate());
+
+ private:
+  template<class F> friend class ReturnValue;
+  template<class F> friend class FunctionCallbackInfo;
+  template<class F> friend class PropertyCallbackInfo;
+  V8_INLINE(internal::Object* GetDefaultValue());
+  V8_INLINE(explicit ReturnValue(internal::Object** slot));
+  internal::Object** value_;
+};
+
+
+/**
+ * The argument information given to function call callbacks.  This
+ * class provides access to information about the context of the call,
+ * including the receiver, the number and values of arguments, and
+ * the holder of the function.
+ */
+template<typename T>
+class FunctionCallbackInfo {
+ public:
+  V8_INLINE(int Length() const);
+  V8_INLINE(Local<Value> operator[](int i) const);
+  V8_INLINE(Local<Function> Callee() const);
+  V8_INLINE(Local<Object> This() const);
+  V8_INLINE(Local<Object> Holder() const);
+  V8_INLINE(bool IsConstructCall() const);
+  V8_INLINE(Local<Value> Data() const);
+  V8_INLINE(Isolate* GetIsolate() const);
+  V8_INLINE(ReturnValue<T> GetReturnValue() const);
+  // This shouldn't be public, but the arm compiler needs it.
+  static const int kArgsLength = 6;
+
+ protected:
+  friend class internal::FunctionCallbackArguments;
+  friend class internal::CustomArguments<FunctionCallbackInfo>;
+  static const int kReturnValueIndex = 0;
+  static const int kReturnValueDefaultValueIndex = -1;
+  static const int kIsolateIndex = -2;
+  static const int kDataIndex = -3;
+  static const int kCalleeIndex = -4;
+  static const int kHolderIndex = -5;
+
+  V8_INLINE(FunctionCallbackInfo(internal::Object** implicit_args,
+                   internal::Object** values,
+                   int length,
+                   bool is_construct_call));
+  internal::Object** implicit_args_;
+  internal::Object** values_;
+  int length_;
+  bool is_construct_call_;
+};
+
+
+/**
+ * The information passed to a property callback about the context
+ * of the property access.
+ */
+template<typename T>
+class PropertyCallbackInfo {
+ public:
+  V8_INLINE(Isolate* GetIsolate() const);
+  V8_INLINE(Local<Value> Data() const);
+  V8_INLINE(Local<Object> This() const);
+  V8_INLINE(Local<Object> Holder() const);
+  V8_INLINE(ReturnValue<T> GetReturnValue() const);
+  // This shouldn't be public, but the arm compiler needs it.
+  static const int kArgsLength = 6;
+
+ protected:
+  friend class MacroAssembler;
+  friend class internal::PropertyCallbackArguments;
+  friend class internal::CustomArguments<PropertyCallbackInfo>;
+  static const int kThisIndex = 0;
+  static const int kHolderIndex = -1;
+  static const int kDataIndex = -2;
+  static const int kReturnValueIndex = -3;
+  static const int kReturnValueDefaultValueIndex = -4;
+  static const int kIsolateIndex = -5;
+
+  V8_INLINE(PropertyCallbackInfo(internal::Object** args))
+      : args_(args) { }
+  internal::Object** args_;
+};
+
+
+typedef void (*FunctionCallback)(const FunctionCallbackInfo<Value>& info);
+
+
 /**
  * A JavaScript function object (ECMA-262, 15.3).
  */
 class V8_EXPORT Function : public Object {
  public:
+  /**
+   * Create a function in the current execution context
+   * for a given FunctionCallback.
+   */
+  static Local<Function> New(Isolate* isolate,
+                             FunctionCallback callback,
+                             Local<Value> data = Local<Value>(),
+                             int length = 0);
+
   Local<Object> NewInstance() const;
   Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
   Local<Value> Call(Handle<Object> recv, int argc, Handle<Value> argv[]);
@@ -3034,114 +3087,6 @@
 };
 
 
-template<typename T>
-class ReturnValue {
- public:
-  template <class S> V8_INLINE(ReturnValue(const ReturnValue<S>& that))
-      : value_(that.value_) {
-    TYPE_CHECK(T, S);
-  }
-  // Handle setters
-  template <typename S> V8_INLINE(void Set(const Persistent<S>& handle));
-  template <typename S> V8_INLINE(void Set(const Handle<S> handle));
-  // Fast primitive setters
-  V8_INLINE(void Set(bool value));
-  V8_INLINE(void Set(double i));
-  V8_INLINE(void Set(int32_t i));
-  V8_INLINE(void Set(uint32_t i));
-  // Fast JS primitive setters
-  V8_INLINE(void SetNull());
-  V8_INLINE(void SetUndefined());
-  V8_INLINE(void SetEmptyString());
-  // Convenience getter for Isolate
-  V8_INLINE(Isolate* GetIsolate());
-
- private:
-  template<class F> friend class ReturnValue;
-  template<class F> friend class FunctionCallbackInfo;
-  template<class F> friend class PropertyCallbackInfo;
-  V8_INLINE(internal::Object* GetDefaultValue());
-  V8_INLINE(explicit ReturnValue(internal::Object** slot));
-  internal::Object** value_;
-};
-
-
-/**
- * The argument information given to function call callbacks.  This
- * class provides access to information about the context of the call,
- * including the receiver, the number and values of arguments, and
- * the holder of the function.
- */
-template<typename T>
-class FunctionCallbackInfo {
- public:
-  V8_INLINE(int Length() const);
-  V8_INLINE(Local<Value> operator[](int i) const);
-  V8_INLINE(Local<Function> Callee() const);
-  V8_INLINE(Local<Object> This() const);
-  V8_INLINE(Local<Object> Holder() const);
-  V8_INLINE(bool IsConstructCall() const);
-  V8_INLINE(Local<Value> Data() const);
-  V8_INLINE(Isolate* GetIsolate() const);
-  V8_INLINE(ReturnValue<T> GetReturnValue() const);
-  // This shouldn't be public, but the arm compiler needs it.
-  static const int kArgsLength = 6;
-
- protected:
-  friend class internal::FunctionCallbackArguments;
-  friend class internal::CustomArguments<FunctionCallbackInfo>;
-  static const int kReturnValueIndex = 0;
-  static const int kReturnValueDefaultValueIndex = -1;
-  static const int kIsolateIndex = -2;
-  static const int kDataIndex = -3;
-  static const int kCalleeIndex = -4;
-  static const int kHolderIndex = -5;
-
-  V8_INLINE(FunctionCallbackInfo(internal::Object** implicit_args,
-                   internal::Object** values,
-                   int length,
-                   bool is_construct_call));
-  internal::Object** implicit_args_;
-  internal::Object** values_;
-  int length_;
-  bool is_construct_call_;
-};
-
-
-/**
- * The information passed to a property callback about the context
- * of the property access.
- */
-template<typename T>
-class PropertyCallbackInfo {
- public:
-  V8_INLINE(Isolate* GetIsolate() const);
-  V8_INLINE(Local<Value> Data() const);
-  V8_INLINE(Local<Object> This() const);
-  V8_INLINE(Local<Object> Holder() const);
-  V8_INLINE(ReturnValue<T> GetReturnValue() const);
-  // This shouldn't be public, but the arm compiler needs it.
-  static const int kArgsLength = 6;
-
- protected:
-  friend class MacroAssembler;
-  friend class internal::PropertyCallbackArguments;
-  friend class internal::CustomArguments<PropertyCallbackInfo>;
-  static const int kThisIndex = 0;
-  static const int kHolderIndex = -1;
-  static const int kDataIndex = -2;
-  static const int kReturnValueIndex = -3;
-  static const int kReturnValueDefaultValueIndex = -4;
-  static const int kIsolateIndex = -5;
-
-  V8_INLINE(PropertyCallbackInfo(internal::Object** args))
-      : args_(args) { }
-  internal::Object** args_;
-};
-
-
-typedef void (*FunctionCallback)(const FunctionCallbackInfo<Value>& info);
-
 /**
  * NamedProperty[Getter|Setter] are used as interceptors on object.
  * See ObjectTemplate::SetNamedPropertyHandler.
@@ -4592,40 +4537,6 @@
       intptr_t change_in_bytes);
 
   /**
-   * Retrieve the V8 thread id of the calling thread.
-   *
-   * The thread id for a thread should only be retrieved after the V8
-   * lock has been acquired with a Locker object with that thread.
-   */
-  static int GetCurrentThreadId();
-
-  /**
-   * Forcefully terminate execution of a JavaScript thread.  This can
-   * be used to terminate long-running scripts.
-   *
-   * TerminateExecution should only be called when then V8 lock has
-   * been acquired with a Locker object.  Therefore, in order to be
-   * able to terminate long-running threads, preemption must be
-   * enabled to allow the user of TerminateExecution to acquire the
-   * lock.
-   *
-   * The termination is achieved by throwing an exception that is
-   * uncatchable by JavaScript exception handlers.  Termination
-   * exceptions act as if they were caught by a C++ TryCatch exception
-   * handler.  If forceful termination is used, any C++ TryCatch
-   * exception handler that catches an exception should check if that
-   * exception is a termination exception and immediately return if
-   * that is the case.  Returning immediately in that case will
-   * continue the propagation of the termination exception if needed.
-   *
-   * The thread id passed to TerminateExecution must have been
-   * obtained by calling GetCurrentThreadId on the thread in question.
-   *
-   * \param thread_id The thread id of the thread to terminate.
-   */
-  static void TerminateExecution(int thread_id);
-
-  /**
    * Forcefully terminate the current thread of JavaScript execution
    * in the given isolate. If no isolate is provided, the default
    * isolate is used.
@@ -4743,10 +4654,13 @@
 
   static internal::Object** GlobalizeReference(internal::Isolate* isolate,
                                                internal::Object** handle);
+  static internal::Object** CopyPersistent(internal::Object** handle);
   static void DisposeGlobal(internal::Object** global_handle);
   typedef WeakReferenceCallbacks<Value, void>::Revivable RevivableCallback;
+  typedef WeakCallbackData<Value, void>::Callback WeakCallback;
   static void MakeWeak(internal::Object** global_handle,
                        void* data,
+                       WeakCallback weak_callback,
                        RevivableCallback weak_reference_callback);
   static void ClearWeak(internal::Object** global_handle);
   static void Eternalize(Isolate* isolate,
@@ -4757,7 +4671,7 @@
   template <class T> friend class Handle;
   template <class T> friend class Local;
   template <class T> friend class Eternal;
-  template <class T> friend class Persistent;
+  template <class T, class M> friend class Persistent;
   friend class Context;
 };
 
@@ -5098,11 +5012,7 @@
     }
     // TODO(dcarney): deprecate
     V8_INLINE(Scope(Isolate* isolate, Persistent<Context>& context)) // NOLINT
-#ifndef V8_USE_UNSAFE_HANDLES
     : context_(Handle<Context>::New(isolate, context)) {
-#else
-    : context_(Local<Context>::New(isolate, context)) {
-#endif
       context_->Enter();
     }
     V8_INLINE(~Scope()) { context_->Exit(); }
@@ -5592,9 +5502,9 @@
   return New(isolate, that.val_);
 }
 
-#ifndef V8_USE_UNSAFE_HANDLES
 template <class T>
-Local<T> Local<T>::New(Isolate* isolate, const Persistent<T>& that) {
+template <class M>
+Local<T> Local<T>::New(Isolate* isolate, const Persistent<T, M>& that) {
   return New(isolate, that.val_);
 }
 
@@ -5606,7 +5516,6 @@
   return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
       reinterpret_cast<internal::Isolate*>(isolate), *p)));
 }
-#endif
 
 
 template <class T>
@@ -5633,27 +5542,8 @@
 }
 
 
-#ifdef V8_USE_UNSAFE_HANDLES
-template <class T>
-Persistent<T> Persistent<T>::New(Handle<T> that) {
-  return New(Isolate::GetCurrent(), that.val_);
-}
-
-
-template <class T>
-Persistent<T> Persistent<T>::New(Isolate* isolate, Handle<T> that) {
-  return New(Isolate::GetCurrent(), that.val_);
-}
-
-template <class T>
-Persistent<T> Persistent<T>::New(Isolate* isolate, Persistent<T> that) {
-  return New(Isolate::GetCurrent(), that.val_);
-}
-#endif
-
-
-template <class T>
-T* Persistent<T>::New(Isolate* isolate, T* that) {
+template <class T, class M>
+T* Persistent<T, M>::New(Isolate* isolate, T* that) {
   if (that == NULL) return NULL;
   internal::Object** p = reinterpret_cast<internal::Object**>(that);
   return reinterpret_cast<T*>(
@@ -5662,8 +5552,20 @@
 }
 
 
-template <class T>
-bool Persistent<T>::IsIndependent() const {
+template <class T, class M>
+template <class S, class M2>
+void Persistent<T, M>::Copy(const Persistent<S, M2>& that) {
+  TYPE_CHECK(T, S);
+  Reset();
+  if (that.IsEmpty()) return;
+  internal::Object** p = reinterpret_cast<internal::Object**>(that.val_);
+  this->val_ = reinterpret_cast<T*>(V8::CopyPersistent(p));
+  M::Copy(that, this);
+}
+
+
+template <class T, class M>
+bool Persistent<T, M>::IsIndependent() const {
   typedef internal::Internals I;
   if (this->IsEmpty()) return false;
   return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
@@ -5671,8 +5573,8 @@
 }
 
 
-template <class T>
-bool Persistent<T>::IsNearDeath() const {
+template <class T, class M>
+bool Persistent<T, M>::IsNearDeath() const {
   typedef internal::Internals I;
   if (this->IsEmpty()) return false;
   uint8_t node_state =
@@ -5682,8 +5584,8 @@
 }
 
 
-template <class T>
-bool Persistent<T>::IsWeak() const {
+template <class T, class M>
+bool Persistent<T, M>::IsWeak() const {
   typedef internal::Internals I;
   if (this->IsEmpty()) return false;
   return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) ==
@@ -5691,66 +5593,89 @@
 }
 
 
-template <class T>
-void Persistent<T>::Dispose() {
+template <class T, class M>
+void Persistent<T, M>::Reset() {
   if (this->IsEmpty()) return;
   V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_));
-#ifndef V8_USE_UNSAFE_HANDLES
   val_ = 0;
-#endif
 }
 
 
-template <class T>
+template <class T, class M>
+template <class S>
+void Persistent<T, M>::Reset(Isolate* isolate, const Handle<S>& other) {
+  TYPE_CHECK(T, S);
+  Reset();
+  if (other.IsEmpty()) return;
+  this->val_ = New(isolate, other.val_);
+}
+
+
+template <class T,  class M>
+template <class S, class M2>
+void Persistent<T, M>::Reset(Isolate* isolate,
+                             const Persistent<S, M2>& other) {
+  TYPE_CHECK(T, S);
+  Reset();
+  if (other.IsEmpty()) return;
+  this->val_ = New(isolate, other.val_);
+}
+
+
+template <class T, class M>
 template <typename S, typename P>
-void Persistent<T>::MakeWeak(
+void Persistent<T, M>::SetWeak(
+    P* parameter,
+    typename WeakCallbackData<S, P>::Callback callback) {
+  TYPE_CHECK(S, T);
+  typedef typename WeakCallbackData<Value, void>::Callback Callback;
+  V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_),
+               parameter,
+               reinterpret_cast<Callback>(callback),
+               NULL);
+}
+
+
+template <class T, class M>
+template <typename P>
+void Persistent<T, M>::SetWeak(
+    P* parameter,
+    typename WeakCallbackData<T, P>::Callback callback) {
+  SetWeak<T, P>(parameter, callback);
+}
+
+
+template <class T, class M>
+template <typename S, typename P>
+void Persistent<T, M>::MakeWeak(
     P* parameters,
     typename WeakReferenceCallbacks<S, P>::Revivable callback) {
   TYPE_CHECK(S, T);
   typedef typename WeakReferenceCallbacks<Value, void>::Revivable Revivable;
   V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_),
                parameters,
+               NULL,
                reinterpret_cast<Revivable>(callback));
 }
 
 
-template <class T>
+template <class T, class M>
 template <typename P>
-void Persistent<T>::MakeWeak(
+void Persistent<T, M>::MakeWeak(
     P* parameters,
     typename WeakReferenceCallbacks<T, P>::Revivable callback) {
   MakeWeak<T, P>(parameters, callback);
 }
 
 
-template <class T>
-template <typename S, typename P>
-void Persistent<T>::MakeWeak(
-    Isolate* isolate,
-    P* parameters,
-    typename WeakReferenceCallbacks<S, P>::Revivable callback) {
-  MakeWeak<S, P>(parameters, callback);
-}
-
-
-template <class T>
-template<typename P>
-void Persistent<T>::MakeWeak(
-    Isolate* isolate,
-    P* parameters,
-    typename WeakReferenceCallbacks<T, P>::Revivable callback) {
-  MakeWeak<P>(parameters, callback);
-}
-
-
-template <class T>
-void Persistent<T>::ClearWeak() {
+template <class T, class M>
+void Persistent<T, M>::ClearWeak() {
   V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_));
 }
 
 
-template <class T>
-void Persistent<T>::MarkIndependent() {
+template <class T, class M>
+void Persistent<T, M>::MarkIndependent() {
   typedef internal::Internals I;
   if (this->IsEmpty()) return;
   I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
@@ -5759,8 +5684,8 @@
 }
 
 
-template <class T>
-void Persistent<T>::MarkPartiallyDependent() {
+template <class T, class M>
+void Persistent<T, M>::MarkPartiallyDependent() {
   typedef internal::Internals I;
   if (this->IsEmpty()) return;
   I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_),
@@ -5769,54 +5694,17 @@
 }
 
 
-template <class T>
-void Persistent<T>::Reset(Isolate* isolate, const Handle<T>& other) {
-  Dispose();
-#ifdef V8_USE_UNSAFE_HANDLES
-  *this = *New(isolate, other);
-#else
-  if (other.IsEmpty()) {
-    this->val_ = NULL;
-    return;
-  }
-  internal::Object** p = reinterpret_cast<internal::Object**>(other.val_);
-  this->val_ = reinterpret_cast<T*>(
-      V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p));
-#endif
-}
-
-
-#ifndef V8_USE_UNSAFE_HANDLES
-template <class T>
-void Persistent<T>::Reset(Isolate* isolate, const Persistent<T>& other) {
-  Dispose();
-  if (other.IsEmpty()) {
-    this->val_ = NULL;
-    return;
-  }
-  internal::Object** p = reinterpret_cast<internal::Object**>(other.val_);
-  this->val_ = reinterpret_cast<T*>(
-      V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p));
-}
-#endif
-
-
-template <class T>
-T* Persistent<T>::ClearAndLeak() {
+template <class T, class M>
+T* Persistent<T, M>::ClearAndLeak() {
   T* old;
-#ifdef V8_USE_UNSAFE_HANDLES
-  old = **this;
-  *this = Persistent<T>();
-#else
   old = val_;
   val_ = NULL;
-#endif
   return old;
 }
 
 
-template <class T>
-void Persistent<T>::SetWrapperClassId(uint16_t class_id) {
+template <class T, class M>
+void Persistent<T, M>::SetWrapperClassId(uint16_t class_id) {
   typedef internal::Internals I;
   if (this->IsEmpty()) return;
   internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_);
@@ -5825,8 +5713,8 @@
 }
 
 
-template <class T>
-uint16_t Persistent<T>::WrapperClassId() const {
+template <class T, class M>
+uint16_t Persistent<T, M>::WrapperClassId() const {
   typedef internal::Internals I;
   if (this->IsEmpty()) return 0;
   internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_);
diff --git a/src/api.cc b/src/api.cc
index ad75715..1bc80d2 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -660,11 +660,22 @@
 }
 
 
+i::Object** V8::CopyPersistent(i::Object** obj) {
+  i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
+#ifdef DEBUG
+  (*obj)->Verify();
+#endif  // DEBUG
+  return result.location();
+}
+
+
 void V8::MakeWeak(i::Object** object,
                   void* parameters,
+                  WeakCallback weak_callback,
                   RevivableCallback weak_reference_callback) {
   i::GlobalHandles::MakeWeak(object,
                              parameters,
+                             weak_callback,
                              weak_reference_callback);
 }
 
@@ -1052,6 +1063,37 @@
 }
 
 
+static Local<FunctionTemplate> FunctionTemplateNew(
+    i::Isolate* isolate,
+    FunctionCallback callback,
+    v8::Handle<Value> data,
+    v8::Handle<Signature> signature,
+    int length,
+    bool do_not_cache) {
+  i::Handle<i::Struct> struct_obj =
+      isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
+  i::Handle<i::FunctionTemplateInfo> obj =
+      i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
+  InitializeFunctionTemplate(obj);
+  obj->set_do_not_cache(do_not_cache);
+  int next_serial_number = 0;
+  if (!do_not_cache) {
+    next_serial_number = isolate->next_serial_number() + 1;
+    isolate->set_next_serial_number(next_serial_number);
+  }
+  obj->set_serial_number(i::Smi::FromInt(next_serial_number));
+  if (callback != 0) {
+    if (data.IsEmpty()) data = v8::Undefined();
+    Utils::ToLocal(obj)->SetCallHandler(callback, data);
+  }
+  obj->set_length(length);
+  obj->set_undetectable(false);
+  obj->set_needs_access_check(false);
+  if (!signature.IsEmpty())
+    obj->set_signature(*Utils::OpenHandle(*signature));
+  return Utils::ToLocal(obj);
+}
+
 Local<FunctionTemplate> FunctionTemplate::New(
     FunctionCallback callback,
     v8::Handle<Value> data,
@@ -1061,25 +1103,8 @@
   EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
   LOG_API(isolate, "FunctionTemplate::New");
   ENTER_V8(isolate);
-  i::Handle<i::Struct> struct_obj =
-      isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
-  i::Handle<i::FunctionTemplateInfo> obj =
-      i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
-  InitializeFunctionTemplate(obj);
-  int next_serial_number = isolate->next_serial_number();
-  isolate->set_next_serial_number(next_serial_number + 1);
-  obj->set_serial_number(i::Smi::FromInt(next_serial_number));
-  if (callback != 0) {
-    if (data.IsEmpty()) data = v8::Undefined();
-    Utils::ToLocal(obj)->SetCallHandler(callback, data);
-  }
-  obj->set_length(length);
-  obj->set_undetectable(false);
-  obj->set_needs_access_check(false);
-
-  if (!signature.IsEmpty())
-    obj->set_signature(*Utils::OpenHandle(*signature));
-  return Utils::ToLocal(obj);
+  return FunctionTemplateNew(
+      isolate, callback, data, signature, length, false);
 }
 
 
@@ -4189,6 +4214,19 @@
 }
 
 
+Local<Function> Function::New(Isolate* v8_isolate,
+                              FunctionCallback callback,
+                              Local<Value> data,
+                              int length) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+  LOG_API(isolate, "Function::New");
+  ENTER_V8(isolate);
+  return FunctionTemplateNew(
+      isolate, callback, data, Local<Signature>(), length, true)->
+          GetFunction();
+}
+
+
 Local<v8::Object> Function::NewInstance() const {
   return NewInstance(0, NULL);
 }
@@ -5408,26 +5446,6 @@
   return env;
 }
 
-#ifdef V8_USE_UNSAFE_HANDLES
-Persistent<Context> v8::Context::New(
-    v8::ExtensionConfiguration* extensions,
-    v8::Handle<ObjectTemplate> global_template,
-    v8::Handle<Value> global_object) {
-  i::Isolate::EnsureDefaultIsolate();
-  i::Isolate* isolate = i::Isolate::Current();
-  Isolate* external_isolate = reinterpret_cast<Isolate*>(isolate);
-  EnsureInitializedForIsolate(isolate, "v8::Context::New()");
-  LOG_API(isolate, "Context::New");
-  ON_BAILOUT(isolate, "v8::Context::New()", return Persistent<Context>());
-  i::HandleScope scope(isolate);
-  i::Handle<i::Context> env =
-      CreateEnvironment(isolate, extensions, global_template, global_object);
-  if (env.is_null()) return Persistent<Context>();
-  return Persistent<Context>::New(external_isolate, Utils::ToLocal(env));
-}
-#endif
-
-
 Local<Context> v8::Context::New(
     v8::Isolate* external_isolate,
     v8::ExtensionConfiguration* extensions,
@@ -6772,29 +6790,6 @@
 }
 
 
-int V8::GetCurrentThreadId() {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
-  return isolate->thread_id().ToInteger();
-}
-
-
-void V8::TerminateExecution(int thread_id) {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (!isolate->IsInitialized()) return;
-  API_ENTRY_CHECK(isolate, "V8::TerminateExecution()");
-  // If the thread_id identifies the current thread just terminate
-  // execution right away.  Otherwise, ask the thread manager to
-  // terminate the thread with the given id if any.
-  i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
-  if (isolate->thread_id().Equals(internal_tid)) {
-    isolate->stack_guard()->TerminateExecution();
-  } else {
-    isolate->thread_manager()->TerminateExecution(internal_tid);
-  }
-}
-
-
 void V8::TerminateExecution(Isolate* isolate) {
   // If no isolate is supplied, use the default isolate.
   if (isolate != NULL) {
@@ -7888,7 +7883,7 @@
       getter));
   VMState<EXTERNAL> state(isolate);
   ExternalCallbackScope call_scope(isolate, getter_address);
-  return getter(property, info);
+  getter(property, info);
 }
 
 
@@ -7899,7 +7894,7 @@
       reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
   VMState<EXTERNAL> state(isolate);
   ExternalCallbackScope call_scope(isolate, callback_address);
-  return callback(info);
+  callback(info);
 }
 
 
diff --git a/src/apinatives.js b/src/apinatives.js
index 7adeb7e..5fb36c0 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -74,8 +74,9 @@
       cache[serialNumber] = null;
       var fun = %CreateApiFunction(data);
       if (name) %FunctionSetName(fun, name);
-      cache[serialNumber] = fun;
       var flags = %GetTemplateField(data, kApiFlagOffset);
+      var doNotCache = flags & (1 << kDoNotCacheBit);
+      if (!doNotCache) cache[serialNumber] = fun;
       if (flags & (1 << kRemovePrototypeBit)) {
         %FunctionRemovePrototype(fun);
       } else {
@@ -97,6 +98,7 @@
         }
       }
       ConfigureTemplateInstance(fun, data);
+      if (doNotCache) return fun;
     } catch (e) {
       cache[serialNumber] = kUninitialized;
       throw e;
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index f9e21f7..132e1a6 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1511,20 +1511,39 @@
   if (instr->representation().IsSmiOrInteger32()) {
     ASSERT(instr->left()->representation().Equals(instr->representation()));
     ASSERT(instr->right()->representation().Equals(instr->representation()));
-    LOperand* left;
-    LOperand* right = UseOrConstant(instr->BetterRightOperand());
-    LOperand* temp = NULL;
-    if (instr->CheckFlag(HValue::kBailoutOnMinusZero) &&
-        (instr->CheckFlag(HValue::kCanOverflow) ||
-        !right->IsConstantOperand())) {
-      left = UseRegister(instr->BetterLeftOperand());
-      temp = TempRegister();
+    HValue* left = instr->BetterLeftOperand();
+    HValue* right = instr->BetterRightOperand();
+    LOperand* left_op;
+    LOperand* right_op;
+    bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
+    bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
+
+    if (right->IsConstant()) {
+      HConstant* constant = HConstant::cast(right);
+      int32_t constant_value = constant->Integer32Value();
+      // Constants -1, 0 and 1 can be optimized if the result can overflow.
+      // For other constants, it can be optimized only without overflow.
+      if (!can_overflow || ((constant_value >= -1) && (constant_value <= 1))) {
+        left_op = UseRegisterAtStart(left);
+        right_op = UseConstant(right);
+      } else {
+        if (bailout_on_minus_zero) {
+          left_op = UseRegister(left);
+        } else {
+          left_op = UseRegisterAtStart(left);
+        }
+        right_op = UseRegister(right);
+      }
     } else {
-      left = UseRegisterAtStart(instr->BetterLeftOperand());
+      if (bailout_on_minus_zero) {
+        left_op = UseRegister(left);
+      } else {
+        left_op = UseRegisterAtStart(left);
+      }
+      right_op = UseRegister(right);
     }
-    LMulI* mul = new(zone()) LMulI(left, right, temp);
-    if (instr->CheckFlag(HValue::kCanOverflow) ||
-        instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    LMulI* mul = new(zone()) LMulI(left_op, right_op);
+    if (can_overflow || bailout_on_minus_zero) {
       AssignEnvironment(mul);
     }
     return DefineAsRegister(mul);
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 781dcf4..f90f3c4 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -677,17 +677,15 @@
 };
 
 
-class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+class LMulI V8_FINAL : public LTemplateInstruction<1, 2, 0> {
  public:
-  LMulI(LOperand* left, LOperand* right, LOperand* temp) {
+  LMulI(LOperand* left, LOperand* right) {
     inputs_[0] = left;
     inputs_[1] = right;
-    temps_[0] = temp;
   }
 
   LOperand* left() { return inputs_[0]; }
   LOperand* right() { return inputs_[1]; }
-  LOperand* temp() { return temps_[0]; }
 
   DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
   DECLARE_HYDROGEN_ACCESSOR(Mul)
@@ -1286,7 +1284,9 @@
   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
   DECLARE_HYDROGEN_ACCESSOR(Constant)
 
-  Handle<Object> value() const { return hydrogen()->handle(); }
+  Handle<Object> value(Isolate* isolate) const {
+    return hydrogen()->handle(isolate);
+  }
 };
 
 
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index ae24210..d880286 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -423,7 +423,7 @@
   } else if (op->IsConstantOperand()) {
     LConstantOperand* const_op = LConstantOperand::cast(op);
     HConstant* constant = chunk_->LookupConstant(const_op);
-    Handle<Object> literal = constant->handle();
+    Handle<Object> literal = constant->handle(isolate());
     Representation r = chunk_->LookupLiteralRepresentation(const_op);
     if (r.IsInteger32()) {
       ASSERT(literal->IsNumber());
@@ -458,7 +458,7 @@
   } else if (op->IsConstantOperand()) {
     LConstantOperand* const_op = LConstantOperand::cast(op);
     HConstant* constant = chunk_->LookupConstant(const_op);
-    Handle<Object> literal = constant->handle();
+    Handle<Object> literal = constant->handle(isolate());
     Representation r = chunk_->LookupLiteralRepresentation(const_op);
     if (r.IsInteger32()) {
       ASSERT(literal->IsNumber());
@@ -486,7 +486,7 @@
 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
   HConstant* constant = chunk_->LookupConstant(op);
   ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
-  return constant->handle();
+  return constant->handle(isolate());
 }
 
 
@@ -543,7 +543,7 @@
       Abort(kToOperandUnsupportedDoubleImmediate);
     }
     ASSERT(r.IsTagged());
-    return Operand(constant->handle());
+    return Operand(constant->handle(isolate()));
   } else if (op->IsRegister()) {
     return Operand(ToRegister(op));
   } else if (op->IsDoubleRegister()) {
@@ -690,7 +690,7 @@
     translation->StoreDoubleRegister(reg);
   } else if (op->IsConstantOperand()) {
     HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
-    int src_index = DefineDeoptimizationLiteral(constant->handle());
+    int src_index = DefineDeoptimizationLiteral(constant->handle(isolate()));
     translation->StoreLiteral(src_index);
   } else {
     UNREACHABLE();
@@ -1573,17 +1573,16 @@
 
 
 void LCodeGen::DoMulI(LMulI* instr) {
-  Register scratch = scratch0();
   Register result = ToRegister(instr->result());
   // Note that result may alias left.
   Register left = ToRegister(instr->left());
   LOperand* right_op = instr->right();
 
-  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
   bool bailout_on_minus_zero =
     instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
+  bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
 
-  if (right_op->IsConstantOperand() && !can_overflow) {
+  if (right_op->IsConstantOperand()) {
     int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
 
     if (bailout_on_minus_zero && (constant < 0)) {
@@ -1595,7 +1594,12 @@
 
     switch (constant) {
       case -1:
-        __ rsb(result, left, Operand::Zero());
+        if (overflow) {
+          __ rsb(result, left, Operand::Zero(), SetCC);
+          DeoptimizeIf(vs, instr->environment());
+        } else {
+          __ rsb(result, left, Operand::Zero());
+        }
         break;
       case 0:
         if (bailout_on_minus_zero) {
@@ -1616,23 +1620,21 @@
         int32_t mask = constant >> 31;
         uint32_t constant_abs = (constant + mask) ^ mask;
 
-        if (IsPowerOf2(constant_abs) ||
-            IsPowerOf2(constant_abs - 1) ||
-            IsPowerOf2(constant_abs + 1)) {
-          if (IsPowerOf2(constant_abs)) {
-            int32_t shift = WhichPowerOf2(constant_abs);
-            __ mov(result, Operand(left, LSL, shift));
-          } else if (IsPowerOf2(constant_abs - 1)) {
-            int32_t shift = WhichPowerOf2(constant_abs - 1);
-            __ add(result, left, Operand(left, LSL, shift));
-          } else if (IsPowerOf2(constant_abs + 1)) {
-            int32_t shift = WhichPowerOf2(constant_abs + 1);
-            __ rsb(result, left, Operand(left, LSL, shift));
-          }
-
+        if (IsPowerOf2(constant_abs)) {
+          int32_t shift = WhichPowerOf2(constant_abs);
+          __ mov(result, Operand(left, LSL, shift));
           // Correct the sign of the result is the constant is negative.
           if (constant < 0)  __ rsb(result, result, Operand::Zero());
-
+        } else if (IsPowerOf2(constant_abs - 1)) {
+          int32_t shift = WhichPowerOf2(constant_abs - 1);
+          __ add(result, left, Operand(left, LSL, shift));
+          // Correct the sign of the result is the constant is negative.
+          if (constant < 0)  __ rsb(result, result, Operand::Zero());
+        } else if (IsPowerOf2(constant_abs + 1)) {
+          int32_t shift = WhichPowerOf2(constant_abs + 1);
+          __ rsb(result, left, Operand(left, LSL, shift));
+          // Correct the sign of the result is the constant is negative.
+          if (constant < 0)  __ rsb(result, result, Operand::Zero());
         } else {
           // Generate standard code.
           __ mov(ip, Operand(constant));
@@ -1641,12 +1643,11 @@
     }
 
   } else {
-    Register right = EmitLoadRegister(right_op, scratch);
-    if (bailout_on_minus_zero) {
-      __ orr(ToRegister(instr->temp()), left, right);
-    }
+    ASSERT(right_op->IsRegister());
+    Register right = ToRegister(right_op);
 
-    if (can_overflow) {
+    if (overflow) {
+      Register scratch = scratch0();
       // scratch:result = left * right.
       if (instr->hydrogen()->representation().IsSmi()) {
         __ SmiUntag(result, left);
@@ -1666,12 +1667,12 @@
     }
 
     if (bailout_on_minus_zero) {
-      // Bail out if the result is supposed to be negative zero.
       Label done;
+      __ teq(left, Operand(right));
+      __ b(pl, &done);
+      // Bail out if the result is minus zero.
       __ cmp(result, Operand::Zero());
-      __ b(ne, &done);
-      __ cmp(ToRegister(instr->temp()), Operand::Zero());
-      DeoptimizeIf(mi, instr->environment());
+      DeoptimizeIf(eq, instr->environment());
       __ bind(&done);
     }
   }
@@ -1868,7 +1869,7 @@
 
 
 void LCodeGen::DoConstantT(LConstantT* instr) {
-  Handle<Object> value = instr->value();
+  Handle<Object> value = instr->value(isolate());
   AllowDeferredHandleDereference smi_check;
   __ LoadObject(ToRegister(instr->result()), value);
 }
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index cb02931..c1c87d9 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -924,6 +924,35 @@
 }
 
 
+// Generate call to api function.
+static void GenerateFastApiCall(MacroAssembler* masm,
+                                const CallOptimization& optimization,
+                                Register receiver,
+                                Register scratch,
+                                int argc,
+                                Register* values) {
+  ASSERT(optimization.is_simple_api_call());
+  ASSERT(!receiver.is(scratch));
+
+  const int stack_space = kFastApiCallArguments + argc + 1;
+  // Assign stack space for the call arguments.
+  __ sub(sp, sp, Operand(stack_space * kPointerSize));
+  // Write holder to stack frame.
+  __ str(receiver, MemOperand(sp, 0));
+  // Write receiver to stack frame.
+  int index = stack_space - 1;
+  __ str(receiver, MemOperand(sp, index * kPointerSize));
+  // Write the arguments to stack frame.
+  for (int i = 0; i < argc; i++) {
+    ASSERT(!receiver.is(values[i]));
+    ASSERT(!scratch.is(values[i]));
+    __ str(receiver, MemOperand(sp, index-- * kPointerSize));
+  }
+
+  GenerateFastApiDirectCall(masm, optimization, argc);
+}
+
+
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
   CallInterceptorCompiler(StubCompiler* stub_compiler,
@@ -1381,19 +1410,8 @@
 
 void BaseLoadStubCompiler::GenerateLoadCallback(
     const CallOptimization& call_optimization) {
-  ASSERT(call_optimization.is_simple_api_call());
-
-  // Assign stack space for the call arguments.
-  __ sub(sp, sp, Operand((kFastApiCallArguments + 1) * kPointerSize));
-
-  int argc = 0;
-  int api_call_argc = argc + kFastApiCallArguments;
-  // Write holder to stack frame.
-  __ str(receiver(), MemOperand(sp, 0));
-  // Write receiver to stack frame.
-  __ str(receiver(), MemOperand(sp, api_call_argc * kPointerSize));
-
-  GenerateFastApiDirectCall(masm(), call_optimization, argc);
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch3(), 0, NULL);
 }
 
 
@@ -2793,6 +2811,24 @@
 }
 
 
+Handle<Code> StoreStubCompiler::CompileStoreCallback(
+    Handle<JSObject> object,
+    Handle<JSObject> holder,
+    Handle<Name> name,
+    const CallOptimization& call_optimization) {
+  Label success;
+  HandlerFrontend(object, receiver(), holder, name, &success);
+  __ bind(&success);
+
+  Register values[] = { value() };
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch3(), 1, values);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::CALLBACKS, name);
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/src/ast.cc b/src/ast.cc
index cbadb75..6d1dc12 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -646,8 +646,15 @@
     Literal* key = property->key()->AsLiteral();
     ASSERT(key != NULL && key->value()->IsString());
     Handle<String> name = Handle<String>::cast(key->value());
+    check_type_ = oracle->GetCallCheckType(this);
     receiver_types_.Clear();
-    oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
+    if (check_type_ == RECEIVER_MAP_CHECK) {
+      oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
+      is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0;
+    } else {
+      holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate());
+      receiver_types_.Add(handle(holder_->map()), oracle->zone());
+    }
 #ifdef DEBUG
     if (FLAG_enable_slow_asserts) {
       int length = receiver_types_.length();
@@ -657,17 +664,8 @@
       }
     }
 #endif
-    check_type_ = oracle->GetCallCheckType(this);
     if (is_monomorphic_) {
-      Handle<Map> map;
-      if (receiver_types_.length() > 0) {
-        ASSERT(check_type_ == RECEIVER_MAP_CHECK);
-        map = receiver_types_.at(0);
-      } else {
-        ASSERT(check_type_ != RECEIVER_MAP_CHECK);
-        holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate());
-        map = Handle<Map>(holder_->map());
-      }
+      Handle<Map> map = receiver_types_.first();
       is_monomorphic_ = ComputeTarget(map, name);
     }
   }
diff --git a/src/ast.h b/src/ast.h
index d0454fb..c630906 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -288,6 +288,14 @@
     Add(map, zone);
   }
 
+  void FilterForPossibleTransitions(Map* root_map) {
+    for (int i = list_.length() - 1; i >= 0; i--) {
+      if (at(i)->FindRootMap() != root_map) {
+        list_.RemoveElement(list_.at(i));
+      }
+    }
+  }
+
   void Add(Handle<Map> handle, Zone* zone) {
     list_.Add(handle.location(), zone);
   }
@@ -366,12 +374,6 @@
     UNREACHABLE();
     return NULL;
   }
-  Handle<Map> GetMonomorphicReceiverType() {
-    ASSERT(IsMonomorphic());
-    SmallMapList* types = GetReceiverTypes();
-    ASSERT(types != NULL && types->length() == 1);
-    return types->at(0);
-  }
   virtual KeyedAccessStoreMode GetStoreMode() {
     UNREACHABLE();
     return STANDARD_STORE;
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index 6e93b64..74e0d82 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -103,50 +103,54 @@
   return false;
 }
 
-
-bool ProfilerEventsProcessor::ProcessTicks() {
-  while (true) {
-    while (!ticks_from_vm_buffer_.IsEmpty()
-        && ticks_from_vm_buffer_.Peek()->order ==
-           last_processed_code_event_id_) {
-      TickSampleEventRecord record;
-      ticks_from_vm_buffer_.Dequeue(&record);
-      generator_->RecordTickSample(record.sample);
-    }
-
-    const TickSampleEventRecord* record = ticks_buffer_.Peek();
-    if (record == NULL) return !ticks_from_vm_buffer_.IsEmpty();
-    if (record->order != last_processed_code_event_id_) return true;
-    generator_->RecordTickSample(record->sample);
-    ticks_buffer_.Remove();
+ProfilerEventsProcessor::SampleProcessingResult
+    ProfilerEventsProcessor::ProcessOneSample() {
+  if (!ticks_from_vm_buffer_.IsEmpty()
+      && ticks_from_vm_buffer_.Peek()->order ==
+         last_processed_code_event_id_) {
+    TickSampleEventRecord record;
+    ticks_from_vm_buffer_.Dequeue(&record);
+    generator_->RecordTickSample(record.sample);
+    return OneSampleProcessed;
   }
-}
 
-
-void ProfilerEventsProcessor::ProcessEventsAndDoSample() {
-  ElapsedTimer timer;
-  timer.Start();
-  // Keep processing existing events until we need to do next sample.
-  while (!timer.HasExpired(period_)) {
-    if (ProcessTicks()) {
-      // All ticks of the current dequeue_order are processed,
-      // proceed to the next code event.
-      ProcessCodeEvent();
-    }
+  const TickSampleEventRecord* record = ticks_buffer_.Peek();
+  if (record == NULL) {
+    if (ticks_from_vm_buffer_.IsEmpty()) return NoSamplesInQueue;
+    return FoundSampleForNextCodeEvent;
   }
-  // Schedule next sample. sampler_ is NULL in tests.
-  if (sampler_) sampler_->DoSample();
+  if (record->order != last_processed_code_event_id_) {
+    return FoundSampleForNextCodeEvent;
+  }
+  generator_->RecordTickSample(record->sample);
+  ticks_buffer_.Remove();
+  return OneSampleProcessed;
 }
 
 
 void ProfilerEventsProcessor::Run() {
   while (running_) {
-    ProcessEventsAndDoSample();
+    ElapsedTimer timer;
+    timer.Start();
+    // Keep processing existing events until we need to do next sample.
+    do {
+      if (FoundSampleForNextCodeEvent == ProcessOneSample()) {
+        // All ticks of the current last_processed_code_event_id_ are
+        // processed, proceed to the next code event.
+        ProcessCodeEvent();
+      }
+    } while (!timer.HasExpired(period_));
+
+    // Schedule next sample. sampler_ is NULL in tests.
+    if (sampler_) sampler_->DoSample();
   }
 
   // Process remaining tick events.
   do {
-    ProcessTicks();
+    SampleProcessingResult result;
+    do {
+      result = ProcessOneSample();
+    } while (result == OneSampleProcessed);
   } while (ProcessCodeEvent());
 }
 
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index e36c301..8aba542 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -161,9 +161,13 @@
  private:
   // Called from events processing thread (Run() method.)
   bool ProcessCodeEvent();
-  bool ProcessTicks();
 
-  void ProcessEventsAndDoSample();
+  enum SampleProcessingResult {
+    OneSampleProcessed,
+    FoundSampleForNextCodeEvent,
+    NoSamplesInQueue
+  };
+  SampleProcessingResult ProcessOneSample();
 
   ProfileGenerator* generator_;
   Sampler* sampler_;
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index a588b4c..19209d4 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -957,12 +957,17 @@
   this.selected_frame = 0;
 }
 
-ExecutionState.prototype.prepareStep = function(opt_action, opt_count) {
+ExecutionState.prototype.prepareStep = function(opt_action, opt_count,
+    opt_callframe) {
   var action = Debug.StepAction.StepIn;
   if (!IS_UNDEFINED(opt_action)) action = %ToNumber(opt_action);
   var count = opt_count ? %ToNumber(opt_count) : 1;
+  var callFrameId = 0;
+  if (!IS_UNDEFINED(opt_callframe)) {
+    callFrameId = opt_callframe.details_.frameId();
+  }
 
-  return %PrepareStep(this.break_id, action, count);
+  return %PrepareStep(this.break_id, action, count, callFrameId);
 };
 
 ExecutionState.prototype.evaluateGlobal = function(source, disable_break,
diff --git a/src/debug.cc b/src/debug.cc
index c82a2aa..7624f26 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1017,7 +1017,7 @@
       // Clear queue
       thread_local_.queued_step_count_ = 0;
 
-      PrepareStep(StepNext, step_count);
+      PrepareStep(StepNext, step_count, StackFrame::NO_ID);
     } else {
       // Notify the debug event listeners.
       isolate_->debugger()->OnDebugBreak(break_points_hit, false);
@@ -1055,7 +1055,7 @@
     ClearStepping();
 
     // Set up for the remaining steps.
-    PrepareStep(step_action, step_count);
+    PrepareStep(step_action, step_count, StackFrame::NO_ID);
   }
 
   if (thread_local_.frame_drop_mode_ == FRAMES_UNTOUCHED) {
@@ -1376,7 +1376,9 @@
 }
 
 
-void Debug::PrepareStep(StepAction step_action, int step_count) {
+void Debug::PrepareStep(StepAction step_action,
+                        int step_count,
+                        StackFrame::Id frame_id) {
   HandleScope scope(isolate_);
 
   PrepareForBreakPoints();
@@ -1402,6 +1404,9 @@
     // If there is no JavaScript stack don't do anything.
     return;
   }
+  if (frame_id != StackFrame::NO_ID) {
+    id = frame_id;
+  }
   JavaScriptFrameIterator frames_it(isolate_, id);
   JavaScriptFrame* frame = frames_it.frame();
 
diff --git a/src/debug.h b/src/debug.h
index 85f7583..03ee40e 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -261,7 +261,9 @@
   void FloodHandlerWithOneShot();
   void ChangeBreakOnException(ExceptionBreakType type, bool enable);
   bool IsBreakOnException(ExceptionBreakType type);
-  void PrepareStep(StepAction step_action, int step_count);
+  void PrepareStep(StepAction step_action,
+                   int step_count,
+                   StackFrame::Id frame_id);
   void ClearStepping();
   void ClearStepOut();
   bool IsStepping() { return thread_local_.step_count_ > 0; }
diff --git a/src/execution.cc b/src/execution.cc
index 91d340e..c59a737 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -705,12 +705,14 @@
     Handle<FunctionTemplateInfo> data,
     bool* exc) {
   Isolate* isolate = data->GetIsolate();
-  // Fast case: see if the function has already been instantiated
-  int serial_number = Smi::cast(data->serial_number())->value();
-  Object* elm =
-      isolate->native_context()->function_cache()->
-          GetElementNoExceptionThrown(isolate, serial_number);
-  if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
+  if (!data->do_not_cache()) {
+    // Fast case: see if the function has already been instantiated
+    int serial_number = Smi::cast(data->serial_number())->value();
+    Object* elm =
+        isolate->native_context()->function_cache()->
+            GetElementNoExceptionThrown(isolate, serial_number);
+    if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
+  }
   // The function has not yet been instantiated in this context; do it.
   Handle<Object> args[] = { data };
   Handle<Object> result = Call(isolate,
diff --git a/src/global-handles.cc b/src/global-handles.cc
index 4a2aad3..1a98e49 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -90,7 +90,7 @@
     set_partially_dependent(false);
     set_in_new_space_list(false);
     parameter_or_next_free_.next_free = NULL;
-    weak_reference_callback_ = NULL;
+    weak_callback_ = NULL;
   }
 #endif
 
@@ -111,7 +111,7 @@
     set_partially_dependent(false);
     set_state(NORMAL);
     parameter_or_next_free_.parameter = NULL;
-    weak_reference_callback_ = NULL;
+    weak_callback_ = NULL;
     IncreaseBlockUses();
   }
 
@@ -123,7 +123,7 @@
     class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
     set_independent(false);
     set_partially_dependent(false);
-    weak_reference_callback_ = NULL;
+    weak_callback_ = NULL;
     DecreaseBlockUses();
   }
 
@@ -169,6 +169,13 @@
     flags_ = IsInNewSpaceList::update(flags_, v);
   }
 
+  bool is_revivable_callback() {
+    return IsRevivableCallback::decode(flags_);
+  }
+  void set_revivable_callback(bool v) {
+    flags_ = IsRevivableCallback::update(flags_, v);
+  }
+
   bool IsNearDeath() const {
     // Check for PENDING to ensure correct answer when processing callbacks.
     return state() == PENDING || state() == NEAR_DEATH;
@@ -228,11 +235,20 @@
   }
 
   void MakeWeak(void* parameter,
-                RevivableCallback weak_reference_callback) {
+                WeakCallback weak_callback,
+                RevivableCallback revivable_callback) {
+    ASSERT((weak_callback == NULL) != (revivable_callback == NULL));
     ASSERT(state() != FREE);
     set_state(WEAK);
     set_parameter(parameter);
-    weak_reference_callback_ = weak_reference_callback;
+    if (weak_callback != NULL) {
+      weak_callback_ = weak_callback;
+      set_revivable_callback(false);
+    } else {
+      weak_callback_ =
+          reinterpret_cast<WeakCallback>(revivable_callback);
+      set_revivable_callback(true);
+    }
   }
 
   void ClearWeakness() {
@@ -243,7 +259,7 @@
 
   bool PostGarbageCollectionProcessing(Isolate* isolate) {
     if (state() != Node::PENDING) return false;
-    if (weak_reference_callback_ == NULL) {
+    if (weak_callback_ == NULL) {
       Release();
       return false;
     }
@@ -262,9 +278,20 @@
       // Leaving V8.
       VMState<EXTERNAL> state(isolate);
       HandleScope handle_scope(isolate);
-      weak_reference_callback_(reinterpret_cast<v8::Isolate*>(isolate),
-                               reinterpret_cast<Persistent<Value>*>(&object),
-                               par);
+      if (is_revivable_callback()) {
+        RevivableCallback revivable =
+            reinterpret_cast<RevivableCallback>(weak_callback_);
+        revivable(reinterpret_cast<v8::Isolate*>(isolate),
+                  reinterpret_cast<Persistent<Value>*>(&object),
+                  par);
+      } else {
+        Handle<Object> handle(*object, isolate);
+        v8::WeakCallbackData<v8::Value, void> data(
+            reinterpret_cast<v8::Isolate*>(isolate),
+            v8::Utils::ToLocal(handle),
+            par);
+        weak_callback_(data);
+      }
     }
     // Absence of explicit cleanup or revival of weak handle
     // in most of the cases would lead to memory leak.
@@ -272,9 +299,10 @@
     return true;
   }
 
+  inline GlobalHandles* GetGlobalHandles();
+
  private:
   inline NodeBlock* FindBlock();
-  inline GlobalHandles* GetGlobalHandles();
   inline void IncreaseBlockUses();
   inline void DecreaseBlockUses();
 
@@ -297,11 +325,12 @@
   class IsIndependent:        public BitField<bool,  4, 1> {};
   class IsPartiallyDependent: public BitField<bool,  5, 1> {};
   class IsInNewSpaceList:     public BitField<bool,  6, 1> {};
+  class IsRevivableCallback:  public BitField<bool,  7, 1> {};
 
   uint8_t flags_;
 
   // Handle specific callback - might be a weak reference in disguise.
-  RevivableCallback weak_reference_callback_;
+  WeakCallback weak_callback_;
 
   // Provided data for callback.  In FREE state, this is used for
   // the free list link.
@@ -480,6 +509,12 @@
 }
 
 
+Handle<Object> GlobalHandles::CopyGlobal(Object** location) {
+  ASSERT(location != NULL);
+  return Node::FromLocation(location)->GetGlobalHandles()->Create(*location);
+}
+
+
 void GlobalHandles::Destroy(Object** location) {
   if (location != NULL) Node::FromLocation(location)->Release();
 }
@@ -487,9 +522,10 @@
 
 void GlobalHandles::MakeWeak(Object** location,
                              void* parameter,
-                             RevivableCallback weak_reference_callback) {
-  ASSERT(weak_reference_callback != NULL);
-  Node::FromLocation(location)->MakeWeak(parameter, weak_reference_callback);
+                             WeakCallback weak_callback,
+                             RevivableCallback revivable_callback) {
+  Node::FromLocation(location)->MakeWeak(
+      parameter, weak_callback, revivable_callback);
 }
 
 
diff --git a/src/global-handles.h b/src/global-handles.h
index 57cf70e..4b46aac 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -128,9 +128,13 @@
   // Creates a new global handle that is alive until Destroy is called.
   Handle<Object> Create(Object* value);
 
+  // Copy a global handle
+  static Handle<Object> CopyGlobal(Object** location);
+
   // Destroy a global handle.
   static void Destroy(Object** location);
 
+  typedef WeakCallbackData<v8::Value, void>::Callback WeakCallback;
   typedef WeakReferenceCallbacks<v8::Value, void>::Revivable RevivableCallback;
 
   // Make the global handle weak and set the callback parameter for the
@@ -141,7 +145,14 @@
   // reason is that Smi::FromInt(0) does not change during garage collection.
   static void MakeWeak(Object** location,
                        void* parameter,
-                       RevivableCallback weak_reference_callback);
+                       WeakCallback weak_callback,
+                       RevivableCallback revivable_callback);
+
+  static inline void MakeWeak(Object** location,
+                              void* parameter,
+                              RevivableCallback revivable_callback) {
+    MakeWeak(location, parameter, NULL, revivable_callback);
+  }
 
   void RecordStats(HeapStats* stats);
 
diff --git a/src/hydrogen-escape-analysis.cc b/src/hydrogen-escape-analysis.cc
index 00cfe27..997e4f9 100644
--- a/src/hydrogen-escape-analysis.cc
+++ b/src/hydrogen-escape-analysis.cc
@@ -31,7 +31,7 @@
 namespace internal {
 
 
-bool HEscapeAnalysisPhase::HasNoEscapingUses(HValue* value) {
+bool HEscapeAnalysisPhase::HasNoEscapingUses(HValue* value, int size) {
   for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
     HValue* use = it.value();
     if (use->HasEscapingOperandAt(it.index())) {
@@ -41,7 +41,15 @@
       }
       return false;
     }
-    if (use->RedefinedOperandIndex() == it.index() && !HasNoEscapingUses(use)) {
+    if (use->HasOutOfBoundsAccess(size)) {
+      if (FLAG_trace_escape_analysis) {
+        PrintF("#%d (%s) out of bounds at #%d (%s) @%d\n", value->id(),
+               value->Mnemonic(), use->id(), use->Mnemonic(), it.index());
+      }
+      return false;
+    }
+    int redefined_index = use->RedefinedOperandIndex();
+    if (redefined_index == it.index() && !HasNoEscapingUses(use, size)) {
       if (FLAG_trace_escape_analysis) {
         PrintF("#%d (%s) escapes redefinition #%d (%s) @%d\n", value->id(),
                value->Mnemonic(), use->id(), use->Mnemonic(), it.index());
@@ -59,7 +67,11 @@
     HBasicBlock* block = graph()->blocks()->at(i);
     for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
       HInstruction* instr = it.Current();
-      if (instr->IsAllocate() && HasNoEscapingUses(instr)) {
+      if (!instr->IsAllocate()) continue;
+      HAllocate* allocate = HAllocate::cast(instr);
+      if (!allocate->size()->IsInteger32Constant()) continue;
+      int size_in_bytes = allocate->size()->GetInteger32Constant();
+      if (HasNoEscapingUses(instr, size_in_bytes)) {
         if (FLAG_trace_escape_analysis) {
           PrintF("#%d (%s) is being captured\n", instr->id(),
                  instr->Mnemonic());
@@ -290,7 +302,6 @@
     HAllocate* allocate = HAllocate::cast(captured_.at(i));
 
     // Compute number of scalar values and start with clean slate.
-    if (!allocate->size()->IsInteger32Constant()) continue;
     int size_in_bytes = allocate->size()->GetInteger32Constant();
     number_of_values_ = size_in_bytes / kPointerSize;
     number_of_objects_++;
diff --git a/src/hydrogen-escape-analysis.h b/src/hydrogen-escape-analysis.h
index 311a653..3e27cc1 100644
--- a/src/hydrogen-escape-analysis.h
+++ b/src/hydrogen-escape-analysis.h
@@ -49,7 +49,7 @@
 
  private:
   void CollectCapturedValues();
-  bool HasNoEscapingUses(HValue* value);
+  bool HasNoEscapingUses(HValue* value, int size);
   void PerformScalarReplacement();
   void AnalyzeDataFlow(HInstruction* instr);
 
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index cd8755a..2855e8a 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -2575,12 +2575,13 @@
 
 Maybe<HConstant*> HConstant::CopyToTruncatedNumber(Zone* zone) {
   HConstant* res = NULL;
-  if (handle()->IsBoolean()) {
-    res = handle()->BooleanValue() ?
+  Handle<Object> handle = this->handle(zone->isolate());
+  if (handle->IsBoolean()) {
+    res = handle->BooleanValue() ?
       new(zone) HConstant(1) : new(zone) HConstant(0);
-  } else if (handle()->IsUndefined()) {
+  } else if (handle->IsUndefined()) {
     res = new(zone) HConstant(OS::nan_value());
-  } else if (handle()->IsNull()) {
+  } else if (handle->IsNull()) {
     res = new(zone) HConstant(0);
   }
   return Maybe<HConstant*>(res != NULL, res);
@@ -2596,7 +2597,7 @@
     stream->Add("%p ", reinterpret_cast<void*>(
             external_reference_value_.address()));
   } else {
-    handle()->ShortPrint(stream);
+    handle(Isolate::Current())->ShortPrint(stream);
   }
 }
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index a6d8915..2bfb284 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -867,6 +867,7 @@
 
   // Escape analysis helpers.
   virtual bool HasEscapingOperandAt(int index) { return true; }
+  virtual bool HasOutOfBoundsAccess(int size) { return false; }
 
   // Representation helpers.
   virtual Representation observed_input_representation(int index) {
@@ -3285,9 +3286,9 @@
     return new_constant;
   }
 
-  Handle<Object> handle() {
+  Handle<Object> handle(Isolate* isolate) {
     if (handle_.is_null()) {
-      Factory* factory = Isolate::Current()->factory();
+      Factory* factory = isolate->factory();
       // Default arguments to is_not_in_new_space depend on this heap number
       // to be tenured so that it's guaranteed not be be located in new space.
       handle_ = factory->NewNumber(double_value_, TENURED);
@@ -3298,7 +3299,7 @@
   }
 
   bool HasMap(Handle<Map> map) {
-    Handle<Object> constant_object = handle();
+    Handle<Object> constant_object = handle(map->GetIsolate());
     return constant_object->IsHeapObject() &&
         Handle<HeapObject>::cast(constant_object)->map() == *map;
   }
@@ -3358,7 +3359,6 @@
 
   virtual bool EmitAtUses() V8_OVERRIDE;
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
-  bool IsInteger() { return handle()->IsSmi(); }
   HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
   Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
   Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone);
@@ -5756,6 +5756,9 @@
   }
 
   virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
+  virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
+    return !access().IsInobject() || access().offset() >= size;
+  }
   virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     if (index == 0 && access().IsExternalMemory()) {
       // object must be external in case of external memory access
@@ -6071,6 +6074,9 @@
   virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE {
     return index == 1;
   }
+  virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
+    return !access().IsInobject() || access().offset() >= size;
+  }
   virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
     if (index == 0 && access().IsExternalMemory()) {
       // object must be external in case of external memory access
@@ -6105,7 +6111,8 @@
 
   Handle<Map> transition_map() const {
     if (has_transition()) {
-      return Handle<Map>::cast(HConstant::cast(transition())->handle());
+      return Handle<Map>::cast(
+          HConstant::cast(transition())->handle(Isolate::Current()));
     } else {
       return Handle<Map>();
     }
@@ -6113,7 +6120,7 @@
 
   void SetTransition(HConstant* map_constant, CompilationInfo* info) {
     ASSERT(!has_transition());  // Only set once.
-    Handle<Map> map = Handle<Map>::cast(map_constant->handle());
+    Handle<Map> map = Handle<Map>::cast(map_constant->handle(info->isolate()));
     if (map->CanBeDeprecated()) {
       map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info);
     }
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index d6b8d64..437d29b 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4896,40 +4896,111 @@
 }
 
 
-void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
-  Property* prop = expr->target()->AsProperty();
-  ASSERT(prop != NULL);
-  CHECK_ALIVE(VisitForValue(prop->obj()));
+static bool ComputeReceiverTypes(Expression* expr,
+                                 HValue* receiver,
+                                 SmallMapList** t) {
+  SmallMapList* types = expr->GetReceiverTypes();
+  *t = types;
+  bool monomorphic = expr->IsMonomorphic();
+  if (types != NULL && receiver->HasMonomorphicJSObjectType()) {
+    Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap();
+    types->FilterForPossibleTransitions(root_map);
+    monomorphic = types->length() == 1;
+  }
+  return monomorphic && CanInlinePropertyAccess(*types->first());
+}
 
-  if (prop->key()->IsPropertyName()) {
-    // Named store.
-    CHECK_ALIVE(VisitForValue(expr->value()));
-    HValue* value = environment()->ExpressionStackAt(0);
-    HValue* object = environment()->ExpressionStackAt(1);
 
-    if (expr->IsUninitialized()) {
-      Add<HDeoptimize>("Insufficient type feedback for property assignment",
-                       Deoptimizer::SOFT);
-    }
-    return BuildStoreNamed(
-        expr, expr->id(), expr->AssignmentId(), prop, object, value);
-  } else {
+void HOptimizedGraphBuilder::BuildStore(Expression* expr,
+                                        Property* prop,
+                                        BailoutId ast_id,
+                                        BailoutId return_id,
+                                        bool is_uninitialized) {
+  HValue* value = environment()->ExpressionStackAt(0);
+
+  if (!prop->key()->IsPropertyName()) {
     // Keyed store.
-    CHECK_ALIVE(VisitForValue(prop->key()));
-    CHECK_ALIVE(VisitForValue(expr->value()));
-    HValue* value = environment()->ExpressionStackAt(0);
     HValue* key = environment()->ExpressionStackAt(1);
     HValue* object = environment()->ExpressionStackAt(2);
     bool has_side_effects = false;
-    HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
+    HandleKeyedElementAccess(object, key, value, expr, return_id,
                              expr->position(),
                              true,  // is_store
                              &has_side_effects);
     Drop(3);
     Push(value);
-    Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
+    Add<HSimulate>(return_id, REMOVABLE_SIMULATE);
     return ast_context()->ReturnValue(Pop());
   }
+
+  // Named store.
+  HValue* object = environment()->ExpressionStackAt(1);
+
+  if (is_uninitialized) {
+    Add<HDeoptimize>("Insufficient type feedback for property assignment",
+                     Deoptimizer::SOFT);
+  }
+
+  Literal* key = prop->key()->AsLiteral();
+  Handle<String> name = Handle<String>::cast(key->value());
+  ASSERT(!name.is_null());
+
+  HInstruction* instr = NULL;
+
+  SmallMapList* types;
+  bool monomorphic = ComputeReceiverTypes(expr, object, &types);
+
+  if (monomorphic) {
+    Handle<Map> map = types->first();
+    Handle<JSFunction> setter;
+    Handle<JSObject> holder;
+    if (LookupSetter(map, name, &setter, &holder)) {
+      AddCheckConstantFunction(holder, object, map);
+      if (FLAG_inline_accessors &&
+          TryInlineSetter(setter, ast_id, return_id, value)) {
+        return;
+      }
+      Drop(2);
+      Add<HPushArgument>(object);
+      Add<HPushArgument>(value);
+      instr = new(zone()) HCallConstantFunction(setter, 2);
+    } else {
+      Drop(2);
+      CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
+                                                     name,
+                                                     value,
+                                                     map));
+    }
+  } else if (types != NULL && types->length() > 1) {
+    Drop(2);
+    return HandlePolymorphicStoreNamedField(
+        expr->position(), ast_id, object, value, types, name);
+  } else {
+    Drop(2);
+    instr = BuildStoreNamedGeneric(object, name, value);
+  }
+
+  if (!ast_context()->IsEffect()) Push(value);
+  instr->set_position(expr->position());
+  AddInstruction(instr);
+  if (instr->HasObservableSideEffects()) {
+    Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
+  }
+  if (!ast_context()->IsEffect()) Drop(1);
+  return ast_context()->ReturnValue(value);
+}
+
+
+void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
+  Property* prop = expr->target()->AsProperty();
+  ASSERT(prop != NULL);
+  CHECK_ALIVE(VisitForValue(prop->obj()));
+  if (!prop->key()->IsPropertyName()) {
+    CHECK_ALIVE(VisitForValue(prop->key()));
+  }
+  CHECK_ALIVE(VisitForValue(expr->value()));
+  BuildStore(expr, prop, expr->id(),
+             expr->AssignmentId(), expr->IsUninitialized());
 }
 
 
@@ -4978,64 +5049,6 @@
 }
 
 
-void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
-                                             BailoutId id,
-                                             BailoutId assignment_id,
-                                             Property* prop,
-                                             HValue* object,
-                                             HValue* value) {
-  Literal* key = prop->key()->AsLiteral();
-  Handle<String> name = Handle<String>::cast(key->value());
-  ASSERT(!name.is_null());
-
-  HInstruction* instr = NULL;
-  SmallMapList* types = expr->GetReceiverTypes();
-  bool monomorphic = expr->IsMonomorphic();
-  Handle<Map> map;
-  if (monomorphic) {
-    map = types->first();
-    monomorphic = CanInlinePropertyAccess(*map);
-  }
-  if (monomorphic) {
-    Handle<JSFunction> setter;
-    Handle<JSObject> holder;
-    if (LookupSetter(map, name, &setter, &holder)) {
-      AddCheckConstantFunction(holder, object, map);
-      if (FLAG_inline_accessors &&
-          TryInlineSetter(setter, id, assignment_id, value)) {
-        return;
-      }
-      Drop(2);
-      Add<HPushArgument>(object);
-      Add<HPushArgument>(value);
-      instr = new(zone()) HCallConstantFunction(setter, 2);
-    } else {
-      Drop(2);
-      CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
-                                                     name,
-                                                     value,
-                                                     map));
-    }
-  } else if (types != NULL && types->length() > 1) {
-    Drop(2);
-    return HandlePolymorphicStoreNamedField(
-        expr->position(), id, object, value, types, name);
-  } else {
-    Drop(2);
-    instr = BuildStoreNamedGeneric(object, name, value);
-  }
-
-  if (!ast_context()->IsEffect()) Push(value);
-  instr->set_position(expr->position());
-  AddInstruction(instr);
-  if (instr->HasObservableSideEffects()) {
-    Add<HSimulate>(id, REMOVABLE_SIMULATE);
-  }
-  if (!ast_context()->IsEffect()) Drop(1);
-  return ast_context()->ReturnValue(value);
-}
-
-
 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
   Expression* target = expr->target();
   VariableProxy* proxy = target->AsVariableProxy();
@@ -5117,62 +5130,30 @@
     return ast_context()->ReturnValue(Pop());
 
   } else if (prop != NULL) {
-    if (prop->key()->IsPropertyName()) {
-      // Named property.
-      CHECK_ALIVE(VisitForValue(prop->obj()));
-      HValue* object = Top();
-      CHECK_ALIVE(PushLoad(prop, object, expr->position()));
-
-      CHECK_ALIVE(VisitForValue(expr->value()));
-      HValue* right = Pop();
-      HValue* left = Pop();
-
-      HInstruction* instr = BuildBinaryOperation(operation, left, right);
-      PushAndAdd(instr);
-      if (instr->HasObservableSideEffects()) {
-        Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
-      }
-
-      return BuildStoreNamed(
-          expr, expr->id(), expr->AssignmentId(), prop, object, instr);
-    } else {
-      // Keyed property.
-      CHECK_ALIVE(VisitForValue(prop->obj()));
+    CHECK_ALIVE(VisitForValue(prop->obj()));
+    HValue* object = Top();
+    HValue* key = NULL;
+    if ((!prop->IsStringLength() &&
+         !prop->IsFunctionPrototype() &&
+         !prop->key()->IsPropertyName()) ||
+        prop->IsStringAccess()) {
       CHECK_ALIVE(VisitForValue(prop->key()));
-      HValue* obj = environment()->ExpressionStackAt(1);
-      HValue* key = environment()->ExpressionStackAt(0);
-
-      bool has_side_effects = false;
-      HValue* load = HandleKeyedElementAccess(
-          obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
-          false,  // is_store
-          &has_side_effects);
-      Push(load);
-      if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
-
-      CHECK_ALIVE(VisitForValue(expr->value()));
-      HValue* right = Pop();
-      HValue* left = Pop();
-
-      HInstruction* instr = BuildBinaryOperation(operation, left, right);
-      PushAndAdd(instr);
-      if (instr->HasObservableSideEffects()) {
-        Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
-      }
-
-      HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
-                               RelocInfo::kNoPosition,
-                               true,  // is_store
-                               &has_side_effects);
-
-      // Drop the simulated receiver, key, and value.  Return the value.
-      Drop(3);
-      Push(instr);
-      ASSERT(has_side_effects);  // Stores always have side effects.
-      Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
-      return ast_context()->ReturnValue(Pop());
+      key = Top();
     }
 
+    CHECK_ALIVE(PushLoad(prop, object, key, expr->position()));
+
+    CHECK_ALIVE(VisitForValue(expr->value()));
+    HValue* right = Pop();
+    HValue* left = Pop();
+
+    HInstruction* instr = BuildBinaryOperation(operation, left, right);
+    PushAndAdd(instr);
+    if (instr->HasObservableSideEffects()) {
+      Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE);
+    }
+    BuildStore(expr, prop, expr->id(),
+               expr->AssignmentId(), expr->IsUninitialized());
   } else {
     return Bailout(kInvalidLhsInCompoundAssignment);
   }
@@ -5692,8 +5673,12 @@
     bool* has_side_effects) {
   ASSERT(!expr->IsPropertyName());
   HInstruction* instr = NULL;
-  if (expr->IsMonomorphic()) {
-    Handle<Map> map = expr->GetMonomorphicReceiverType();
+
+  SmallMapList* types;
+  bool monomorphic = ComputeReceiverTypes(expr, obj, &types);
+
+  if (monomorphic) {
+    Handle<Map> map = types->first();
     if (map->has_slow_elements_kind()) {
       instr = is_store ? BuildStoreKeyedGeneric(obj, key, val)
                        : BuildLoadKeyedGeneric(obj, key);
@@ -5796,8 +5781,7 @@
     }
   } else {
     Push(graph()->GetArgumentsObject());
-    VisitForValue(expr->key());
-    if (HasStackOverflow() || current_block() == NULL) return true;
+    CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true);
     HValue* key = Pop();
     Drop(1);  // Arguments object.
     if (function_state()->outer() == NULL) {
@@ -5824,9 +5808,11 @@
 
 void HOptimizedGraphBuilder::PushLoad(Property* expr,
                                       HValue* object,
+                                      HValue* key,
                                       int position) {
   ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
   Push(object);
+  if (key != NULL) Push(key);
   BuildLoad(expr, position, expr->LoadId());
 }
 
@@ -5842,7 +5828,6 @@
         AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
     instr = BuildLoadStringLength(string, checkstring);
   } else if (expr->IsStringAccess()) {
-    CHECK_ALIVE(VisitForValue(expr->key()));
     HValue* index = Pop();
     HValue* string = Pop();
     HValue* context = environment()->context();
@@ -5858,19 +5843,13 @@
 
   } else if (expr->key()->IsPropertyName()) {
     Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
-    SmallMapList* types = expr->GetReceiverTypes();
     HValue* object = Top();
 
-    Handle<Map> map;
-    bool monomorphic = false;
-    if (expr->IsMonomorphic()) {
-      map = types->first();
-      monomorphic = CanInlinePropertyAccess(*map);
-    } else if (object->HasMonomorphicJSObjectType()) {
-      map = object->GetMonomorphicJSObjectMap();
-      monomorphic = CanInlinePropertyAccess(*map);
-    }
+    SmallMapList* types;
+    bool monomorphic = ComputeReceiverTypes(expr, object, &types);
+
     if (monomorphic) {
+      Handle<Map> map = types->first();
       Handle<JSFunction> getter;
       Handle<JSObject> holder;
       if (LookupGetter(map, name, &getter, &holder)) {
@@ -5892,8 +5871,6 @@
     }
 
   } else {
-    CHECK_ALIVE(VisitForValue(expr->key()));
-
     HValue* key = Pop();
     HValue* obj = Pop();
 
@@ -5926,6 +5903,13 @@
   if (TryArgumentsAccess(expr)) return;
 
   CHECK_ALIVE(VisitForValue(expr->obj()));
+  if ((!expr->IsStringLength() &&
+       !expr->IsFunctionPrototype() &&
+       !expr->key()->IsPropertyName()) ||
+      expr->IsStringAccess()) {
+    CHECK_ALIVE(VisitForValue(expr->key()));
+  }
+
   BuildLoad(expr, expr->position(), expr->id());
 }
 
@@ -6865,14 +6849,12 @@
   if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
 
   // Found pattern f.apply(receiver, arguments).
-  VisitForValue(prop->obj());
-  if (HasStackOverflow() || current_block() == NULL) return true;
+  CHECK_ALIVE_OR_RETURN(VisitForValue(prop->obj()), true);
   HValue* function = Top();
   AddCheckConstantFunction(expr->holder(), function, function_map);
   Drop(1);
 
-  VisitForValue(args->at(0));
-  if (HasStackOverflow() || current_block() == NULL) return true;
+  CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true);
   HValue* receiver = Pop();
 
   if (function_state()->outer() == NULL) {
@@ -6903,7 +6885,8 @@
     Handle<JSFunction> known_function;
     if (function->IsConstant()) {
       HConstant* constant_function = HConstant::cast(function);
-      known_function = Handle<JSFunction>::cast(constant_function->handle());
+      known_function = Handle<JSFunction>::cast(
+          constant_function->handle(isolate()));
       int args_count = arguments_count - 1;  // Excluding receiver.
       if (TryInlineApply(known_function, expr, args_count)) return true;
     }
@@ -6965,23 +6948,19 @@
     CHECK_ALIVE(VisitExpressions(expr->arguments()));
 
     Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
-    SmallMapList* types = expr->GetReceiverTypes();
-
-    bool monomorphic = expr->IsMonomorphic();
-    Handle<Map> receiver_map;
-    if (monomorphic) {
-      receiver_map = (types == NULL || types->is_empty())
-          ? Handle<Map>::null()
-          : types->first();
-    }
-
     HValue* receiver =
         environment()->ExpressionStackAt(expr->arguments()->length());
+
+    SmallMapList* types;
+    bool was_monomorphic = expr->IsMonomorphic();
+    bool monomorphic = ComputeReceiverTypes(expr, receiver, &types);
+    if (!was_monomorphic && monomorphic) {
+      monomorphic = expr->ComputeTarget(types->first(), name);
+    }
+
     if (monomorphic) {
-      if (TryInlineBuiltinMethodCall(expr,
-                                     receiver,
-                                     receiver_map,
-                                     expr->check_type())) {
+      Handle<Map> map = types->first();
+      if (TryInlineBuiltinMethodCall(expr, receiver, map, expr->check_type())) {
         if (FLAG_trace_inlining) {
           PrintF("Inlining builtin ");
           expr->target()->ShortPrint();
@@ -6999,7 +6978,7 @@
         call = PreProcessCall(
             new(zone()) HCallNamed(context, name, argument_count));
       } else {
-        AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
+        AddCheckConstantFunction(expr->holder(), receiver, map);
 
         if (TryInlineCall(expr)) return;
         call = PreProcessCall(
@@ -7474,16 +7453,18 @@
 }
 
 
-void HOptimizedGraphBuilder::BuildStoreInEffect(Expression* expr,
-                                                Property* prop,
-                                                BailoutId ast_id,
-                                                BailoutId return_id,
-                                                HValue* object,
-                                                HValue* value) {
+void HOptimizedGraphBuilder::BuildStoreForEffect(Expression* expr,
+                                                 Property* prop,
+                                                 BailoutId ast_id,
+                                                 BailoutId return_id,
+                                                 HValue* object,
+                                                 HValue* key,
+                                                 HValue* value) {
   EffectContext for_effect(this);
   Push(object);
+  if (key != NULL) Push(key);
   Push(value);
-  BuildStoreNamed(expr, ast_id, return_id, prop, object, value);
+  BuildStore(expr, prop, ast_id, return_id);
 }
 
 
@@ -7563,69 +7544,42 @@
         return Bailout(kLookupVariableInCountOperation);
     }
 
-  } else {
-    // Argument of the count operation is a property.
-    ASSERT(prop != NULL);
-
-    if (prop->key()->IsPropertyName()) {
-      // Named property.
-      if (returns_original_input) Push(graph()->GetConstantUndefined());
-
-      CHECK_ALIVE(VisitForValue(prop->obj()));
-      HValue* object = Top();
-      CHECK_ALIVE(PushLoad(prop, object, expr->position()));
-
-      after = BuildIncrement(returns_original_input, expr);
-
-      if (returns_original_input) {
-        HValue* result = Pop();
-        HValue* object = Pop();
-        environment()->SetExpressionStackAt(0, result);
-        CHECK_ALIVE(BuildStoreInEffect(
-            expr, prop, expr->id(), expr->AssignmentId(), object, after));
-        return ast_context()->ReturnValue(Pop());
-      }
-
-      return BuildStoreNamed(
-          expr, expr->id(), expr->AssignmentId(), prop, object, after);
-    } else {
-      // Keyed property.
-      if (returns_original_input) Push(graph()->GetConstantUndefined());
-
-      CHECK_ALIVE(VisitForValue(prop->obj()));
-      CHECK_ALIVE(VisitForValue(prop->key()));
-      HValue* obj = environment()->ExpressionStackAt(1);
-      HValue* key = environment()->ExpressionStackAt(0);
-
-      bool has_side_effects = false;
-      HValue* load = HandleKeyedElementAccess(
-          obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
-          false,  // is_store
-          &has_side_effects);
-      Push(load);
-      if (has_side_effects) Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE);
-
-      after = BuildIncrement(returns_original_input, expr);
-      input = environment()->ExpressionStackAt(0);
-
-      HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(),
-                               RelocInfo::kNoPosition,
-                               true,  // is_store
-                               &has_side_effects);
-
-      // Drop the key and the original value from the bailout environment.
-      // Overwrite the receiver with the result of the operation, and the
-      // placeholder with the original value if necessary.
-      Drop(2);
-      environment()->SetExpressionStackAt(0, after);
-      if (returns_original_input) environment()->SetExpressionStackAt(1, input);
-      ASSERT(has_side_effects);  // Stores always have side effects.
-      Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
-    }
+    Drop(returns_original_input ? 2 : 1);
+    return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
   }
 
-  Drop(returns_original_input ? 2 : 1);
-  return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
+  // Argument of the count operation is a property.
+  ASSERT(prop != NULL);
+  if (returns_original_input) Push(graph()->GetConstantUndefined());
+
+  CHECK_ALIVE(VisitForValue(prop->obj()));
+  HValue* object = Top();
+
+  HValue* key = NULL;
+  if ((!prop->IsStringLength() &&
+       !prop->IsFunctionPrototype() &&
+       !prop->key()->IsPropertyName()) ||
+      prop->IsStringAccess()) {
+    CHECK_ALIVE(VisitForValue(prop->key()));
+    key = Top();
+  }
+
+  CHECK_ALIVE(PushLoad(prop, object, key, expr->position()));
+
+  after = BuildIncrement(returns_original_input, expr);
+
+  if (returns_original_input) {
+    input = Pop();
+    // Drop object and key to push it again in the effect context below.
+    Drop(key == NULL ? 1 : 2);
+    environment()->SetExpressionStackAt(0, input);
+    CHECK_ALIVE(BuildStoreForEffect(
+        expr, prop, expr->id(), expr->AssignmentId(), object, key, after));
+    return ast_context()->ReturnValue(Pop());
+  }
+
+  environment()->SetExpressionStackAt(0, after);
+  return BuildStore(expr, prop, expr->id(), expr->AssignmentId());
 }
 
 
@@ -7987,12 +7941,15 @@
 }
 
 
-static bool IsLiteralCompareBool(HValue* left,
+static bool IsLiteralCompareBool(Isolate* isolate,
+                                 HValue* left,
                                  Token::Value op,
                                  HValue* right) {
   return op == Token::EQ_STRICT &&
-      ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) ||
-       (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean()));
+      ((left->IsConstant() &&
+          HConstant::cast(left)->handle(isolate)->IsBoolean()) ||
+       (right->IsConstant() &&
+           HConstant::cast(right)->handle(isolate)->IsBoolean()));
 }
 
 
@@ -8044,7 +8001,7 @@
   HValue* left = Pop();
   Token::Value op = expr->op();
 
-  if (IsLiteralCompareBool(left, op, right)) {
+  if (IsLiteralCompareBool(isolate(), left, op, right)) {
     HCompareObjectEqAndBranch* result =
         New<HCompareObjectEqAndBranch>(left, right);
     result->set_position(expr->position());
diff --git a/src/hydrogen.h b/src/hydrogen.h
index a12773f..395d1cd 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -2038,21 +2038,22 @@
                  BailoutId ast_id);
   void PushLoad(Property* property,
                 HValue* object,
+                HValue* key,
                 int position);
 
-  void BuildStoreInEffect(Expression* expression,
-                          Property* prop,
-                          BailoutId ast_id,
-                          BailoutId return_id,
-                          HValue* object,
-                          HValue* value);
+  void BuildStoreForEffect(Expression* expression,
+                           Property* prop,
+                           BailoutId ast_id,
+                           BailoutId return_id,
+                           HValue* object,
+                           HValue* key,
+                           HValue* value);
 
-  void BuildStoreNamed(Expression* expression,
-                       BailoutId id,
-                       BailoutId assignment_id,
-                       Property* prop,
-                       HValue* object,
-                       HValue* value);
+  void BuildStore(Expression* expression,
+                  Property* prop,
+                  BailoutId ast_id,
+                  BailoutId return_id,
+                  bool is_uninitialized = false);
 
   HInstruction* BuildStoreNamedField(HValue* object,
                                      Handle<String> name,
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 28b0f4a..84a4d23 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -177,11 +177,6 @@
 #undef __
 #define __ ACCESS_MASM(masm)
 
-// Keep around global pointers to these objects so that Valgrind won't complain.
-static size_t* medium_handlers = NULL;
-static size_t* small_handlers = NULL;
-
-
 enum Direction { FORWARD, BACKWARD };
 enum Alignment { MOVE_ALIGNED, MOVE_UNALIGNED };
 
@@ -253,12 +248,24 @@
 #define __ masm.
 
 
+class LabelConverter {
+ public:
+  explicit LabelConverter(byte* buffer) : buffer_(buffer) {}
+  int32_t address(Label* l) const {
+    return reinterpret_cast<int32_t>(buffer_) + l->pos();
+  }
+ private:
+  byte* buffer_;
+};
+
+
 OS::MemMoveFunction CreateMemMoveFunction() {
   size_t actual_size;
   // Allocate buffer in executable space.
   byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
   if (buffer == NULL) return NULL;
   MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
+  LabelConverter conv(buffer);
 
   // Generated code is put into a fixed, unmovable buffer, and not into
   // the V8 heap. We can't, and don't, refer to any relocatable addresses
@@ -452,7 +459,7 @@
       // Special handlers for 9 <= copy_size < 64. No assumptions about
       // alignment or move distance, so all reads must be unaligned and
       // must happen before any writes.
-      Label f9_16, f17_32, f33_48, f49_63;
+      Label medium_handlers, f9_16, f17_32, f33_48, f49_63;
 
       __ bind(&f9_16);
       __ movdbl(xmm0, Operand(src, 0));
@@ -488,11 +495,11 @@
       __ movdqu(Operand(dst, count, times_1, -0x10), xmm3);
       MemMoveEmitPopAndReturn(&masm);
 
-      medium_handlers = new size_t[4];
-      medium_handlers[0] = reinterpret_cast<intptr_t>(buffer) + f9_16.pos();
-      medium_handlers[1] = reinterpret_cast<intptr_t>(buffer) + f17_32.pos();
-      medium_handlers[2] = reinterpret_cast<intptr_t>(buffer) + f33_48.pos();
-      medium_handlers[3] = reinterpret_cast<intptr_t>(buffer) + f49_63.pos();
+      __ bind(&medium_handlers);
+      __ dd(conv.address(&f9_16));
+      __ dd(conv.address(&f17_32));
+      __ dd(conv.address(&f33_48));
+      __ dd(conv.address(&f49_63));
 
       __ bind(&medium_size);  // Entry point into this block.
       __ mov(eax, count);
@@ -505,13 +512,12 @@
         __ int3();
         __ bind(&ok);
       }
-      __ mov(eax, Operand(eax, times_4,
-                          reinterpret_cast<intptr_t>(medium_handlers)));
+      __ mov(eax, Operand(eax, times_4, conv.address(&medium_handlers)));
       __ jmp(eax);
     }
     {
       // Specialized copiers for copy_size <= 8 bytes.
-      Label f0, f1, f2, f3, f4, f5_8;
+      Label small_handlers, f0, f1, f2, f3, f4, f5_8;
       __ bind(&f0);
       MemMoveEmitPopAndReturn(&masm);
 
@@ -544,16 +550,16 @@
       __ mov(Operand(dst, count, times_1, -4), edx);
       MemMoveEmitPopAndReturn(&masm);
 
-      small_handlers = new size_t[9];
-      small_handlers[0] = reinterpret_cast<intptr_t>(buffer) + f0.pos();
-      small_handlers[1] = reinterpret_cast<intptr_t>(buffer) + f1.pos();
-      small_handlers[2] = reinterpret_cast<intptr_t>(buffer) + f2.pos();
-      small_handlers[3] = reinterpret_cast<intptr_t>(buffer) + f3.pos();
-      small_handlers[4] = reinterpret_cast<intptr_t>(buffer) + f4.pos();
-      small_handlers[5] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
-      small_handlers[6] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
-      small_handlers[7] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
-      small_handlers[8] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
+      __ bind(&small_handlers);
+      __ dd(conv.address(&f0));
+      __ dd(conv.address(&f1));
+      __ dd(conv.address(&f2));
+      __ dd(conv.address(&f3));
+      __ dd(conv.address(&f4));
+      __ dd(conv.address(&f5_8));
+      __ dd(conv.address(&f5_8));
+      __ dd(conv.address(&f5_8));
+      __ dd(conv.address(&f5_8));
 
       __ bind(&small_size);  // Entry point into this block.
       if (FLAG_debug_code) {
@@ -563,8 +569,7 @@
         __ int3();
         __ bind(&ok);
       }
-      __ mov(eax, Operand(count, times_4,
-                          reinterpret_cast<intptr_t>(small_handlers)));
+      __ mov(eax, Operand(count, times_4, conv.address(&small_handlers)));
       __ jmp(eax);
     }
   } else {
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 75525ed..32c9f00 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -713,7 +713,7 @@
 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
   HConstant* constant = chunk_->LookupConstant(op);
   ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
-  return constant->handle();
+  return constant->handle(isolate());
 }
 
 
@@ -876,7 +876,7 @@
     translation->StoreDoubleRegister(reg);
   } else if (op->IsConstantOperand()) {
     HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
-    int src_index = DefineDeoptimizationLiteral(constant->handle());
+    int src_index = DefineDeoptimizationLiteral(constant->handle(isolate()));
     translation->StoreLiteral(src_index);
   } else {
     UNREACHABLE();
@@ -936,7 +936,7 @@
   } else if (context->IsConstantOperand()) {
     HConstant* constant =
         chunk_->LookupConstant(LConstantOperand::cast(context));
-    __ LoadObject(esi, Handle<Object>::cast(constant->handle()));
+    __ LoadObject(esi, Handle<Object>::cast(constant->handle(isolate())));
   } else {
     UNREACHABLE();
   }
@@ -1943,7 +1943,7 @@
 
 void LCodeGen::DoConstantT(LConstantT* instr) {
   Register reg = ToRegister(instr->result());
-  Handle<Object> handle = instr->value();
+  Handle<Object> handle = instr->value(isolate());
   AllowDeferredHandleDereference smi_check;
   __ LoadObject(reg, handle);
 }
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 8b311b7..ab964af 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -1261,7 +1261,9 @@
   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
   DECLARE_HYDROGEN_ACCESSOR(Constant)
 
-  Handle<Object> value() const { return hydrogen()->handle(); }
+  Handle<Object> value(Isolate* isolate) const {
+    return hydrogen()->handle(isolate);
+  }
 };
 
 
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index e90810e..bcf64ce 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -542,6 +542,39 @@
 }
 
 
+// Generate call to api function.
+static void GenerateFastApiCall(MacroAssembler* masm,
+                                const CallOptimization& optimization,
+                                Register receiver,
+                                Register scratch,
+                                int argc,
+                                Register* values) {
+  ASSERT(optimization.is_simple_api_call());
+  ASSERT(!receiver.is(scratch));
+
+  const int stack_space = kFastApiCallArguments + argc + 1;
+  // Copy return value.
+  __ mov(scratch, Operand(esp, 0));
+  // Assign stack space for the call arguments.
+  __ sub(esp, Immediate(stack_space * kPointerSize));
+  // Move the return address on top of the stack.
+  __ mov(Operand(esp, 0), scratch);
+  // Write holder to stack frame.
+  __ mov(Operand(esp, 1 * kPointerSize), receiver);
+  // Write receiver to stack frame.
+  int index = stack_space;
+  __ mov(Operand(esp, index-- * kPointerSize), receiver);
+  // Write the arguments to stack frame.
+  for (int i = 0; i < argc; i++) {
+    ASSERT(!receiver.is(values[i]));
+    ASSERT(!scratch.is(values[i]));
+    __ mov(Operand(esp, index-- * kPointerSize), values[i]);
+  }
+
+  GenerateFastApiCall(masm, optimization, argc);
+}
+
+
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
   CallInterceptorCompiler(StubCompiler* stub_compiler,
@@ -1356,23 +1389,8 @@
 
 void BaseLoadStubCompiler::GenerateLoadCallback(
     const CallOptimization& call_optimization) {
-  ASSERT(call_optimization.is_simple_api_call());
-
-  // Copy return value.
-  __ mov(scratch3(), Operand(esp, 0));
-  // Assign stack space for the call arguments.
-  __ sub(esp, Immediate((kFastApiCallArguments + 1) * kPointerSize));
-  // Move the return address on top of the stack.
-  __ mov(Operand(esp, 0), scratch3());
-
-  int argc = 0;
-  int api_call_argc = argc + kFastApiCallArguments;
-  // Write holder to stack frame.
-  __ mov(Operand(esp, 1 * kPointerSize), receiver());
-  // Write receiver to stack frame.
-  __ mov(Operand(esp, (api_call_argc + 1) * kPointerSize), receiver());
-
-  GenerateFastApiCall(masm(), call_optimization, argc);
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch3(), 0, NULL);
 }
 
 
@@ -2901,6 +2919,24 @@
 }
 
 
+Handle<Code> StoreStubCompiler::CompileStoreCallback(
+    Handle<JSObject> object,
+    Handle<JSObject> holder,
+    Handle<Name> name,
+    const CallOptimization& call_optimization) {
+  Label success;
+  HandlerFrontend(object, receiver(), holder, name, &success);
+  __ bind(&success);
+
+  Register values[] = { value() };
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch1(), 1, values);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::CALLBACKS, name);
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/src/ic.cc b/src/ic.cc
index d88ab4a..9724c44 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1831,6 +1831,13 @@
         if (!setter->IsJSFunction()) break;
         if (holder->IsGlobalObject()) break;
         if (!holder->HasFastProperties()) break;
+        Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
+        CallOptimization call_optimization(function);
+        if (call_optimization.is_simple_api_call() &&
+            call_optimization.IsCompatibleReceiver(*receiver)) {
+          return isolate()->stub_cache()->ComputeStoreCallback(
+              name, receiver, holder, call_optimization, strict_mode);
+        }
         return isolate()->stub_cache()->ComputeStoreViaSetter(
             name, receiver, holder, Handle<JSFunction>::cast(setter),
             strict_mode);
diff --git a/src/isolate.cc b/src/isolate.cc
index 17762b2..74a77c6 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -343,35 +343,23 @@
 #ifdef DEBUG
 Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key;
 #endif  // DEBUG
-RecursiveMutex Isolate::process_wide_mutex_;
+Mutex Isolate::process_wide_mutex_;
 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
 Atomic32 Isolate::isolate_counter_ = 0;
 
-Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
-    ThreadId thread_id) {
-  ASSERT(!thread_id.Equals(ThreadId::Invalid()));
-  PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id);
-  {
-    LockGuard<RecursiveMutex> lock_guard(&process_wide_mutex_);
-    ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL);
-    thread_data_table_->Insert(per_thread);
-    ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
-  }
-  return per_thread;
-}
-
-
 Isolate::PerIsolateThreadData*
     Isolate::FindOrAllocatePerThreadDataForThisThread() {
   ThreadId thread_id = ThreadId::Current();
   PerIsolateThreadData* per_thread = NULL;
   {
-    LockGuard<RecursiveMutex> lock_guard(&process_wide_mutex_);
+    LockGuard<Mutex> lock_guard(&process_wide_mutex_);
     per_thread = thread_data_table_->Lookup(this, thread_id);
     if (per_thread == NULL) {
-      per_thread = AllocatePerIsolateThreadData(thread_id);
+      per_thread = new PerIsolateThreadData(this, thread_id);
+      thread_data_table_->Insert(per_thread);
     }
   }
+  ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
   return per_thread;
 }
 
@@ -386,7 +374,7 @@
     ThreadId thread_id) {
   PerIsolateThreadData* per_thread = NULL;
   {
-    LockGuard<RecursiveMutex> lock_guard(&process_wide_mutex_);
+    LockGuard<Mutex> lock_guard(&process_wide_mutex_);
     per_thread = thread_data_table_->Lookup(this, thread_id);
   }
   return per_thread;
@@ -394,7 +382,7 @@
 
 
 void Isolate::EnsureDefaultIsolate() {
-  LockGuard<RecursiveMutex> lock_guard(&process_wide_mutex_);
+  LockGuard<Mutex> lock_guard(&process_wide_mutex_);
   if (default_isolate_ == NULL) {
     isolate_key_ = Thread::CreateThreadLocalKey();
     thread_id_key_ = Thread::CreateThreadLocalKey();
@@ -1717,15 +1705,6 @@
 }
 
 
-void Isolate::ThreadDataTable::Remove(Isolate* isolate,
-                                      ThreadId thread_id) {
-  PerIsolateThreadData* data = Lookup(isolate, thread_id);
-  if (data != NULL) {
-    Remove(data);
-  }
-}
-
-
 void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
   PerIsolateThreadData* data = list_;
   while (data != NULL) {
@@ -1864,7 +1843,7 @@
 
   Deinit();
 
-  { LockGuard<RecursiveMutex> lock_guard(&process_wide_mutex_);
+  { LockGuard<Mutex> lock_guard(&process_wide_mutex_);
     thread_data_table_->RemoveAllThreads(this);
   }
 
diff --git a/src/isolate.h b/src/isolate.h
index 741c4c0..f0854e5 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1155,7 +1155,6 @@
 
     PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id);
     void Insert(PerIsolateThreadData* data);
-    void Remove(Isolate* isolate, ThreadId thread_id);
     void Remove(PerIsolateThreadData* data);
     void RemoveAllThreads(Isolate* isolate);
 
@@ -1190,7 +1189,7 @@
 
   // This mutex protects highest_thread_id_, thread_data_table_ and
   // default_isolate_.
-  static RecursiveMutex process_wide_mutex_;
+  static Mutex process_wide_mutex_;
 
   static Thread::LocalStorageKey per_isolate_thread_data_key_;
   static Thread::LocalStorageKey isolate_key_;
@@ -1206,10 +1205,6 @@
   static void SetIsolateThreadLocals(Isolate* isolate,
                                      PerIsolateThreadData* data);
 
-  // Allocate and insert PerIsolateThreadData into the ThreadDataTable
-  // (regardless of whether such data already exists).
-  PerIsolateThreadData* AllocatePerIsolateThreadData(ThreadId thread_id);
-
   // Find the PerThread for this particular (isolate, thread) combination.
   // If one does not yet exist, allocate a new one.
   PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
diff --git a/src/macros.py b/src/macros.py
index 38b9a08..d699c14 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -69,6 +69,7 @@
 const kUninitialized = -1;
 const kReadOnlyPrototypeBit = 3;
 const kRemovePrototypeBit = 4;  # For FunctionTemplateInfo, matches objects.h
+const kDoNotCacheBit = 5;  # For FunctionTemplateInfo, matches objects.h
 
 # Note: kDayZeroInJulianDay = ToJulianDay(1970, 0, 1).
 const kInvalidDate        = 'Invalid Date';
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 4342a06..cc75a61 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -917,6 +917,36 @@
                               kFastApiCallArguments + 1);
 }
 
+
+// Generate call to api function.
+static void GenerateFastApiCall(MacroAssembler* masm,
+                                const CallOptimization& optimization,
+                                Register receiver,
+                                Register scratch,
+                                int argc,
+                                Register* values) {
+  ASSERT(optimization.is_simple_api_call());
+  ASSERT(!receiver.is(scratch));
+
+  const int stack_space = kFastApiCallArguments + argc + 1;
+  // Assign stack space for the call arguments.
+  __ Subu(sp, sp, Operand(stack_space * kPointerSize));
+  // Write holder to stack frame.
+  __ sw(receiver, MemOperand(sp, 0));
+  // Write receiver to stack frame.
+  int index = stack_space - 1;
+  __ sw(receiver, MemOperand(sp, index * kPointerSize));
+  // Write the arguments to stack frame.
+  for (int i = 0; i < argc; i++) {
+    ASSERT(!receiver.is(values[i]));
+    ASSERT(!scratch.is(values[i]));
+    __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
+  }
+
+  GenerateFastApiDirectCall(masm, optimization, argc);
+}
+
+
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
   CallInterceptorCompiler(StubCompiler* stub_compiler,
@@ -1375,19 +1405,8 @@
 
 void BaseLoadStubCompiler::GenerateLoadCallback(
     const CallOptimization& call_optimization) {
-  ASSERT(call_optimization.is_simple_api_call());
-
-  // Assign stack space for the call arguments.
-  __ Subu(sp, sp, Operand((kFastApiCallArguments + 1) * kPointerSize));
-
-  int argc = 0;
-  int api_call_argc = argc + kFastApiCallArguments;
-  // Write holder to stack frame.
-  __ sw(receiver(), MemOperand(sp, 0));
-  // Write receiver to stack frame.
-  __ sw(receiver(), MemOperand(sp, api_call_argc * kPointerSize));
-
-  GenerateFastApiDirectCall(masm(), call_optimization, argc);
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch3(), 0, NULL);
 }
 
 
@@ -2814,6 +2833,24 @@
 }
 
 
+Handle<Code> StoreStubCompiler::CompileStoreCallback(
+    Handle<JSObject> object,
+    Handle<JSObject> holder,
+    Handle<Name> name,
+    const CallOptimization& call_optimization) {
+  Label success;
+  HandlerFrontend(object, receiver(), holder, name, &success);
+  __ bind(&success);
+
+  Register values[] = { value() };
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch3(), 1, values);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::CALLBACKS, name);
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index cd8426f..8a3cbec 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4569,6 +4569,8 @@
                kReadOnlyPrototypeBit)
 BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
                kRemovePrototypeBit)
+BOOL_ACCESSORS(FunctionTemplateInfo, flag, do_not_cache,
+               kDoNotCacheBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
                kIsExpressionBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
diff --git a/src/objects.h b/src/objects.h
index 30b1b85..97d1e5d 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -9878,6 +9878,7 @@
   DECL_BOOLEAN_ACCESSORS(needs_access_check)
   DECL_BOOLEAN_ACCESSORS(read_only_prototype)
   DECL_BOOLEAN_ACCESSORS(remove_prototype)
+  DECL_BOOLEAN_ACCESSORS(do_not_cache)
 
   static inline FunctionTemplateInfo* cast(Object* obj);
 
@@ -9913,6 +9914,7 @@
   static const int kNeedsAccessCheckBit  = 2;
   static const int kReadOnlyPrototypeBit = 3;
   static const int kRemovePrototypeBit   = 4;
+  static const int kDoNotCacheBit        = 5;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
 };
diff --git a/src/platform/elapsed-timer.h b/src/platform/elapsed-timer.h
index e5bcf23..773abbc 100644
--- a/src/platform/elapsed-timer.h
+++ b/src/platform/elapsed-timer.h
@@ -87,7 +87,7 @@
 
   // Returns the time elapsed since the previous start. This method may only
   // be called on a previously started timer.
-  MUST_USE_RESULT TimeDelta Elapsed() const {
+  TimeDelta Elapsed() const V8_WARN_UNUSED_RESULT {
     ASSERT(IsStarted());
     TimeDelta elapsed = Now() - start_ticks_;
     ASSERT(elapsed.InMicroseconds() >= 0);
@@ -97,13 +97,13 @@
   // Returns |true| if the specified |time_delta| has elapsed since the
   // previous start, or |false| if not. This method may only be called on
   // a previously started timer.
-  MUST_USE_RESULT bool HasExpired(TimeDelta time_delta) const {
+  bool HasExpired(TimeDelta time_delta) const V8_WARN_UNUSED_RESULT {
     ASSERT(IsStarted());
     return Elapsed() >= time_delta;
   }
 
  private:
-  MUST_USE_RESULT V8_INLINE(static TimeTicks Now()) {
+  V8_INLINE(static TimeTicks Now()) V8_WARN_UNUSED_RESULT {
     TimeTicks now = TimeTicks::HighResNow();
     ASSERT(!now.IsNull());
     return now;
diff --git a/src/runtime.cc b/src/runtime.cc
index 9e44b58..56558e0 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -12484,7 +12484,7 @@
 //          of frames to step down.
 RUNTIME_FUNCTION(MaybeObject*, Runtime_PrepareStep) {
   HandleScope scope(isolate);
-  ASSERT(args.length() == 3);
+  ASSERT(args.length() == 4);
   // Check arguments.
   Object* check;
   { MaybeObject* maybe_check = Runtime_CheckExecutionState(
@@ -12495,6 +12495,15 @@
     return isolate->Throw(isolate->heap()->illegal_argument_string());
   }
 
+  CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
+
+  StackFrame::Id frame_id;
+  if (wrapped_frame_id == 0) {
+    frame_id = StackFrame::NO_ID;
+  } else {
+    frame_id = UnwrapFrameId(wrapped_frame_id);
+  }
+
   // Get the step action and check validity.
   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
   if (step_action != StepIn &&
@@ -12505,6 +12514,11 @@
     return isolate->Throw(isolate->heap()->illegal_argument_string());
   }
 
+  if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
+      step_action != StepMin && step_action != StepOut) {
+    return isolate->ThrowIllegalOperation();
+  }
+
   // Get the number of steps.
   int step_count = NumberToInt32(args[2]);
   if (step_count < 1) {
@@ -12516,7 +12530,8 @@
 
   // Prepare step.
   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
-                                step_count);
+                                step_count,
+                                frame_id);
   return isolate->heap()->undefined_value();
 }
 
diff --git a/src/runtime.h b/src/runtime.h
index 9054fc7..4c76098 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -504,7 +504,7 @@
   F(ClearBreakPoint, 1, 1) \
   F(ChangeBreakOnException, 2, 1) \
   F(IsBreakOnException, 1, 1) \
-  F(PrepareStep, 3, 1) \
+  F(PrepareStep, 4, 1) \
   F(ClearStepping, 0, 1) \
   F(DebugEvaluate, 6, 1) \
   F(DebugEvaluateGlobal, 4, 1) \
diff --git a/src/store-buffer.cc b/src/store-buffer.cc
index 9705b60..30b7f25 100644
--- a/src/store-buffer.cc
+++ b/src/store-buffer.cc
@@ -170,7 +170,10 @@
   PointerChunkIterator it(heap_);
   MemoryChunk* chunk;
   while ((chunk = it.next()) != NULL) {
-    if (chunk->scan_on_scavenge()) page_has_scan_on_scavenge_flag = true;
+    if (chunk->scan_on_scavenge()) {
+      page_has_scan_on_scavenge_flag = true;
+      break;
+    }
   }
 
   if (page_has_scan_on_scavenge_flag) {
@@ -279,7 +282,10 @@
   MemoryChunk* chunk;
   bool page_has_scan_on_scavenge_flag = false;
   while ((chunk = it.next()) != NULL) {
-    if (chunk->scan_on_scavenge()) page_has_scan_on_scavenge_flag = true;
+    if (chunk->scan_on_scavenge()) {
+      page_has_scan_on_scavenge_flag = true;
+      break;
+    }
   }
 
   if (page_has_scan_on_scavenge_flag) {
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index b312b1e..f83a7d2 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -631,6 +631,24 @@
 }
 
 
+Handle<Code> StubCache::ComputeStoreCallback(
+    Handle<Name> name,
+    Handle<JSObject> receiver,
+    Handle<JSObject> holder,
+    const CallOptimization& call_optimization,
+    StrictModeFlag strict_mode) {
+  Handle<Code> stub = FindStoreHandler(
+      name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode);
+  if (!stub.is_null()) return stub;
+
+  StoreStubCompiler compiler(isolate_, strict_mode);
+  Handle<Code> handler = compiler.CompileStoreCallback(
+      receiver, holder, name, call_optimization);
+  JSObject::UpdateMapCodeCache(receiver, name, handler);
+  return handler;
+}
+
+
 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name,
                                               Handle<JSObject> receiver,
                                               Handle<JSObject> holder,
diff --git a/src/stub-cache.h b/src/stub-cache.h
index a267100..12afdd3 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -222,6 +222,12 @@
                                     Handle<ExecutableAccessorInfo> callback,
                                     StrictModeFlag strict_mode);
 
+  Handle<Code> ComputeStoreCallback(Handle<Name> name,
+                                    Handle<JSObject> object,
+                                    Handle<JSObject> holder,
+                                    const CallOptimization& call_optimation,
+                                    StrictModeFlag strict_mode);
+
   Handle<Code> ComputeStoreViaSetter(Handle<Name> name,
                                      Handle<JSObject> object,
                                      Handle<JSObject> holder,
@@ -960,6 +966,11 @@
                                     Handle<Name> name,
                                     Handle<ExecutableAccessorInfo> callback);
 
+  Handle<Code> CompileStoreCallback(Handle<JSObject> object,
+                                    Handle<JSObject> holder,
+                                    Handle<Name> name,
+                                    const CallOptimization& call_optimization);
+
   static void GenerateStoreViaSetter(MacroAssembler* masm,
                                      Handle<JSFunction> setter);
 
diff --git a/src/v8.cc b/src/v8.cc
index 9dea902..d9ce840 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -50,8 +50,6 @@
 
 V8_DECLARE_ONCE(init_once);
 
-bool V8::has_been_set_up_ = false;
-bool V8::has_been_disposed_ = false;
 List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
 v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL;
 
@@ -81,9 +79,6 @@
   if (isolate->IsDead()) return false;
   if (isolate->IsInitialized()) return true;
 
-  has_been_set_up_ = true;
-  has_been_disposed_ = false;
-
   return isolate->Init(des);
 }
 
@@ -91,8 +86,7 @@
 void V8::TearDown() {
   Isolate* isolate = Isolate::Current();
   ASSERT(isolate->IsDefaultIsolate());
-
-  if (!has_been_set_up_ || has_been_disposed_) return;
+  if (!isolate->IsInitialized()) return;
 
   // The isolate has to be torn down before clearing the LOperand
   // caches so that the optimizing compiler thread (if running)
@@ -106,8 +100,6 @@
   RegisteredExtension::UnregisterAll();
   Isolate::GlobalTearDown();
 
-  has_been_disposed_ = true;
-
   delete call_completed_callbacks_;
   call_completed_callbacks_ = NULL;
 
diff --git a/src/v8.h b/src/v8.h
index 69f4df9..23277b3 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -122,11 +122,6 @@
   static void InitializeOncePerProcessImpl();
   static void InitializeOncePerProcess();
 
-  // True if V8 has ever been run
-  static bool has_been_set_up_;
-  // True if engine has been shut down
-  // (reset if engine is restarted)
-  static bool has_been_disposed_;
   // List of callbacks when a Call completes.
   static List<CallCompletedCallback>* call_completed_callbacks_;
   // Allocator for external array buffers.
diff --git a/src/version.cc b/src/version.cc
index ec28896..9b59e2a 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     21
-#define BUILD_NUMBER      11
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      12
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index fd9bf18..f1430d7 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -450,7 +450,7 @@
 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
   HConstant* constant = chunk_->LookupConstant(op);
   ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
-  return constant->handle();
+  return constant->handle(isolate());
 }
 
 
@@ -582,7 +582,7 @@
     translation->StoreDoubleRegister(reg);
   } else if (op->IsConstantOperand()) {
     HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
-    int src_index = DefineDeoptimizationLiteral(constant->handle());
+    int src_index = DefineDeoptimizationLiteral(constant->handle(isolate()));
     translation->StoreLiteral(src_index);
   } else {
     UNREACHABLE();
@@ -1425,7 +1425,7 @@
         break;
       case Token::BIT_XOR:
         if (right_operand == int32_t(~0)) {
-          __ not_(ToRegister(left));
+          __ notl(ToRegister(left));
         } else {
           __ xorl(ToRegister(left), Immediate(right_operand));
         }
@@ -1598,7 +1598,7 @@
 
 
 void LCodeGen::DoConstantT(LConstantT* instr) {
-  Handle<Object> value = instr->value();
+  Handle<Object> value = instr->value(isolate());
   AllowDeferredHandleDereference smi_check;
   __ LoadObject(ToRegister(instr->result()), value);
 }
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index e95713d..ff0c61b 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -1221,7 +1221,9 @@
   DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
   DECLARE_HYDROGEN_ACCESSOR(Constant)
 
-  Handle<Object> value() const { return hydrogen()->handle(); }
+  Handle<Object> value(Isolate* isolate) const {
+    return hydrogen()->handle(isolate);
+  }
 };
 
 
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index f6cc449..31f60be 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -528,6 +528,39 @@
 }
 
 
+// Generate call to api function.
+static void GenerateFastApiCall(MacroAssembler* masm,
+                                const CallOptimization& optimization,
+                                Register receiver,
+                                Register scratch,
+                                int argc,
+                                Register* values) {
+  ASSERT(optimization.is_simple_api_call());
+  ASSERT(!receiver.is(scratch));
+
+  const int stack_space = kFastApiCallArguments + argc + 1;
+  // Copy return value.
+  __ movq(scratch, Operand(rsp, 0));
+  // Assign stack space for the call arguments.
+  __ subq(rsp, Immediate(stack_space * kPointerSize));
+  // Move the return address on top of the stack.
+  __ movq(Operand(rsp, 0), scratch);
+  // Write holder to stack frame.
+  __ movq(Operand(rsp, 1 * kPointerSize), receiver);
+  // Write receiver to stack frame.
+  int index = stack_space;
+  __ movq(Operand(rsp, index-- * kPointerSize), receiver);
+  // Write the arguments to stack frame.
+  for (int i = 0; i < argc; i++) {
+    ASSERT(!receiver.is(values[i]));
+    ASSERT(!scratch.is(values[i]));
+    __ movq(Operand(rsp, index-- * kPointerSize), values[i]);
+  }
+
+  GenerateFastApiCall(masm, optimization, argc);
+}
+
+
 class CallInterceptorCompiler BASE_EMBEDDED {
  public:
   CallInterceptorCompiler(StubCompiler* stub_compiler,
@@ -1277,24 +1310,8 @@
 
 void BaseLoadStubCompiler::GenerateLoadCallback(
     const CallOptimization& call_optimization) {
-  ASSERT(call_optimization.is_simple_api_call());
-
-  // Copy return value.
-  __ movq(scratch3(), Operand(rsp, 0));
-  // Assign stack space for the call arguments.
-  __ subq(rsp, Immediate((kFastApiCallArguments + 1) * kPointerSize));
-  // Move the return address on top of the stack.
-  __ movq(Operand(rsp, 0), scratch3());
-
-  int argc = 0;
-  int api_call_argc = argc + kFastApiCallArguments;
-  StackArgumentsAccessor args(rsp, api_call_argc);
-  // Write holder to stack frame.
-  __ movq(args.GetArgumentOperand(api_call_argc), receiver());
-  // Write receiver to stack frame.
-  __ movq(args.GetArgumentOperand(api_call_argc - 6), receiver());
-
-  GenerateFastApiCall(masm(), call_optimization, argc);
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch3(), 0, NULL);
 }
 
 
@@ -2795,6 +2812,24 @@
 }
 
 
+Handle<Code> StoreStubCompiler::CompileStoreCallback(
+    Handle<JSObject> object,
+    Handle<JSObject> holder,
+    Handle<Name> name,
+    const CallOptimization& call_optimization) {
+  Label success;
+  HandlerFrontend(object, receiver(), holder, name, &success);
+  __ bind(&success);
+
+  Register values[] = { value() };
+  GenerateFastApiCall(
+      masm(), call_optimization, receiver(), scratch3(), 1, values);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::CALLBACKS, name);
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index e09de7d..a8dde16 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -34,6 +34,10 @@
 # BUG(382): Weird test. Can't guarantee that it never times out.
 test-api/ApplyInterruption: PASS || TIMEOUT
 
+# TODO(mstarzinger): Fail gracefully on multiple V8::Dispose calls.
+test-api/InitializeAndDisposeOnce: SKIP
+test-api/InitializeAndDisposeMultiple: SKIP
+
 # These tests always fail.  They are here to test test.py.  If
 # they don't fail then test.py has failed.
 test-serialize/TestThatAlwaysFails: FAIL
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index e190b71..aaac486 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -166,6 +166,24 @@
 }
 
 
+// Tests that call v8::V8::Dispose() cannot be threaded.
+TEST(InitializeAndDisposeOnce) {
+  CHECK(v8::V8::Initialize());
+  CHECK(v8::V8::Dispose());
+}
+
+
+// Tests that call v8::V8::Dispose() cannot be threaded.
+TEST(InitializeAndDisposeMultiple) {
+  for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
+  for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
+  for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
+  // TODO(mstarzinger): This should fail gracefully instead of asserting.
+  // for (int i = 0; i < 3; ++i) CHECK(v8::V8::Initialize());
+  for (int i = 0; i < 3; ++i) CHECK(v8::V8::Dispose());
+}
+
+
 THREADED_TEST(Handles) {
   v8::HandleScope scope(v8::Isolate::GetCurrent());
   Local<Context> local_env;
@@ -206,78 +224,98 @@
 }
 
 
+static void TestSignature(const char* loop_js, Local<Value> receiver) {
+  i::ScopedVector<char> source(200);
+  i::OS::SNPrintF(source,
+                  "for (var i = 0; i < 10; i++) {"
+                  "  %s"
+                  "}",
+                  loop_js);
+  signature_callback_count = 0;
+  signature_expected_receiver = receiver;
+  bool expected_to_throw = receiver.IsEmpty();
+  v8::TryCatch try_catch;
+  CompileRun(source.start());
+  CHECK_EQ(expected_to_throw, try_catch.HasCaught());
+  if (!expected_to_throw) {
+    CHECK_EQ(10, signature_callback_count);
+  } else {
+    CHECK_EQ(v8_str("TypeError: Illegal invocation"),
+             try_catch.Exception()->ToString());
+  }
+}
+
+
 THREADED_TEST(ReceiverSignature) {
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
+  // Setup templates.
   v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New();
   v8::Handle<v8::Signature> sig = v8::Signature::New(fun);
-  fun->PrototypeTemplate()->Set(
-      v8_str("m"),
-      v8::FunctionTemplate::New(IncrementingSignatureCallback,
-                                v8::Handle<Value>(),
-                                sig));
-  fun->PrototypeTemplate()->SetAccessorProperty(
-      v8_str("n"),
-      v8::FunctionTemplate::New(IncrementingSignatureCallback,
-                                v8::Handle<Value>(),
-                                sig));
-  env->Global()->Set(v8_str("Fun"), fun->GetFunction());
-  Local<Value> fun_instance = fun->InstanceTemplate()->NewInstance();
-  env->Global()->Set(v8_str("fun_instance"), fun_instance);
-  signature_callback_count = 0;
-  int expected_count = 0;
-  signature_expected_receiver = fun_instance;
-  CompileRun(
-      "var o = fun_instance;"
-      "var key_n = 'n';"
-      "for (var i = 0; i < 10; i++) o.m();"
-      "for (var i = 0; i < 10; i++) o.n;"
-      "for (var i = 0; i < 10; i++) o[key_n];");
-  expected_count += 30;
-  CHECK_EQ(expected_count, signature_callback_count);
+  v8::Handle<v8::FunctionTemplate> callback_sig =
+      v8::FunctionTemplate::New(
+          IncrementingSignatureCallback, Local<Value>(), sig);
+  v8::Handle<v8::FunctionTemplate> callback =
+      v8::FunctionTemplate::New(IncrementingSignatureCallback);
   v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New();
   sub_fun->Inherit(fun);
-  fun_instance = sub_fun->InstanceTemplate()->NewInstance();
-  env->Global()->Set(v8_str("fun_instance"), fun_instance);
-  signature_expected_receiver = fun_instance;
-  CompileRun(
-      "var o = fun_instance;"
-      "var key_n = 'n';"
-      "for (var i = 0; i < 10; i++) o.m();"
-      "for (var i = 0; i < 10; i++) o.n;"
-      "for (var i = 0; i < 10; i++) o[key_n];");
-  expected_count += 30;
-  CHECK_EQ(expected_count, signature_callback_count);
-  v8::TryCatch try_catch;
-  CompileRun(
-      "var o = { };"
-      "o.m = Fun.prototype.m;"
-      "o.m();");
-  CHECK_EQ(expected_count, signature_callback_count);
-  CHECK(try_catch.HasCaught());
-  CompileRun(
-      "var o = { };"
-      "o.n = Fun.prototype.n;"
-      "o.n;");
-  CHECK_EQ(expected_count, signature_callback_count);
-  CHECK(try_catch.HasCaught());
-  try_catch.Reset();
   v8::Handle<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New();
-  sub_fun->Inherit(fun);
+  // Install properties.
+  v8::Handle<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate();
+  fun_proto->Set(v8_str("prop_sig"), callback_sig);
+  fun_proto->Set(v8_str("prop"), callback);
+  fun_proto->SetAccessorProperty(
+      v8_str("accessor_sig"), callback_sig, callback_sig);
+  fun_proto->SetAccessorProperty(v8_str("accessor"), callback, callback);
+  // Instantiate templates.
+  Local<Value> fun_instance = fun->InstanceTemplate()->NewInstance();
+  Local<Value> sub_fun_instance = sub_fun->InstanceTemplate()->NewInstance();
+  // Setup global variables.
+  env->Global()->Set(v8_str("Fun"), fun->GetFunction());
   env->Global()->Set(v8_str("UnrelFun"), unrel_fun->GetFunction());
+  env->Global()->Set(v8_str("fun_instance"), fun_instance);
+  env->Global()->Set(v8_str("sub_fun_instance"), sub_fun_instance);
   CompileRun(
-      "var o = new UnrelFun();"
-      "o.m = Fun.prototype.m;"
-      "o.m();");
-  CHECK_EQ(expected_count, signature_callback_count);
-  CHECK(try_catch.HasCaught());
-  try_catch.Reset();
-  CompileRun(
-      "var o = new UnrelFun();"
-      "o.n = Fun.prototype.n;"
-      "o.n;");
-  CHECK_EQ(expected_count, signature_callback_count);
-  CHECK(try_catch.HasCaught());
+      "var accessor_sig_key = 'accessor_sig';"
+      "var accessor_key = 'accessor';"
+      "var prop_sig_key = 'prop_sig';"
+      "var prop_key = 'prop';"
+      ""
+      "function copy_props(obj) {"
+      "  var keys = [accessor_sig_key, accessor_key, prop_sig_key, prop_key];"
+      "  var source = Fun.prototype;"
+      "  for (var i in keys) {"
+      "    var key = keys[i];"
+      "    var desc = Object.getOwnPropertyDescriptor(source, key);"
+      "    Object.defineProperty(obj, key, desc);"
+      "  }"
+      "}"
+      ""
+      "var obj = {};"
+      "copy_props(obj);"
+      "var unrel = new UnrelFun();"
+      "copy_props(unrel);");
+  // Test with and without ICs
+  const char* test_objects[] = {
+      "fun_instance", "sub_fun_instance", "obj", "unrel" };
+  unsigned bad_signature_start_offset = 2;
+  for (unsigned i = 0; i < ARRAY_SIZE(test_objects); i++) {
+    i::ScopedVector<char> source(200);
+    i::OS::SNPrintF(
+        source, "var test_object = %s; test_object", test_objects[i]);
+    Local<Value> test_object = CompileRun(source.start());
+    TestSignature("test_object.prop();", test_object);
+    TestSignature("test_object.accessor;", test_object);
+    TestSignature("test_object[accessor_key];", test_object);
+    TestSignature("test_object.accessor = 1;", test_object);
+    TestSignature("test_object[accessor_key] = 1;", test_object);
+    if (i >= bad_signature_start_offset) test_object = Local<Value>();
+    TestSignature("test_object.prop_sig();", test_object);
+    TestSignature("test_object.accessor_sig;", test_object);
+    TestSignature("test_object[accessor_sig_key];", test_object);
+    TestSignature("test_object.accessor_sig = 1;", test_object);
+    TestSignature("test_object[accessor_sig_key] = 1;", test_object);
+  }
 }
 
 
@@ -3208,13 +3246,8 @@
   v8::HandleScope scope(isolate);
   v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
   v8::Persistent<String> global_string(isolate, local);
-#ifdef V8_USE_UNSAFE_HANDLES
-  v8::Persistent<Value> global_value =
-      v8::Persistent<Value>::Cast(global_string);
-#else
   v8::Persistent<Value>& global_value =
       v8::Persistent<Value>::Cast(global_string);
-#endif
   CHECK(v8::Local<v8::Value>::New(isolate, global_value)->IsString());
   CHECK(global_string == v8::Persistent<String>::Cast(global_value));
   global_string.Dispose();
@@ -12632,6 +12665,75 @@
   }
 }
 
+template<class T>
+struct CopyablePersistentTraits {
+  typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent;
+  static const bool kResetInDestructor = true;
+  template<class S, class M>
+  V8_INLINE(static void Copy(const Persistent<S, M>& source,
+                             CopyablePersistent* dest)) {
+    // do nothing, just allow copy
+  }
+};
+
+
+TEST(CopyablePersistent) {
+  LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
+  i::GlobalHandles* globals =
+      reinterpret_cast<i::Isolate*>(isolate)->global_handles();
+  int initial_handles = globals->global_handles_count();
+  {
+    v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> > handle1;
+    {
+      v8::HandleScope scope(isolate);
+      handle1.Reset(isolate, v8::Object::New());
+    }
+    CHECK_EQ(initial_handles + 1, globals->global_handles_count());
+    v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> > handle2;
+    handle2 = handle1;
+    CHECK(handle1 == handle2);
+    CHECK_EQ(initial_handles + 2, globals->global_handles_count());
+    v8::Persistent<v8::Object, CopyablePersistentTraits<v8::Object> >
+    handle3(handle2);
+    CHECK(handle1 == handle3);
+    CHECK_EQ(initial_handles + 3, globals->global_handles_count());
+  }
+  // Verify autodispose
+//  CHECK_EQ(initial_handles, globals->global_handles_count());
+}
+
+
+static void WeakApiCallback(
+    const v8::WeakCallbackData<v8::Object, Persistent<v8::Object> >& data) {
+  Local<Value> value = data.GetValue()->Get(v8_str("key"));
+  CHECK_EQ(231, static_cast<int32_t>(Local<v8::Integer>::Cast(value)->Value()));
+  data.GetParameter()->Reset();
+  delete data.GetParameter();
+}
+
+
+TEST(WeakCallbackApi) {
+  LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
+  i::GlobalHandles* globals =
+      reinterpret_cast<i::Isolate*>(isolate)->global_handles();
+  int initial_handles = globals->global_handles_count();
+  {
+    v8::HandleScope scope(isolate);
+    v8::Local<v8::Object> obj = v8::Object::New();
+    obj->Set(v8_str("key"), v8::Integer::New(231, isolate));
+    v8::Persistent<v8::Object>* handle =
+        new v8::Persistent<v8::Object>(isolate, obj);
+    handle->SetWeak<v8::Object, v8::Persistent<v8::Object> >(handle,
+                                                             WeakApiCallback);
+  }
+  reinterpret_cast<i::Isolate*>(isolate)->heap()->
+      CollectAllGarbage(i::Heap::kNoGCFlags);
+  // Verify disposed.
+  CHECK_EQ(initial_handles, globals->global_handles_count());
+}
+
 
 v8::Persistent<v8::Object> some_object;
 v8::Persistent<v8::Object> bad_handle;
@@ -20453,4 +20555,34 @@
   ExpectInt32("obj.interceptor_age", 103);
 }
 
+
 #endif  // V8_OS_POSIX
+
+
+static Local<Value> function_new_expected_env;
+static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
+  CHECK_EQ(function_new_expected_env, info.Data());
+  info.GetReturnValue().Set(17);
+}
+
+
+THREADED_TEST(FunctionNew) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  Local<Object> data = v8::Object::New();
+  function_new_expected_env = data;
+  Local<Function> func = Function::New(isolate, FunctionNewCallback, data);
+  env->Global()->Set(v8_str("func"), func);
+  Local<Value> result = CompileRun("func();");
+  CHECK_EQ(v8::Integer::New(17, isolate), result);
+  // Verify function not cached
+  int serial_number =
+      i::Smi::cast(v8::Utils::OpenHandle(*func)
+          ->shared()->get_api_func_data()->serial_number())->value();
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  i::Object* elm = i_isolate->native_context()->function_cache()
+      ->GetElementNoExceptionThrown(i_isolate, serial_number);
+  CHECK(elm->IsNull());
+}
+
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 6bd6fee..2540a3d 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -37,6 +37,7 @@
 #include "compilation-cache.h"
 #include "debug.h"
 #include "deoptimizer.h"
+#include "frames.h"
 #include "platform.h"
 #include "platform/condition-variable.h"
 #include "platform/socket.h"
@@ -60,6 +61,7 @@
 using ::v8::internal::Debugger;
 using ::v8::internal::CommandMessage;
 using ::v8::internal::CommandMessageQueue;
+using ::v8::internal::StackFrame;
 using ::v8::internal::StepAction;
 using ::v8::internal::StepIn;  // From StepAction enum
 using ::v8::internal::StepNext;  // From StepAction enum
@@ -390,7 +392,7 @@
 // Prepare to step to next break location.
 static void PrepareStep(StepAction step_action) {
   v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
-  debug->PrepareStep(step_action, 1);
+  debug->PrepareStep(step_action, 1, StackFrame::NO_ID);
 }
 
 
diff --git a/test/cctest/test-thread-termination.cc b/test/cctest/test-thread-termination.cc
index 4c08539..619bce7 100644
--- a/test/cctest/test-thread-termination.cc
+++ b/test/cctest/test-thread-termination.cc
@@ -192,73 +192,6 @@
 }
 
 
-class LoopingThread : public v8::internal::Thread {
- public:
-  LoopingThread() : Thread("LoopingThread") { }
-  void Run() {
-    v8::Locker locker(CcTest::default_isolate());
-    v8::HandleScope scope(CcTest::default_isolate());
-    v8_thread_id_ = v8::V8::GetCurrentThreadId();
-    v8::Handle<v8::ObjectTemplate> global =
-        CreateGlobalTemplate(Signal, DoLoop);
-    v8::Handle<v8::Context> context =
-        v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
-    v8::Context::Scope context_scope(context);
-    CHECK(!v8::V8::IsExecutionTerminating());
-    // Run a loop that will be infinite if thread termination does not work.
-    v8::Handle<v8::String> source =
-        v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
-    v8::Script::Compile(source)->Run();
-  }
-
-  int GetV8ThreadId() { return v8_thread_id_; }
-
- private:
-  int v8_thread_id_;
-};
-
-
-// Test that multiple threads using default isolate can be terminated
-// from another thread when using Lockers and preemption.
-TEST(TerminateMultipleV8ThreadsDefaultIsolate) {
-  {
-    v8::Locker locker(CcTest::default_isolate());
-    v8::V8::Initialize();
-    v8::Locker::StartPreemption(1);
-    semaphore = new v8::internal::Semaphore(0);
-  }
-  const int kThreads = 2;
-  i::List<LoopingThread*> threads(kThreads);
-  for (int i = 0; i < kThreads; i++) {
-    threads.Add(new LoopingThread());
-  }
-  for (int i = 0; i < kThreads; i++) {
-    threads[i]->Start();
-  }
-  // Wait until all threads have signaled the semaphore.
-  for (int i = 0; i < kThreads; i++) {
-    semaphore->Wait();
-  }
-  {
-    v8::Locker locker(CcTest::default_isolate());
-    for (int i = 0; i < kThreads; i++) {
-      v8::V8::TerminateExecution(threads[i]->GetV8ThreadId());
-    }
-  }
-  for (int i = 0; i < kThreads; i++) {
-    threads[i]->Join();
-    delete threads[i];
-  }
-  {
-    v8::Locker locker(CcTest::default_isolate());
-    v8::Locker::StopPreemption();
-  }
-
-  delete semaphore;
-  semaphore = NULL;
-}
-
-
 int call_count = 0;
 
 
diff --git a/test/mjsunit/compiler/escape-analysis.js b/test/mjsunit/compiler/escape-analysis.js
index 7452e3b..74e638a 100644
--- a/test/mjsunit/compiler/escape-analysis.js
+++ b/test/mjsunit/compiler/escape-analysis.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax --use-escape-analysis
+// Flags: --allow-natives-syntax --use-escape-analysis --expose-gc
 
 
 // Test stores on a join path.
@@ -241,3 +241,33 @@
   test(osr2);
   test(osr3);
 })();
+
+
+// Test out-of-bounds access on captured objects.
+(function testOOB() {
+  function cons1() {
+    this.x = 1;
+    this.y = 2;
+    this.z = 3;
+  }
+  function cons2() {
+    this.a = 7;
+  }
+  function oob(constructor, branch) {
+    var o = new constructor();
+    if (branch) {
+      return o.a;
+    } else {
+      return o.z;
+    }
+  }
+  assertEquals(3, oob(cons1, false));
+  assertEquals(3, oob(cons1, false));
+  assertEquals(7, oob(cons2, true));
+  assertEquals(7, oob(cons2, true));
+  gc();  // Clears type feedback of constructor call.
+  assertEquals(7, oob(cons2, true));
+  assertEquals(7, oob(cons2, true));
+  %OptimizeFunctionOnNextCall(oob);
+  assertEquals(7, oob(cons2, true));
+})();
diff --git a/test/mjsunit/debug-step-4-in-frame.js b/test/mjsunit/debug-step-4-in-frame.js
new file mode 100644
index 0000000..65ac490
--- /dev/null
+++ b/test/mjsunit/debug-step-4-in-frame.js
@@ -0,0 +1,132 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+// Tests how debugger can step over not necessarily in the top frame.
+
+// Simple 3 functions, that protocol their execution state in global
+// variable state.
+var state;
+
+function f() {
+  var a = 1978;
+  for (state[2] = 0; state[2] < 5; state[2]++) {
+    void String(a);
+  }
+}
+function g() {
+  for (state[1] = 0; state[1] < 5; state[1]++) {
+    f();
+  }
+}
+function h() {
+  state = [-1, -1, -1];
+  for (state[0] = 0; state[0] < 5; state[0]++) {
+    g();
+  }
+}
+
+function TestCase(frame_index, step_count, expected_final_state) {
+  print("Test case, parameters " + frame_index + "/" + step_count);
+
+  var listener_exception = null;
+  var state_snapshot;
+  var listener_state;
+  var bp;
+
+  function listener(event, exec_state, event_data, data) {
+    print("Here ("+event+"/"+listener_state+"): " +
+        exec_state.frame(0).sourceLineText());
+    try {
+      if (event == Debug.DebugEvent.Break) {
+        if (listener_state == 0) {
+          Debug.clearBreakPoint(bp);
+          var context_frame;
+          if (frame_index !== undefined) {
+            context_frame = exec_state.frame(frame_index);
+          }
+          exec_state.prepareStep(Debug.StepAction.StepNext,
+              step_count, context_frame);
+          listener_state = 1;
+        } else if (listener_state == 1) {
+          state_snapshot = String(state);
+          print("State: " + state_snapshot);
+          Debug.setListener(null);
+          listener_state = 2;
+        }
+      }
+    } catch (e) {
+      listener_exception = e;
+    }
+  }
+
+
+  // Add the debug event listener.
+  listener_state = 0;
+  Debug.setListener(listener);
+  bp = Debug.setBreakPoint(f, 1);
+
+  h();
+  Debug.setListener(null);
+  if (listener_exception !== null) {
+    print("Exception caught: " + listener_exception);
+    assertUnreachable();
+  }
+
+  assertEquals(expected_final_state, state_snapshot);
+}
+
+
+// Warm-up -- make sure all is compiled and ready for breakpoint.
+h();
+
+
+// Stepping in the default (top) frame.
+TestCase(undefined, 0, "0,0,-1");
+TestCase(undefined, 1, "0,0,-1");
+TestCase(undefined, 2, "0,0,0");
+TestCase(undefined, 5, "0,0,1");
+TestCase(undefined, 8, "0,0,3");
+
+// Stepping in the frame #0 (should be exactly the same as above).
+TestCase(0, 0, "0,0,-1");
+TestCase(0, 1, "0,0,-1");
+TestCase(0, 2, "0,0,0");
+TestCase(0, 5, "0,0,1");
+TestCase(0, 8, "0,0,3");
+
+// Stepping in the frame #1.
+TestCase(1, 0, "0,0,5");
+TestCase(1, 3, "0,1,5");
+TestCase(1, 8, "0,4,5");
+
+// Stepping in the frame #2.
+TestCase(2, 3, "1,5,5");
+TestCase(2, 8, "4,5,5");
diff --git a/test/mjsunit/lithium/MulI.js b/test/mjsunit/lithium/MulI.js
new file mode 100644
index 0000000..68588bd
--- /dev/null
+++ b/test/mjsunit/lithium/MulI.js
@@ -0,0 +1,70 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --no-use-osr
+
+function foo_smi(a, b) {
+  var result = a * b;
+  result += a * 35;
+  result += a * -1;
+  result += a * 1;
+  result += a * 0;
+  return result * a;
+}
+
+function foo_int(a, b) {
+  var result = a * b;
+  result += a * 35;
+  result += a * -1;
+  result += a * 1;
+  result += a * 0;
+  return result * a;
+}
+
+foo_smi(10, 5);
+var r1 = foo_smi(10, 5);
+%OptimizeFunctionOnNextCall(foo_smi);
+var r2 = foo_smi(10, 5);
+
+assertEquals(r1, r2);
+
+foo_int(10, 21474800);
+var r3 = foo_int(10, 21474800);
+%OptimizeFunctionOnNextCall(foo_int);
+var r4 = foo_int(10, 21474800);
+
+assertEquals(r3, r4);
+
+// Check overflow with -1 constant.
+function foo2(value) {
+  return value * -1;
+}
+
+foo2(-2147483600);
+foo2(-2147483600);
+%OptimizeFunctionOnNextCall(foo2);
+assertEquals(2147483648, foo2(-2147483648));
diff --git a/test/mjsunit/regress/regress-crbug-285355.js b/test/mjsunit/regress/regress-crbug-285355.js
new file mode 100644
index 0000000..ebd480a
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-285355.js
@@ -0,0 +1,43 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function inverted_index() {
+  return ~1;
+}
+
+%NeverOptimizeFunction(inverted_index);
+
+function crash(array) {
+  return array[~inverted_index()] = 2;
+}
+
+assertEquals(2, crash(new Array(1)));
+assertEquals(2, crash(new Array(1)));
+%OptimizeFunctionOnNextCall(crash)
+assertEquals(2, crash(new Array(1)));
diff --git a/tools/run-tests.py b/tools/run-tests.py
index 48682d4..4f212d6 100755
--- a/tools/run-tests.py
+++ b/tools/run-tests.py
@@ -293,7 +293,7 @@
   if timeout == -1:
     # Simulators are slow, therefore allow a longer default timeout.
     if arch in SLOW_ARCHS:
-      timeout = 2 * TIMEOUT_DEFAULT;
+      timeout = 3 * TIMEOUT_DEFAULT;
     else:
       timeout = TIMEOUT_DEFAULT;