Merge v8 from https://chromium.googlesource.com/external/v8.git at 5ae72c9d3193fcbb0e2640a2b74b2f1f0d1b05e9

This commit was generated by merge_from_chromium.py.

Change-Id: I3bf2ac32eaeef3a3997ee2b7197348aa1a190eb7
diff --git a/ChangeLog b/ChangeLog
index f3498c7..153f45c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2013-09-27: Version 3.22.3
+
+        Added methods to enable configuration of ResourceConstraints based on
+        limits derived at runtime.
+        (Chromium issue 292928)
+
+        Added -optimize-for-size flag to optimize for memory size (will be used
+        by pre-aging CL), and removed the is_memory_constrained
+        ResourceConstraint.
+        (Chromium issue 292928)
+
+        Performance and stability improvements on all platforms.
+
+
 2013-09-26: Version 3.22.2
 
         Performance and stability improvements on all platforms.
diff --git a/include/v8-defaults.h b/include/v8-defaults.h
new file mode 100644
index 0000000..381a482
--- /dev/null
+++ b/include/v8-defaults.h
@@ -0,0 +1,54 @@
+// 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.
+
+#ifndef V8_V8_DEFAULTS_H_
+#define V8_V8_DEFAULTS_H_
+
+#include "v8.h"
+
+/**
+ * Default configuration support for the V8 JavaScript engine.
+ */
+namespace v8 {
+
+/**
+ * Configures the constraints with reasonable default values based on the
+ * capabilities of the current device the VM is running on.
+ */
+bool V8_EXPORT ConfigureResourceConstraintsForCurrentPlatform(
+    ResourceConstraints* constraints);
+
+
+/**
+ * Convience function which performs SetResourceConstraints with the settings
+ * returned by ConfigureResourceConstraintsForCurrentPlatform.
+ */
+bool V8_EXPORT SetDefaultResourceConstraintsForCurrentPlatform();
+
+}  // namespace v8
+
+#endif  // V8_V8_DEFAULTS_H_
diff --git a/include/v8-testing.h b/include/v8-testing.h
index 97b467a..ba4fcc4 100644
--- a/include/v8-testing.h
+++ b/include/v8-testing.h
@@ -68,8 +68,4 @@
 
 }  // namespace v8
 
-
-#undef V8_EXPORT
-
-
 #endif  // V8_V8_TEST_H_
diff --git a/include/v8.h b/include/v8.h
index 62a1cb3..19abf0f 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -135,6 +135,7 @@
 class ObjectOperationDescriptor;
 class RawOperationDescriptor;
 class CallHandlerHelper;
+class EscapableHandleScope;
 
 namespace internal {
 class Arguments;
@@ -377,7 +378,6 @@
    * The referee is kept alive by the local handle even when
    * the original handle is destroyed/disposed.
    */
-  V8_INLINE static Local<T> New(Handle<T> that);
   V8_INLINE static Local<T> New(Isolate* isolate, Handle<T> that);
   template<class M>
   V8_INLINE static Local<T> New(Isolate* isolate,
@@ -401,6 +401,7 @@
   friend class Context;
   template<class F> friend class internal::CustomArguments;
   friend class HandleScope;
+  friend class EscapableHandleScope;
 
   V8_INLINE static Local<T> New(Isolate* isolate, T* that);
 };
@@ -773,10 +774,7 @@
 
   ~HandleScope();
 
-  /**
-   * Closes the handle scope and returns the value as a handle in the
-   * previous scope, which is the new current scope after the call.
-   */
+  // TODO(dcarney): deprecated - use EscapableHandleScope::Escape.
   template <class T> Local<T> Close(Handle<T> value);
 
   /**
@@ -784,16 +782,19 @@
    */
   static int NumberOfHandles();
 
+ private:
   /**
    * Creates a new handle with the given value.
    */
-  static internal::Object** CreateHandle(internal::Object* value);
   static internal::Object** CreateHandle(internal::Isolate* isolate,
                                          internal::Object* value);
-  // Faster version, uses HeapObject to obtain the current Isolate.
-  static internal::Object** CreateHandle(internal::HeapObject* value);
+  // Uses HeapObject to obtain the current Isolate.
+  static internal::Object** CreateHandle(internal::HeapObject* heap_object,
+                                         internal::Object* value);
 
- private:
+  V8_INLINE HandleScope() {}
+  void Initialize(Isolate* isolate);
+
   // Make it hard to create heap-allocated or illegal handle scopes by
   // disallowing certain operations.
   HandleScope(const HandleScope&);
@@ -814,19 +815,58 @@
     }
   };
 
-  void Initialize(Isolate* isolate);
   void Leave();
 
   internal::Isolate* isolate_;
   internal::Object** prev_next_;
   internal::Object** prev_limit_;
 
+  // TODO(dcarney): remove this field
   // Allow for the active closing of HandleScopes which allows to pass a handle
   // from the HandleScope being closed to the next top most HandleScope.
   bool is_closed_;
   internal::Object** RawClose(internal::Object** value);
 
   friend class ImplementationUtilities;
+  friend class EscapableHandleScope;
+  template<class F> friend class Handle;
+  template<class F> friend class Local;
+  friend class Object;
+  friend class Context;
+};
+
+
+/**
+ * A HandleScope which first allocates a handle in the current scope
+ * which will be later filled with the escape value.
+ */
+class V8_EXPORT EscapableHandleScope : public HandleScope {
+ public:
+  EscapableHandleScope(Isolate* isolate);
+  V8_INLINE ~EscapableHandleScope() {}
+
+  /**
+   * Pushes the value into the previous scope and returns a handle to it.
+   * Cannot be called twice.
+   */
+  template <class T>
+  V8_INLINE Local<T> Escape(Local<T> value) {
+    internal::Object** slot =
+        Escape(reinterpret_cast<internal::Object**>(*value));
+    return Local<T>(reinterpret_cast<T*>(slot));
+  }
+
+ private:
+  internal::Object** Escape(internal::Object** escape_value);
+
+  // Make it hard to create heap-allocated or illegal handle scopes by
+  // disallowing certain operations.
+  EscapableHandleScope(const EscapableHandleScope&);
+  void operator=(const EscapableHandleScope&);
+  void* operator new(size_t size);
+  void operator delete(void*, size_t);
+
+  internal::Object** escape_slot_;
 };
 
 
@@ -2386,13 +2426,13 @@
  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;
-  static const int kContextSaveIndex = -6;
+  static const int kContextSaveIndex = 0;
+  static const int kCalleeIndex = -1;
+  static const int kDataIndex = -2;
+  static const int kReturnValueIndex = -3;
+  static const int kReturnValueDefaultValueIndex = -4;
+  static const int kIsolateIndex = -5;
+  static const int kHolderIndex = -6;
 
   V8_INLINE FunctionCallbackInfo(internal::Object** implicit_args,
                    internal::Object** values,
@@ -3762,23 +3802,18 @@
   uint32_t* stack_limit() const { return stack_limit_; }
   // Sets an address beyond which the VM's stack may not grow.
   void set_stack_limit(uint32_t* value) { stack_limit_ = value; }
-  Maybe<bool> is_memory_constrained() const { return is_memory_constrained_; }
-  // If set to true, V8 will limit it's memory usage, at the potential cost of
-  // lower performance.  Note, this option is a tentative addition to the API
-  // and may be removed or modified without warning.
-  void set_memory_constrained(bool value) {
-    is_memory_constrained_ = Maybe<bool>(value);
-  }
 
  private:
   int max_young_space_size_;
   int max_old_space_size_;
   int max_executable_size_;
   uint32_t* stack_limit_;
-  Maybe<bool> is_memory_constrained_;
 };
 
 
+/**
+ * Sets the given ResourceConstraints on the current isolate.
+ */
 bool V8_EXPORT SetResourceConstraints(ResourceConstraints* constraints);
 
 
@@ -3791,12 +3826,7 @@
 typedef void (*MessageCallback)(Handle<Message> message, Handle<Value> error);
 
 
-/**
- * Schedules an exception to be thrown when returning to JavaScript.  When an
- * exception has been scheduled it is illegal to invoke any JavaScript
- * operation; the caller must return immediately and only after the exception
- * has been handled does it become legal to invoke JavaScript operations.
- */
+// TODO(dcarney): remove. Use Isolate::ThrowException instead.
 Handle<Value> V8_EXPORT ThrowException(Handle<Value> exception);
 
 /**
@@ -4052,6 +4082,14 @@
   Local<Context> GetEnteredContext();
 
   /**
+   * Schedules an exception to be thrown when returning to JavaScript.  When an
+   * exception has been scheduled it is illegal to invoke any JavaScript
+   * operation; the caller must return immediately and only after the exception
+   * has been handled does it become legal to invoke JavaScript operations.
+   */
+  Local<Value> ThrowException(Local<Value> exception);
+
+  /**
    * Allows the host application to group objects together. If one
    * object in the group is alive, all objects in the group are alive.
    * After each garbage collection, object groups are removed. It is
@@ -5425,7 +5463,7 @@
   static const int kUndefinedOddballKind = 5;
   static const int kNullOddballKind = 3;
 
-  static void CheckInitializedImpl(v8::Isolate* isolate);
+  V8_EXPORT static void CheckInitializedImpl(v8::Isolate* isolate);
   V8_INLINE static void CheckInitialized(v8::Isolate* isolate) {
 #ifdef V8_ENABLE_CHECKS
     CheckInitializedImpl(isolate);
@@ -5541,19 +5579,6 @@
 
 
 template <class T>
-Local<T> Local<T>::New(Handle<T> that) {
-  if (that.IsEmpty()) return Local<T>();
-  T* that_ptr = *that;
-  internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr);
-  if (internal::Internals::CanCastToHeapObject(that_ptr)) {
-    return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
-        reinterpret_cast<internal::HeapObject*>(*p))));
-  }
-  return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(*p)));
-}
-
-
-template <class T>
 Local<T> Local<T>::New(Isolate* isolate, Handle<T> that) {
   return New(isolate, that.val_);
 }
@@ -5894,7 +5919,7 @@
 
 template<typename T>
 Local<Value> FunctionCallbackInfo<T>::operator[](int i) const {
-  if (i < 0 || length_ <= i) return Local<Value>(*Undefined());
+  if (i < 0 || length_ <= i) return Local<Value>(*Undefined(GetIsolate()));
   return Local<Value>(reinterpret_cast<Value*>(values_ - i));
 }
 
@@ -5976,7 +6001,8 @@
 
 
 Handle<Boolean> Boolean::New(bool value) {
-  return value ? True() : False();
+  Isolate* isolate = Isolate::GetCurrent();
+  return value ? True(isolate) : False(isolate);
 }
 
 
@@ -5988,6 +6014,7 @@
 Local<Value> Object::GetInternalField(int index) {
 #ifndef V8_ENABLE_CHECKS
   typedef internal::Object O;
+  typedef internal::HeapObject HO;
   typedef internal::Internals I;
   O* obj = *reinterpret_cast<O**>(this);
   // Fast path: If the object is a plain JSObject, which is the common case, we
@@ -5995,7 +6022,7 @@
   if (I::GetInstanceType(obj) == I::kJSObjectType) {
     int offset = I::kJSObjectHeaderSize + (internal::kApiPointerSize * index);
     O* value = I::ReadField<O*>(obj, offset);
-    O** result = HandleScope::CreateHandle(value);
+    O** result = HandleScope::CreateHandle(reinterpret_cast<HO*>(obj), value);
     return Local<Value>(reinterpret_cast<Value*>(result));
   }
 #endif
@@ -6447,8 +6474,11 @@
 Local<Value> Context::GetEmbedderData(int index) {
 #ifndef V8_ENABLE_CHECKS
   typedef internal::Object O;
+  typedef internal::HeapObject HO;
   typedef internal::Internals I;
-  O** result = HandleScope::CreateHandle(I::ReadEmbedderData<O*>(this, index));
+  HO* context = *reinterpret_cast<HO**>(this);
+  O** result =
+      HandleScope::CreateHandle(context, I::ReadEmbedderData<O*>(this, index));
   return Local<Value>(reinterpret_cast<Value*>(result));
 #else
   return SlowGetEmbedderData(index);
diff --git a/samples/lineprocessor.cc b/samples/lineprocessor.cc
index b4ffb44..5068c88 100644
--- a/samples/lineprocessor.cc
+++ b/samples/lineprocessor.cc
@@ -296,7 +296,7 @@
     v8::HandleScope handle_scope(isolate);
 
     v8::Handle<v8::String> input_line = ReadLine();
-    if (input_line == v8::Undefined()) {
+    if (input_line == v8::Undefined(isolate)) {
       continue;
     }
 
@@ -417,7 +417,7 @@
 // function is called. Reads a string from standard input and returns.
 void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() > 0) {
-    v8::ThrowException(v8::String::New("Unexpected arguments"));
+    args.GetIsolate()->ThrowException(v8::String::New("Unexpected arguments"));
     return;
   }
   args.GetReturnValue().Set(ReadLine());
@@ -436,7 +436,7 @@
     res = fgets(buffer, kBufferSize, stdin);
   }
   if (res == NULL) {
-    v8::Handle<v8::Primitive> t = v8::Undefined();
+    v8::Handle<v8::Primitive> t = v8::Undefined(v8::Isolate::GetCurrent());
     return v8::Handle<v8::String>::Cast(t);
   }
   // Remove newline char
diff --git a/samples/shell.cc b/samples/shell.cc
index 710547c..06bd8f6 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -140,17 +140,20 @@
 // the argument into a JavaScript string.
 void Read(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
-    v8::ThrowException(v8::String::New("Bad parameters"));
+    args.GetIsolate()->ThrowException(
+        v8::String::New("Bad parameters"));
     return;
   }
   v8::String::Utf8Value file(args[0]);
   if (*file == NULL) {
-    v8::ThrowException(v8::String::New("Error loading file"));
+    args.GetIsolate()->ThrowException(
+        v8::String::New("Error loading file"));
     return;
   }
   v8::Handle<v8::String> source = ReadFile(*file);
   if (source.IsEmpty()) {
-    v8::ThrowException(v8::String::New("Error loading file"));
+    args.GetIsolate()->ThrowException(
+        v8::String::New("Error loading file"));
     return;
   }
   args.GetReturnValue().Set(source);
@@ -165,12 +168,14 @@
     v8::HandleScope handle_scope(args.GetIsolate());
     v8::String::Utf8Value file(args[i]);
     if (*file == NULL) {
-      v8::ThrowException(v8::String::New("Error loading file"));
+      args.GetIsolate()->ThrowException(
+          v8::String::New("Error loading file"));
       return;
     }
     v8::Handle<v8::String> source = ReadFile(*file);
     if (source.IsEmpty()) {
-      v8::ThrowException(v8::String::New("Error loading file"));
+      args.GetIsolate()->ThrowException(
+           v8::String::New("Error loading file"));
       return;
     }
     if (!ExecuteString(args.GetIsolate(),
@@ -178,7 +183,8 @@
                        v8::String::New(*file),
                        false,
                        false)) {
-      v8::ThrowException(v8::String::New("Error executing file"));
+      args.GetIsolate()->ThrowException(
+          v8::String::New("Error executing file"));
       return;
     }
   }
diff --git a/src/api.cc b/src/api.cc
index 6eb3789..6d62749 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -473,16 +473,7 @@
 
 
 v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {
-  i::Isolate* isolate = i::Isolate::Current();
-  ENTER_V8(isolate);
-  // If we're passed an empty handle, we throw an undefined exception
-  // to deal more gracefully with out of memory situations.
-  if (value.IsEmpty()) {
-    isolate->ScheduleThrow(isolate->heap()->undefined_value());
-  } else {
-    isolate->ScheduleThrow(*Utils::OpenHandle(*value));
-  }
-  return v8::Undefined();
+  return v8::Isolate::GetCurrent()->ThrowException(value);
 }
 
 
@@ -572,8 +563,7 @@
   : max_young_space_size_(0),
     max_old_space_size_(0),
     max_executable_size_(0),
-    stack_limit_(NULL),
-    is_memory_constrained_() { }
+    stack_limit_(NULL) { }
 
 
 bool SetResourceConstraints(ResourceConstraints* constraints) {
@@ -594,11 +584,6 @@
     uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());
     isolate->stack_guard()->SetStackLimit(limit);
   }
-  if (constraints->is_memory_constrained().has_value &&
-      !i::FLAG_force_memory_constrained.has_value) {
-    isolate->set_is_memory_constrained(
-        constraints->is_memory_constrained().value);
-  }
   return true;
 }
 
@@ -698,21 +683,35 @@
 }
 
 
-i::Object** HandleScope::CreateHandle(i::Object* value) {
-  return i::HandleScope::CreateHandle(i::Isolate::Current(), value);
-}
-
-
 i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
-  ASSERT(isolate == i::Isolate::Current());
   return i::HandleScope::CreateHandle(isolate, value);
 }
 
 
-i::Object** HandleScope::CreateHandle(i::HeapObject* value) {
-  ASSERT(value->IsHeapObject());
-  return reinterpret_cast<i::Object**>(
-      i::HandleScope::CreateHandle(value->GetIsolate(), value));
+i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
+                                      i::Object* value) {
+  ASSERT(heap_object->IsHeapObject());
+  return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
+}
+
+
+EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+  escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
+  Initialize(v8_isolate);
+}
+
+
+i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
+  ApiCheck(*escape_slot_ == isolate_->heap()->the_hole_value(),
+           "EscapeableHandleScope::Escape",
+           "Escape value set twice");
+  if (escape_value == NULL) {
+    *escape_slot_ = isolate_->heap()->undefined_value();
+    return NULL;
+  }
+  *escape_slot_ = *escape_value;
+  return escape_slot_;
 }
 
 
@@ -1019,7 +1018,9 @@
   }
   obj->set_serial_number(i::Smi::FromInt(next_serial_number));
   if (callback != 0) {
-    if (data.IsEmpty()) data = v8::Undefined();
+    if (data.IsEmpty()) {
+      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+    }
     Utils::ToLocal(obj)->SetCallHandler(callback, data);
   }
   obj->set_length(length);
@@ -1243,7 +1244,9 @@
   i::Handle<i::CallHandlerInfo> obj =
       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
   SET_FIELD_WRAPPED(obj, set_callback, callback);
-  if (data.IsEmpty()) data = v8::Undefined();
+  if (data.IsEmpty()) {
+    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+  }
   obj->set_data(*Utils::OpenHandle(*data));
   Utils::OpenHandle(this)->set_call_code(*obj);
 }
@@ -1281,7 +1284,9 @@
       isolate->factory()->NewExecutableAccessorInfo();
   SET_FIELD_WRAPPED(obj, set_getter, getter);
   SET_FIELD_WRAPPED(obj, set_setter, setter);
-  if (data.IsEmpty()) data = v8::Undefined();
+  if (data.IsEmpty()) {
+    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+  }
   obj->set_data(*Utils::OpenHandle(*data));
   return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
 }
@@ -1509,7 +1514,9 @@
   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
 
-  if (data.IsEmpty()) data = v8::Undefined();
+  if (data.IsEmpty()) {
+    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+  }
   obj->set_data(*Utils::OpenHandle(*data));
   cons->set_named_property_handler(*obj);
 }
@@ -1545,7 +1552,9 @@
   SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
   SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
 
-  if (data.IsEmpty()) data = v8::Undefined();
+  if (data.IsEmpty()) {
+    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+  }
   info->set_data(*Utils::OpenHandle(*data));
 
   i::FunctionTemplateInfo* constructor =
@@ -1581,7 +1590,9 @@
   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
 
-  if (data.IsEmpty()) data = v8::Undefined();
+  if (data.IsEmpty()) {
+    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+  }
   obj->set_data(*Utils::OpenHandle(*data));
   cons->set_indexed_property_handler(*obj);
 }
@@ -1601,7 +1612,9 @@
   i::Handle<i::CallHandlerInfo> obj =
       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
   SET_FIELD_WRAPPED(obj, set_callback, callback);
-  if (data.IsEmpty()) data = v8::Undefined();
+  if (data.IsEmpty()) {
+    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+  }
   obj->set_data(*Utils::OpenHandle(*data));
   cons->set_instance_call_handler(*obj);
 }
@@ -1706,8 +1719,9 @@
             static_cast<int>(origin->ResourceColumnOffset()->Value());
       }
       if (!origin->ResourceIsSharedCrossOrigin().IsEmpty()) {
+        v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
         is_shared_cross_origin =
-            origin->ResourceIsSharedCrossOrigin() == v8::True();
+            origin->ResourceIsSharedCrossOrigin() == v8::True(v8_isolate);
       }
     }
     EXCEPTION_PREAMBLE(isolate);
@@ -1915,8 +1929,9 @@
 v8::TryCatch::~TryCatch() {
   ASSERT(isolate_ == i::Isolate::Current());
   if (rethrow_) {
-    v8::HandleScope scope(reinterpret_cast<Isolate*>(isolate_));
-    v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
+    v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
+    v8::HandleScope scope(isolate);
+    v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
     if (HasCaught() && capture_message_) {
       // If an exception was caught and rethrow_ is indicated, the saved
       // message, script, and location need to be restored to Isolate TLS
@@ -1926,7 +1941,7 @@
       isolate_->RestorePendingMessageFromTryCatch(this);
     }
     isolate_->UnregisterTryCatchHandler(this);
-    v8::ThrowException(exc);
+    reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
     ASSERT(!isolate_->thread_local_top()->rethrowing_message_);
   } else {
     isolate_->UnregisterTryCatchHandler(this);
@@ -1952,7 +1967,7 @@
 v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
   if (!HasCaught()) return v8::Local<v8::Value>();
   rethrow_ = true;
-  return v8::Undefined();
+  return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
 }
 
 
@@ -4122,10 +4137,12 @@
 
 Handle<Value> Function::GetScriptId() const {
   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
-  if (!func->shared()->script()->IsScript())
-    return v8::Undefined();
+  i::Isolate* isolate = func->GetIsolate();
+  if (!func->shared()->script()->IsScript()) {
+    return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+  }
   i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
-  return Utils::ToLocal(i::Handle<i::Object>(script->id(), func->GetIsolate()));
+  return Utils::ToLocal(i::Handle<i::Object>(script->id(), isolate));
 }
 
 
@@ -6361,6 +6378,20 @@
 }
 
 
+v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  ENTER_V8(isolate);
+  // If we're passed an empty handle, we throw an undefined exception
+  // to deal more gracefully with out of memory situations.
+  if (value.IsEmpty()) {
+    isolate->ScheduleThrow(isolate->heap()->undefined_value());
+  } else {
+    isolate->ScheduleThrow(*Utils::OpenHandle(*value));
+  }
+  return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+}
+
+
 void Isolate::SetObjectGroupId(const Persistent<Value>& object,
                                UniqueId id) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
@@ -7108,7 +7139,7 @@
           isolate->factory()->NewNumberFromInt(edge->index()));
     default: UNREACHABLE();
   }
-  return v8::Undefined();
+  return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
 }
 
 
diff --git a/src/arguments.h b/src/arguments.h
index f291816..634545e 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -238,6 +238,12 @@
   typedef CustomArguments<T> Super;
   static const int kArgsLength = T::kArgsLength;
   static const int kHolderIndex = T::kHolderIndex;
+  static const int kDataIndex = T::kDataIndex;
+  static const int kReturnValueDefaultValueIndex =
+      T::kReturnValueDefaultValueIndex;
+  static const int kIsolateIndex = T::kIsolateIndex;
+  static const int kCalleeIndex = T::kCalleeIndex;
+  static const int kContextSaveIndex = T::kContextSaveIndex;
 
   FunctionCallbackArguments(internal::Isolate* isolate,
       internal::Object* data,
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 6308b34..b860e3e 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -842,27 +842,25 @@
                                       int argc,
                                       bool restore_context) {
   // ----------- S t a t e -------------
-  //  -- sp[0]              : context
-  //  -- sp[4]              : holder (set by CheckPrototypes)
-  //  -- sp[8]              : callee JS function
-  //  -- sp[12]             : call data
-  //  -- sp[16]             : isolate
-  //  -- sp[20]             : ReturnValue default value
-  //  -- sp[24]             : ReturnValue
+  //  -- sp[0] - sp[24]     : FunctionCallbackInfo, incl.
+  //                        :  holder (set by CheckPrototypes)
   //  -- sp[28]             : last JS argument
   //  -- ...
   //  -- sp[(argc + 6) * 4] : first JS argument
   //  -- sp[(argc + 7) * 4] : receiver
   // -----------------------------------
+  typedef FunctionCallbackArguments FCA;
+  const int kArgs = kFastApiCallArguments;
   // Save calling context.
-  __ str(cp, MemOperand(sp));
+  __ str(cp,
+         MemOperand(sp, (kArgs - 1 + FCA::kContextSaveIndex) * kPointerSize));
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(r5, function);
   __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset));
-  __ str(r5, MemOperand(sp, 2 * kPointerSize));
+  __ str(r5, MemOperand(sp, (kArgs - 1 + FCA::kCalleeIndex) * kPointerSize));
 
-  // Pass the additional arguments.
+  // Construct the FunctionCallbackInfo.
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
@@ -872,17 +870,21 @@
     __ Move(r6, call_data);
   }
   // Store call data.
-  __ str(r6, MemOperand(sp, 3 * kPointerSize));
+  __ str(r6, MemOperand(sp, (kArgs - 1 + FCA::kDataIndex) * kPointerSize));
   // Store isolate.
   __ mov(r5, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ str(r5, MemOperand(sp, 4 * kPointerSize));
+  __ str(r5, MemOperand(sp, (kArgs - 1 + FCA::kIsolateIndex) * kPointerSize));
   // Store ReturnValue default and ReturnValue.
   __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
-  __ str(r5, MemOperand(sp, 5 * kPointerSize));
-  __ str(r5, MemOperand(sp, 6 * kPointerSize));
+  __ str(r5,
+         MemOperand(sp, (kArgs - 1 + FCA::kReturnValueOffset) * kPointerSize));
+  __ str(
+      r5,
+      MemOperand(
+          sp, (kArgs - 1 + FCA::kReturnValueDefaultValueIndex) * kPointerSize));
 
   // Prepare arguments.
-  __ add(r2, sp, Operand((kFastApiCallArguments - 1) * kPointerSize));
+  __ add(r2, sp, Operand((kArgs - 1) * kPointerSize));
 
   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
@@ -906,7 +908,7 @@
   __ mov(ip, Operand::Zero());
   __ str(ip, MemOperand(r0, 3 * kPointerSize));
 
-  const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
+  const int kStackUnwindSpace = argc + kArgs + 1;
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
   ApiFunction fun(function_address);
   ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
@@ -921,9 +923,9 @@
 
   AllowExternalCallThatCantCauseGC scope(masm);
   MemOperand context_restore_operand(
-      fp, 2 * kPointerSize);
+      fp, (kArgs + 1 + FCA::kContextSaveIndex) * kPointerSize);
   MemOperand return_value_operand(
-      fp, (kFastApiCallArguments + 1) * kPointerSize);
+      fp, (kArgs + 1 + FCA::kReturnValueOffset) * kPointerSize);
   __ CallApiFunctionAndReturn(ref,
                               function_address,
                               thunk_ref,
diff --git a/src/d8-posix.cc b/src/d8-posix.cc
index 424dbbb..81c15ae 100644
--- a/src/d8-posix.cc
+++ b/src/d8-posix.cc
@@ -245,7 +245,8 @@
     if (args[3]->IsNumber()) {
       *total_timeout = args[3]->Int32Value();
     } else {
-      ThrowException(String::New("system: Argument 4 must be a number"));
+      args.GetIsolate()->ThrowException(
+          String::New("system: Argument 4 must be a number"));
       return false;
     }
   }
@@ -253,7 +254,8 @@
     if (args[2]->IsNumber()) {
       *read_timeout = args[2]->Int32Value();
     } else {
-      ThrowException(String::New("system: Argument 3 must be a number"));
+      args.GetIsolate()->ThrowException(
+          String::New("system: Argument 3 must be a number"));
       return false;
     }
   }
@@ -456,7 +458,8 @@
   Handle<Array> command_args;
   if (args.Length() > 1) {
     if (!args[1]->IsArray()) {
-      ThrowException(String::New("system: Argument 2 must be an array"));
+      args.GetIsolate()->ThrowException(
+          String::New("system: Argument 2 must be an array"));
       return;
     }
     command_args = Handle<Array>::Cast(args[1]);
@@ -464,11 +467,13 @@
     command_args = Array::New(0);
   }
   if (command_args->Length() > ExecArgs::kMaxArgs) {
-    ThrowException(String::New("Too many arguments to system()"));
+    args.GetIsolate()->ThrowException(
+        String::New("Too many arguments to system()"));
     return;
   }
   if (args.Length() < 1) {
-    ThrowException(String::New("Too few arguments to system()"));
+    args.GetIsolate()->ThrowException(
+        String::New("Too few arguments to system()"));
     return;
   }
 
@@ -483,11 +488,13 @@
   int stdout_fds[2];
 
   if (pipe(exec_error_fds) != 0) {
-    ThrowException(String::New("pipe syscall failed."));
+    args.GetIsolate()->ThrowException(
+        String::New("pipe syscall failed."));
     return;
   }
   if (pipe(stdout_fds) != 0) {
-    ThrowException(String::New("pipe syscall failed."));
+    args.GetIsolate()->ThrowException(
+        String::New("pipe syscall failed."));
     return;
   }
 
@@ -531,17 +538,17 @@
 void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "chdir() takes one argument";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   String::Utf8Value directory(args[0]);
   if (*directory == NULL) {
     const char* message = "os.chdir(): String conversion of argument failed.";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   if (chdir(*directory) != 0) {
-    ThrowException(String::New(strerror(errno)));
+    args.GetIsolate()->ThrowException(String::New(strerror(errno)));
     return;
   }
 }
@@ -550,7 +557,7 @@
 void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "umask() takes one argument";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   if (args[0]->IsNumber()) {
@@ -560,7 +567,7 @@
     return;
   } else {
     const char* message = "umask() argument must be numeric";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
 }
@@ -616,18 +623,18 @@
       mask = args[1]->Int32Value();
     } else {
       const char* message = "mkdirp() second argument must be numeric";
-      ThrowException(String::New(message));
+      args.GetIsolate()->ThrowException(String::New(message));
       return;
     }
   } else if (args.Length() != 1) {
     const char* message = "mkdirp() takes one or two arguments";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   String::Utf8Value directory(args[0]);
   if (*directory == NULL) {
     const char* message = "os.mkdirp(): String conversion of argument failed.";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   mkdirp(*directory, mask);
@@ -637,13 +644,13 @@
 void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "rmdir() takes one or two arguments";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   String::Utf8Value directory(args[0]);
   if (*directory == NULL) {
     const char* message = "os.rmdir(): String conversion of argument failed.";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   rmdir(*directory);
@@ -653,7 +660,7 @@
 void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 2) {
     const char* message = "setenv() takes two arguments";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   String::Utf8Value var(args[0]);
@@ -661,13 +668,13 @@
   if (*var == NULL) {
     const char* message =
         "os.setenv(): String conversion of variable name failed.";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   if (*value == NULL) {
     const char* message =
         "os.setenv(): String conversion of variable contents failed.";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   setenv(*var, *value, 1);
@@ -677,14 +684,14 @@
 void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "unsetenv() takes one argument";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   String::Utf8Value var(args[0]);
   if (*var == NULL) {
     const char* message =
         "os.setenv(): String conversion of variable name failed.";
-    ThrowException(String::New(message));
+    args.GetIsolate()->ThrowException(String::New(message));
     return;
   }
   unsetenv(*var);
diff --git a/src/d8.cc b/src/d8.cc
index 614b16e..1c6e453 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -49,6 +49,7 @@
 #endif  // !V8_SHARED
 
 #ifdef V8_SHARED
+#include "../include/v8-defaults.h"
 #include "../include/v8-testing.h"
 #endif  // V8_SHARED
 
@@ -66,6 +67,7 @@
 #include "natives.h"
 #include "platform.h"
 #include "v8.h"
+#include "v8-defaults.h"
 #endif  // V8_SHARED
 
 #if !defined(_WIN32) && !defined(_WIN64)
@@ -1649,6 +1651,7 @@
 #else
   SetStandaloneFlagsViaCommandLine();
 #endif
+  v8::SetDefaultResourceConstraintsForCurrentPlatform();
   ShellArrayBufferAllocator array_buffer_allocator;
   v8::V8::SetArrayBufferAllocator(&array_buffer_allocator);
   int result = 0;
diff --git a/src/debug.cc b/src/debug.cc
index 63d33eb..c820b97 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -3135,8 +3135,7 @@
     v8::Local<v8::Function> fun =
         v8::Local<v8::Function>::Cast(api_exec_state->Get(fun_name));
 
-    v8::Handle<v8::Boolean> running =
-        auto_continue ? v8::True() : v8::False();
+    v8::Handle<v8::Boolean> running = v8::Boolean::New(auto_continue);
     static const int kArgc = 1;
     v8::Handle<Value> argv[kArgc] = { running };
     cmd_processor = v8::Local<v8::Object>::Cast(
diff --git a/src/defaults.cc b/src/defaults.cc
new file mode 100644
index 0000000..301155f
--- /dev/null
+++ b/src/defaults.cc
@@ -0,0 +1,71 @@
+// 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.
+
+#include "../include/v8-defaults.h"
+
+#include "platform.h"
+#include "globals.h"
+#include "v8.h"
+
+namespace v8 {
+
+bool ConfigureResourceConstraintsForCurrentPlatform(
+    ResourceConstraints* constraints) {
+  if (constraints == NULL) {
+    return false;
+  }
+
+  uint64_t physical_memory = i::OS::TotalPhysicalMemory();
+  int lump_of_memory = (i::kPointerSize / 4) * i::MB;
+
+  // The young_space_size should be a power of 2 and old_generation_size should
+  // be a multiple of Page::kPageSize.
+  if (physical_memory > 2ul * i::GB) {
+    constraints->set_max_young_space_size(16 * lump_of_memory);
+    constraints->set_max_old_space_size(700 * lump_of_memory);
+    constraints->set_max_executable_size(256 * lump_of_memory);
+  } else if (physical_memory > 512ul * i::MB) {
+    constraints->set_max_young_space_size(8 * lump_of_memory);
+    constraints->set_max_old_space_size(192 * lump_of_memory);
+    constraints->set_max_executable_size(192 * lump_of_memory);
+  } else /* (physical_memory <= 512GB) */ {
+    constraints->set_max_young_space_size(2 * lump_of_memory);
+    constraints->set_max_old_space_size(96 * lump_of_memory);
+    constraints->set_max_executable_size(96 * lump_of_memory);
+  }
+  return true;
+}
+
+
+bool SetDefaultResourceConstraintsForCurrentPlatform() {
+  ResourceConstraints constraints;
+  if (!ConfigureResourceConstraintsForCurrentPlatform(&constraints))
+    return false;
+  return SetResourceConstraints(&constraints);
+}
+
+}  // namespace v8::internal
diff --git a/src/extensions/externalize-string-extension.cc b/src/extensions/externalize-string-extension.cc
index 5fd821b..9fdb194 100644
--- a/src/extensions/externalize-string-extension.cc
+++ b/src/extensions/externalize-string-extension.cc
@@ -75,7 +75,7 @@
 void ExternalizeStringExtension::Externalize(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() < 1 || !args[0]->IsString()) {
-    v8::ThrowException(v8::String::New(
+    args.GetIsolate()->ThrowException(v8::String::New(
         "First parameter to externalizeString() must be a string."));
     return;
   }
@@ -84,7 +84,7 @@
     if (args[1]->IsBoolean()) {
       force_two_byte = args[1]->BooleanValue();
     } else {
-      v8::ThrowException(v8::String::New(
+      args.GetIsolate()->ThrowException(v8::String::New(
         "Second parameter to externalizeString() must be a boolean."));
       return;
     }
@@ -92,7 +92,7 @@
   bool result = false;
   Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
   if (string->IsExternalString()) {
-    v8::ThrowException(v8::String::New(
+    args.GetIsolate()->ThrowException(v8::String::New(
         "externalizeString() can't externalize twice."));
     return;
   }
@@ -120,7 +120,8 @@
     if (!result) delete resource;
   }
   if (!result) {
-    v8::ThrowException(v8::String::New("externalizeString() failed."));
+    args.GetIsolate()->ThrowException(
+        v8::String::New("externalizeString() failed."));
     return;
   }
 }
@@ -129,7 +130,7 @@
 void ExternalizeStringExtension::IsAscii(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1 || !args[0]->IsString()) {
-    v8::ThrowException(v8::String::New(
+    args.GetIsolate()->ThrowException(v8::String::New(
         "isAsciiString() requires a single string argument."));
     return;
   }
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index e745471..2a3c7e0 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -216,6 +216,11 @@
 DEFINE_implication(track_computed_fields, track_fields)
 DEFINE_bool(smi_binop, true, "support smi representation in binary operations")
 
+// Flags for optimization types.
+DEFINE_bool(optimize_for_size, false,
+            "Enables optimizations which favor memory size over execution "
+            "speed.")
+
 // Flags for data representation optimizations
 DEFINE_bool(unbox_double_arrays, true, "automatically unbox arrays of doubles")
 DEFINE_bool(string_slices, true, "use string slices")
@@ -227,7 +232,7 @@
 DEFINE_bool(use_gvn, true, "use hydrogen global value numbering")
 DEFINE_bool(use_canonicalizing, true, "use hydrogen instruction canonicalizing")
 DEFINE_bool(use_inlining, true, "use function inlining")
-DEFINE_bool(use_escape_analysis, true, "use hydrogen escape analysis")
+DEFINE_bool(use_escape_analysis, false, "use hydrogen escape analysis")
 DEFINE_bool(use_allocation_folding, true, "use allocation folding")
 DEFINE_int(max_inlining_levels, 5, "maximum number of inlining levels")
 DEFINE_int(max_inlined_source_size, 600,
@@ -242,6 +247,7 @@
             true,
             "crankshaft harvests type feedback from stub cache")
 DEFINE_bool(hydrogen_stats, false, "print statistics for hydrogen")
+DEFINE_bool(trace_check_elimination, false, "trace check elimination phase")
 DEFINE_bool(trace_hydrogen, false, "trace generated hydrogen to file")
 DEFINE_string(trace_hydrogen_filter, "*", "hydrogen tracing filter")
 DEFINE_bool(trace_hydrogen_stubs, false, "trace generated hydrogen for stubs")
@@ -284,6 +290,7 @@
 DEFINE_bool(analyze_environment_liveness, true,
             "analyze liveness of environment slots and zap dead values")
 DEFINE_bool(load_elimination, false, "use load elimination")
+DEFINE_bool(check_elimination, false, "use check elimination")
 DEFINE_bool(dead_code_elimination, true, "use dead code elimination")
 DEFINE_bool(fold_constants, true, "use constant folding")
 DEFINE_bool(trace_dead_code_elimination, false, "trace dead code elimination")
@@ -589,9 +596,6 @@
            0,
            "Fixed seed to use to hash property keys (0 means random)"
            "(with snapshots this option cannot override the baked-in seed)")
-DEFINE_maybe_bool(force_memory_constrained,
-           "force (if true) or prevent (if false) the runtime from treating "
-           "the device as being memory constrained.")
 
 // v8.cc
 DEFINE_bool(preemption, false,
diff --git a/src/globals.h b/src/globals.h
index 1977e68..d06c6d7 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -248,10 +248,12 @@
 const int kPointerSizeLog2 = 3;
 const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
 const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF);
+const bool kIs64BitArch = true;
 #else
 const int kPointerSizeLog2 = 2;
 const intptr_t kIntptrSignBit = 0x80000000;
 const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu;
+const bool kIs64BitArch = false;
 #endif
 
 const int kBitsPerByte = 8;
diff --git a/src/heap.cc b/src/heap.cc
index 7b9f0d5..5d75cb4 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -67,29 +67,14 @@
 
 Heap::Heap()
     : isolate_(NULL),
+      code_range_size_(kIs64BitArch ? 512 * MB : 0),
 // semispace_size_ should be a power of 2 and old_generation_size_ should be
 // a multiple of Page::kPageSize.
-#if V8_TARGET_ARCH_X64
-#define LUMP_OF_MEMORY (2 * MB)
-      code_range_size_(512*MB),
-#else
-#define LUMP_OF_MEMORY MB
-      code_range_size_(0),
-#endif
-#if defined(ANDROID) || V8_TARGET_ARCH_MIPS
-      reserved_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
-      max_semispace_size_(4 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
+      reserved_semispace_size_(8 * (kPointerSize / 4) * MB),
+      max_semispace_size_(8 * (kPointerSize / 4)  * MB),
       initial_semispace_size_(Page::kPageSize),
-      max_old_generation_size_(192*MB),
-      max_executable_size_(max_old_generation_size_),
-#else
-      reserved_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
-      max_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)),
-      initial_semispace_size_(Page::kPageSize),
-      max_old_generation_size_(700ul * LUMP_OF_MEMORY),
-      max_executable_size_(256l * LUMP_OF_MEMORY),
-#endif
-
+      max_old_generation_size_(700ul * (kPointerSize / 4) * MB),
+      max_executable_size_(256ul * (kPointerSize / 4) * MB),
 // Variables set based on semispace_size_ and old_generation_size_ in
 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_)
 // Will be 4 * reserved_semispace_size_ to ensure that young
@@ -170,6 +155,9 @@
   max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
 #endif
 
+  // Ensure old_generation_size_ is a multiple of kPageSize.
+  ASSERT(MB >= Page::kPageSize);
+
   intptr_t max_virtual = OS::MaxVirtualMemory();
 
   if (max_virtual > 0) {
@@ -5340,25 +5328,10 @@
 }
 
 
-MaybeObject* Heap::AllocateRawFixedArray(int length) {
-  if (length < 0 || length > FixedArray::kMaxLength) {
-    return Failure::OutOfMemoryException(0xd);
-  }
-  ASSERT(length > 0);
-  // Use the general function if we're forced to always allocate.
-  if (always_allocate()) return AllocateFixedArray(length, TENURED);
-  // Allocate the raw data for a fixed array.
-  int size = FixedArray::SizeFor(length);
-  return size <= Page::kMaxNonCodeHeapObjectSize
-      ? new_space_.AllocateRaw(size)
-      : lo_space_->AllocateRaw(size, NOT_EXECUTABLE);
-}
-
-
 MaybeObject* Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
   int len = src->length();
   Object* obj;
-  { MaybeObject* maybe_obj = AllocateRawFixedArray(len);
+  { MaybeObject* maybe_obj = AllocateRawFixedArray(len, NOT_TENURED);
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
   if (InNewSpace(obj)) {
@@ -5409,22 +5382,20 @@
 }
 
 
-MUST_USE_RESULT static MaybeObject* AllocateFixedArrayWithFiller(
-    Heap* heap,
-    int length,
-    PretenureFlag pretenure,
-    Object* filler) {
+MaybeObject* Heap::AllocateFixedArrayWithFiller(int length,
+                                                PretenureFlag pretenure,
+                                                Object* filler) {
   ASSERT(length >= 0);
-  ASSERT(heap->empty_fixed_array()->IsFixedArray());
-  if (length == 0) return heap->empty_fixed_array();
+  ASSERT(empty_fixed_array()->IsFixedArray());
+  if (length == 0) return empty_fixed_array();
 
-  ASSERT(!heap->InNewSpace(filler));
+  ASSERT(!InNewSpace(filler));
   Object* result;
-  { MaybeObject* maybe_result = heap->AllocateRawFixedArray(length, pretenure);
+  { MaybeObject* maybe_result = AllocateRawFixedArray(length, pretenure);
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
 
-  HeapObject::cast(result)->set_map_no_write_barrier(heap->fixed_array_map());
+  HeapObject::cast(result)->set_map_no_write_barrier(fixed_array_map());
   FixedArray* array = FixedArray::cast(result);
   array->set_length(length);
   MemsetPointer(array->data_start(), filler, length);
@@ -5433,19 +5404,13 @@
 
 
 MaybeObject* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
-  return AllocateFixedArrayWithFiller(this,
-                                      length,
-                                      pretenure,
-                                      undefined_value());
+  return AllocateFixedArrayWithFiller(length, pretenure, undefined_value());
 }
 
 
 MaybeObject* Heap::AllocateFixedArrayWithHoles(int length,
                                                PretenureFlag pretenure) {
-  return AllocateFixedArrayWithFiller(this,
-                                      length,
-                                      pretenure,
-                                      the_hole_value());
+  return AllocateFixedArrayWithFiller(length, pretenure, the_hole_value());
 }
 
 
@@ -5453,7 +5418,7 @@
   if (length == 0) return empty_fixed_array();
 
   Object* obj;
-  { MaybeObject* maybe_obj = AllocateRawFixedArray(length);
+  { MaybeObject* maybe_obj = AllocateRawFixedArray(length, NOT_TENURED);
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
 
diff --git a/src/heap.h b/src/heap.h
index e059434..d25c7c8 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -951,10 +951,6 @@
       int length,
       PretenureFlag pretenure = NOT_TENURED);
 
-  MUST_USE_RESULT MaybeObject* AllocateRawFixedDoubleArray(
-      int length,
-      PretenureFlag pretenure);
-
   // Allocates a fixed double array with uninitialized values. Returns
   // Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
   // Please note this does not perform a garbage collection.
@@ -1505,11 +1501,6 @@
   inline intptr_t AdjustAmountOfExternalAllocatedMemory(
       intptr_t change_in_bytes);
 
-  // Allocate uninitialized fixed array.
-  MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length);
-  MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(int length,
-                                                     PretenureFlag pretenure);
-
   // This is only needed for testing high promotion mode.
   void SetNewSpaceHighPromotionModeActive(bool mode) {
     new_space_high_promotion_mode_active_ = mode;
@@ -2083,6 +2074,18 @@
   // Allocate an uninitialized object in the global property cell space.
   MUST_USE_RESULT inline MaybeObject* AllocateRawPropertyCell();
 
+  // Allocate an uninitialized fixed array.
+  MUST_USE_RESULT MaybeObject* AllocateRawFixedArray(
+      int length, PretenureFlag pretenure);
+
+  // Allocate an uninitialized fixed double array.
+  MUST_USE_RESULT MaybeObject* AllocateRawFixedDoubleArray(
+      int length, PretenureFlag pretenure);
+
+  // Allocate an initialized fixed array with the given filler value.
+  MUST_USE_RESULT MaybeObject* AllocateFixedArrayWithFiller(
+      int length, PretenureFlag pretenure, Object* filler);
+
   // Initializes a JSObject based on its map.
   void InitializeJSObjectFromMap(JSObject* obj,
                                  FixedArray* properties,
diff --git a/src/hydrogen-check-elimination.cc b/src/hydrogen-check-elimination.cc
new file mode 100644
index 0000000..f712a39
--- /dev/null
+++ b/src/hydrogen-check-elimination.cc
@@ -0,0 +1,357 @@
+// 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.
+
+#include "hydrogen-check-elimination.h"
+#include "hydrogen-alias-analysis.h"
+
+namespace v8 {
+namespace internal {
+
+static const int kMaxTrackedObjects = 10;
+typedef UniqueSet<Map>* MapSet;
+
+// The main datastructure used during check elimination, which stores a
+// set of known maps for each object.
+class HCheckTable {
+ public:
+  explicit HCheckTable(Zone* zone) : zone_(zone) {
+    Kill();
+    redundant_ = 0;
+    narrowed_ = 0;
+    empty_ = 0;
+    removed_ = 0;
+    compares_true_ = 0;
+    compares_false_ = 0;
+    transitions_ = 0;
+    loads_ = 0;
+  }
+
+  void ReduceCheckMaps(HCheckMaps* instr) {
+    HValue* object = instr->value()->ActualValue();
+    int index = Find(object);
+    if (index >= 0) {
+      // entry found;
+      MapSet a = known_maps_[index];
+      MapSet i = instr->map_set().Copy(zone_);
+      if (a->IsSubset(i)) {
+        // The first check is more strict; the second is redundant.
+        if (checks_[index] != NULL) {
+          instr->DeleteAndReplaceWith(checks_[index]);
+          redundant_++;
+        } else {
+          instr->DeleteAndReplaceWith(instr->value());
+          removed_++;
+        }
+        return;
+      }
+      i = i->Intersect(a, zone_);
+      if (i->size() == 0) {
+        // Intersection is empty; probably megamorphic, which is likely to
+        // deopt anyway, so just leave things as they are.
+        empty_++;
+      } else {
+        // TODO(titzer): replace the first check with a more strict check.
+        narrowed_++;
+      }
+    } else {
+      // No entry; insert a new one.
+      Insert(object, instr, instr->map_set().Copy(zone_));
+    }
+  }
+
+  void ReduceCheckValue(HCheckValue* instr) {
+    // Canonicalize HCheckValues; they might have their values load-eliminated.
+    HValue* value = instr->Canonicalize();
+    if (value == NULL) {
+      instr->DeleteAndReplaceWith(instr->value());
+      removed_++;
+    } else if (value != instr) {
+      instr->DeleteAndReplaceWith(value);
+      redundant_++;
+    }
+  }
+
+  void ReduceLoadNamedField(HLoadNamedField* instr) {
+    // Reduce a load of the map field when it is known to be a constant.
+    if (!IsMapAccess(instr->access())) return;
+
+    HValue* object = instr->object()->ActualValue();
+    MapSet maps = FindMaps(object);
+    if (maps == NULL || maps->size() != 1) return;  // Not a constant.
+
+    Unique<Map> map = maps->at(0);
+    HConstant* constant = HConstant::CreateAndInsertBefore(
+        instr->block()->graph()->zone(), map, true, instr);
+    instr->DeleteAndReplaceWith(constant);
+    loads_++;
+  }
+
+  void ReduceCheckMapValue(HCheckMapValue* instr) {
+    if (!instr->map()->IsConstant()) return;  // Nothing to learn.
+
+    HValue* object = instr->value()->ActualValue();
+    // Match a HCheckMapValue(object, HConstant(map))
+    Unique<Map> map = MapConstant(instr->map());
+    MapSet maps = FindMaps(object);
+    if (maps != NULL) {
+      if (maps->Contains(map)) {
+        if (maps->size() == 1) {
+          // Object is known to have exactly this map.
+          instr->DeleteAndReplaceWith(NULL);
+          removed_++;
+        } else {
+          // Only one map survives the check.
+          maps->Clear();
+          maps->Add(map, zone_);
+        }
+      }
+    } else {
+      // No prior information.
+      Insert(object, map);
+    }
+  }
+
+  void ReduceStoreNamedField(HStoreNamedField* instr) {
+    HValue* object = instr->object()->ActualValue();
+    if (instr->has_transition()) {
+      // This store transitions the object to a new map.
+      Kill(object);
+      Insert(object, MapConstant(instr->transition()));
+    } else if (IsMapAccess(instr->access())) {
+      // This is a store directly to the map field of the object.
+      Kill(object);
+      if (!instr->value()->IsConstant()) return;
+      Insert(object, MapConstant(instr->value()));
+    } else if (instr->CheckGVNFlag(kChangesMaps)) {
+      // This store indirectly changes the map of the object.
+      Kill(instr->object());
+      UNREACHABLE();
+    }
+  }
+
+  void ReduceCompareMap(HCompareMap* instr) {
+    MapSet maps = FindMaps(instr->value()->ActualValue());
+    if (maps == NULL) return;
+    if (maps->Contains(instr->map())) {
+      // TODO(titzer): replace with goto true branch
+      if (maps->size() == 1) compares_true_++;
+    } else {
+      // TODO(titzer): replace with goto false branch
+      compares_false_++;
+    }
+  }
+
+  void ReduceTransitionElementsKind(HTransitionElementsKind* instr) {
+    MapSet maps = FindMaps(instr->object()->ActualValue());
+    // Can only learn more about an object that already has a known set of maps.
+    if (maps == NULL) return;
+    if (maps->Contains(instr->original_map())) {
+      // If the object has the original map, it will be transitioned.
+      maps->Remove(instr->original_map());
+      maps->Add(instr->transitioned_map(), zone_);
+    } else {
+      // Object does not have the given map, thus the transition is redundant.
+      instr->DeleteAndReplaceWith(instr->object());
+      transitions_++;
+    }
+  }
+
+  // Kill everything in the table.
+  void Kill() {
+    memset(objects_, 0, sizeof(objects_));
+  }
+
+  // Kill everything in the table that may alias {object}.
+  void Kill(HValue* object) {
+    for (int i = 0; i < kMaxTrackedObjects; i++) {
+      if (objects_[i] == NULL) continue;
+      if (aliasing_.MayAlias(objects_[i], object)) objects_[i] = NULL;
+    }
+    ASSERT(Find(object) < 0);
+  }
+
+  void Print() {
+    for (int i = 0; i < kMaxTrackedObjects; i++) {
+      if (objects_[i] == NULL) continue;
+      PrintF("  checkmaps-table @%d: object #%d ", i, objects_[i]->id());
+      if (checks_[i] != NULL) {
+        PrintF("check #%d ", checks_[i]->id());
+      }
+      MapSet list = known_maps_[i];
+      PrintF("%d maps { ", list->size());
+      for (int j = 0; j < list->size(); j++) {
+        if (j > 0) PrintF(", ");
+        PrintF("%" V8PRIxPTR, list->at(j).Hashcode());
+      }
+      PrintF(" }\n");
+    }
+  }
+
+  void PrintStats() {
+    if (redundant_ > 0)      PrintF("  redundant   = %2d\n", redundant_);
+    if (removed_ > 0)        PrintF("  removed     = %2d\n", removed_);
+    if (narrowed_ > 0)       PrintF("  narrowed    = %2d\n", narrowed_);
+    if (loads_ > 0)          PrintF("  loads       = %2d\n", loads_);
+    if (empty_ > 0)          PrintF("  empty       = %2d\n", empty_);
+    if (compares_true_ > 0)  PrintF("  cmp_true    = %2d\n", compares_true_);
+    if (compares_false_ > 0) PrintF("  cmp_false   = %2d\n", compares_false_);
+    if (transitions_ > 0)    PrintF("  transitions = %2d\n", transitions_);
+  }
+
+ private:
+  int Find(HValue* object) {
+    for (int i = 0; i < kMaxTrackedObjects; i++) {
+      if (objects_[i] == NULL) continue;
+      if (aliasing_.MustAlias(objects_[i], object)) return i;
+    }
+    return -1;
+  }
+
+  MapSet FindMaps(HValue* object) {
+    int index = Find(object);
+    return index < 0 ? NULL : known_maps_[index];
+  }
+
+  void Insert(HValue* object, Unique<Map> map) {
+    MapSet list = new(zone_) UniqueSet<Map>();
+    list->Add(map, zone_);
+    Insert(object, NULL, list);
+  }
+
+  void Insert(HValue* object, HCheckMaps* check, MapSet maps) {
+    for (int i = 0; i < kMaxTrackedObjects; i++) {
+      // TODO(titzer): drop old entries instead of disallowing new ones.
+      if (objects_[i] == NULL) {
+        objects_[i] = object;
+        checks_[i] = check;
+        known_maps_[i] = maps;
+        return;
+      }
+    }
+  }
+
+  bool IsMapAccess(HObjectAccess access) {
+    return access.IsInobject() && access.offset() == JSObject::kMapOffset;
+  }
+
+  Unique<Map> MapConstant(HValue* value) {
+    return Unique<Map>::cast(HConstant::cast(value)->GetUnique());
+  }
+
+  Zone* zone_;
+  HValue* objects_[kMaxTrackedObjects];
+  HValue* checks_[kMaxTrackedObjects];
+  MapSet known_maps_[kMaxTrackedObjects];
+  HAliasAnalyzer aliasing_;
+  int redundant_;
+  int removed_;
+  int narrowed_;
+  int loads_;
+  int empty_;
+  int compares_true_;
+  int compares_false_;
+  int transitions_;
+};
+
+
+void HCheckEliminationPhase::Run() {
+  for (int i = 0; i < graph()->blocks()->length(); i++) {
+    EliminateLocalChecks(graph()->blocks()->at(i));
+  }
+}
+
+
+// For code de-uglification.
+#define TRACE(x) if (FLAG_trace_check_elimination) PrintF x
+
+
+// Eliminate checks local to a block.
+void HCheckEliminationPhase::EliminateLocalChecks(HBasicBlock* block) {
+  HCheckTable table(zone());
+  TRACE(("-- check-elim B%d ------------------------------------------------\n",
+         block->block_id()));
+
+  for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
+    bool changed = false;
+    HInstruction* instr = it.Current();
+
+    switch (instr->opcode()) {
+      case HValue::kCheckMaps: {
+        table.ReduceCheckMaps(HCheckMaps::cast(instr));
+        changed = true;
+        break;
+      }
+      case HValue::kCheckValue: {
+        table.ReduceCheckValue(HCheckValue::cast(instr));
+        changed = true;
+        break;
+      }
+      case HValue::kLoadNamedField: {
+        table.ReduceLoadNamedField(HLoadNamedField::cast(instr));
+        changed = true;
+        break;
+      }
+      case HValue::kStoreNamedField: {
+        table.ReduceStoreNamedField(HStoreNamedField::cast(instr));
+        changed = true;
+        break;
+      }
+      case HValue::kCompareMap: {
+        table.ReduceCompareMap(HCompareMap::cast(instr));
+        changed = true;
+        break;
+      }
+      case HValue::kTransitionElementsKind: {
+        table.ReduceTransitionElementsKind(
+            HTransitionElementsKind::cast(instr));
+        changed = true;
+        break;
+      }
+      case HValue::kCheckMapValue: {
+        table.ReduceCheckMapValue(HCheckMapValue::cast(instr));
+        changed = true;
+        break;
+      }
+      default: {
+        // If the instruction changes maps uncontrollably, kill the whole town.
+        if (instr->CheckGVNFlag(kChangesMaps)) {
+          table.Kill();
+          changed = true;
+        }
+      }
+      // Improvements possible:
+      // - eliminate HCheckSmi and HCheckHeapObject
+    }
+
+    if (changed && FLAG_trace_check_elimination) table.Print();
+  }
+
+  if (FLAG_trace_check_elimination) table.PrintStats();
+}
+
+
+} }  // namespace v8::internal
diff --git a/src/hydrogen-check-elimination.h b/src/hydrogen-check-elimination.h
new file mode 100644
index 0000000..fa01964
--- /dev/null
+++ b/src/hydrogen-check-elimination.h
@@ -0,0 +1,52 @@
+// 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.
+
+#ifndef V8_HYDROGEN_CHECK_ELIMINATION_H_
+#define V8_HYDROGEN_CHECK_ELIMINATION_H_
+
+#include "hydrogen.h"
+
+namespace v8 {
+namespace internal {
+
+
+// Remove CheckMaps instructions through flow- and branch-sensitive analysis.
+class HCheckEliminationPhase : public HPhase {
+ public:
+  explicit HCheckEliminationPhase(HGraph* graph)
+      : HPhase("H_Check Elimination", graph) { }
+
+  void Run();
+
+ private:
+  void EliminateLocalChecks(HBasicBlock* block);
+};
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_HYDROGEN_CHECK_ELIMINATION_H_
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 6125ca2..a66b6ab 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -2341,18 +2341,27 @@
 }
 
 
+static void ReplayEnvironmentNested(const ZoneList<HValue*>* values,
+                                    HCapturedObject* other) {
+  for (int i = 0; i < values->length(); ++i) {
+    HValue* value = values->at(i);
+    if (value->IsCapturedObject()) {
+      if (HCapturedObject::cast(value)->capture_id() == other->capture_id()) {
+        values->at(i) = other;
+      } else {
+        ReplayEnvironmentNested(HCapturedObject::cast(value)->values(), other);
+      }
+    }
+  }
+}
+
+
 // Replay captured objects by replacing all captured objects with the
 // same capture id in the current and all outer environments.
 void HCapturedObject::ReplayEnvironment(HEnvironment* env) {
   ASSERT(env != NULL);
   while (env != NULL) {
-    for (int i = 0; i < env->length(); ++i) {
-      HValue* value = env->values()->at(i);
-      if (value->IsCapturedObject() &&
-          HCapturedObject::cast(value)->capture_id() == this->capture_id()) {
-        env->SetValueAt(i, this);
-      }
-    }
+    ReplayEnvironmentNested(env->values(), this);
     env = env->outer();
   }
 }
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 3b6822d..97e1b0e 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -3287,6 +3287,17 @@
     return new_constant;
   }
 
+  static HConstant* CreateAndInsertBefore(Zone* zone,
+                                          Unique<Object> unique,
+                                          bool is_not_in_new_space,
+                                          HInstruction* instruction) {
+    HConstant* new_constant = new(zone) HConstant(unique,
+        Representation::Tagged(), HType::Tagged(), false, is_not_in_new_space,
+        false, false);
+    new_constant->InsertBefore(instruction);
+    return new_constant;
+  }
+
   Handle<Object> handle(Isolate* isolate) {
     if (object_.handle().is_null()) {
       // Default arguments to is_not_in_new_space depend on this heap number
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index fe59b54..57ea173 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -36,6 +36,7 @@
 #include "hydrogen-bce.h"
 #include "hydrogen-bch.h"
 #include "hydrogen-canonicalize.h"
+#include "hydrogen-check-elimination.h"
 #include "hydrogen-dce.h"
 #include "hydrogen-dehoist.h"
 #include "hydrogen-deoptimizing-mark.h"
@@ -3122,9 +3123,8 @@
     return false;
   }
 
-  // Remove dead code and phis
+  if (FLAG_check_elimination) Run<HCheckEliminationPhase>();
   if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
-
   if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>();
 
   if (FLAG_load_elimination) Run<HLoadEliminationPhase>();
@@ -3162,12 +3162,8 @@
   // Eliminate redundant stack checks on backwards branches.
   Run<HStackCheckEliminationPhase>();
 
-  if (FLAG_array_bounds_checks_elimination) {
-    Run<HBoundsCheckEliminationPhase>();
-  }
-  if (FLAG_array_bounds_checks_hoisting) {
-    Run<HBoundsCheckHoistingPhase>();
-  }
+  if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>();
+  if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>();
   if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
   if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
 
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index d339da9..eb26477 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -462,51 +462,48 @@
                                 bool restore_context) {
   // ----------- S t a t e -------------
   //  -- esp[0]              : return address
-  //  -- esp[4]              : context
-  //  -- esp[8]              : object passing the type check
-  //                           (last fast api call extra argument,
-  //                            set by CheckPrototypes)
-  //  -- esp[12]             : api function
-  //                           (first fast api call extra argument)
-  //  -- esp[16]             : api call data
-  //  -- esp[20]             : isolate
-  //  -- esp[24]             : ReturnValue default value
-  //  -- esp[28]             : ReturnValue
+  //  -- esp[4] - esp[28]    : FunctionCallbackInfo, incl.
+  //                         :  object passing the type check
+  //                            (set by CheckPrototypes)
   //  -- esp[32]             : last argument
   //  -- ...
   //  -- esp[(argc + 7) * 4] : first argument
   //  -- esp[(argc + 8) * 4] : receiver
   // -----------------------------------
 
+  typedef FunctionCallbackArguments FCA;
+  const int kArgs = kFastApiCallArguments;
   // Save calling context.
-  __ mov(Operand(esp, kPointerSize), esi);
+  __ mov(Operand(esp, (kArgs + FCA::kContextSaveIndex) * kPointerSize), esi);
 
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(edi, function);
   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
 
-  // Pass the additional arguments.
-  __ mov(Operand(esp, 3 * kPointerSize), edi);
+  // Construct the FunctionCallbackInfo.
+  __ mov(Operand(esp, (kArgs + FCA::kCalleeIndex) * kPointerSize), edi);
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
     __ mov(ecx, api_call_info);
     __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
-    __ mov(Operand(esp, 4 * kPointerSize), ebx);
+    __ mov(Operand(esp, (kArgs + FCA::kDataIndex) * kPointerSize), ebx);
   } else {
-    __ mov(Operand(esp, 4 * kPointerSize), Immediate(call_data));
+    __ mov(Operand(esp, (kArgs + FCA::kDataIndex) * kPointerSize),
+           Immediate(call_data));
   }
-  __ mov(Operand(esp, 5 * kPointerSize),
+  __ mov(Operand(esp, (kArgs + FCA::kIsolateIndex) * kPointerSize),
          Immediate(reinterpret_cast<int>(masm->isolate())));
-  __ mov(Operand(esp, 6 * kPointerSize),
+  __ mov(Operand(esp, (kArgs + FCA::kReturnValueOffset) * kPointerSize),
          masm->isolate()->factory()->undefined_value());
-  __ mov(Operand(esp, 7 * kPointerSize),
-         masm->isolate()->factory()->undefined_value());
+  __ mov(
+      Operand(esp, (kArgs + FCA::kReturnValueDefaultValueIndex) * kPointerSize),
+      masm->isolate()->factory()->undefined_value());
 
   // Prepare arguments.
-  STATIC_ASSERT(kFastApiCallArguments == 7);
-  __ lea(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
+  STATIC_ASSERT(kArgs == 7);
+  __ lea(eax, Operand(esp, kArgs * kPointerSize));
 
 
   // API function gets reference to the v8::Arguments. If CPU profiler
@@ -539,13 +536,14 @@
 
   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
-  Operand context_restore_operand(ebp, 2 * kPointerSize);
+  Operand context_restore_operand(
+      ebp, (kArgs + 1 + FCA::kContextSaveIndex) * kPointerSize);
   Operand return_value_operand(
-      ebp, (kFastApiCallArguments + 1) * kPointerSize);
+      ebp, (kArgs + 1 + FCA::kReturnValueOffset) * kPointerSize);
   __ CallApiFunctionAndReturn(function_address,
                               thunk_address,
                               ApiParameterOperand(1),
-                              argc + kFastApiCallArguments + 1,
+                              argc + kArgs + 1,
                               return_value_operand,
                               restore_context ?
                                   &context_restore_operand : NULL);
diff --git a/src/isolate.cc b/src/isolate.cc
index 5a80d3d..3e5d2b9 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1792,10 +1792,6 @@
       // TODO(bmeurer) Initialized lazily because it depends on flags; can
       // be fixed once the default isolate cleanup is done.
       random_number_generator_(NULL),
-      // TODO(rmcilroy) Currently setting this based on
-      // FLAG_force_memory_constrained in Isolate::Init; move to here when
-      // isolate cleanup is done
-      is_memory_constrained_(false),
       has_fatal_error_(false),
       use_crankshaft_(true),
       initialized_from_snapshot_(false),
@@ -2157,8 +2153,6 @@
   TRACE_ISOLATE(init);
 
   stress_deopt_count_ = FLAG_deopt_every_n_times;
-  if (FLAG_force_memory_constrained.has_value)
-    is_memory_constrained_ = FLAG_force_memory_constrained.value;
 
   has_fatal_error_ = false;
 
diff --git a/src/isolate.h b/src/isolate.h
index cfea075..420cf03 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1132,13 +1132,6 @@
   // Given an address occupied by a live code object, return that object.
   Object* FindCodeObject(Address a);
 
-  bool is_memory_constrained() const {
-    return is_memory_constrained_;
-  }
-  void set_is_memory_constrained(bool value) {
-    is_memory_constrained_ = value;
-  }
-
  private:
   Isolate();
 
@@ -1311,7 +1304,6 @@
   unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
   CodeStubInterfaceDescriptor* code_stub_interface_descriptors_;
   RandomNumberGenerator* random_number_generator_;
-  bool is_memory_constrained_;
 
   // True if fatal error has been signaled for this isolate.
   bool has_fatal_error_;
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index e0cf1b6..7177c70 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -832,27 +832,25 @@
                                       int argc,
                                       bool restore_context) {
   // ----------- S t a t e -------------
-  //  -- sp[0]              : context
-  //  -- sp[4]              : holder (set by CheckPrototypes)
-  //  -- sp[8]              : callee JS function
-  //  -- sp[12]             : call data
-  //  -- sp[16]             : isolate
-  //  -- sp[20]             : ReturnValue default value
-  //  -- sp[24]             : ReturnValue
+  //  -- sp[0] - sp[24]     : FunctionCallbackInfo, incl.
+  //                        :  holder (set by CheckPrototypes)
   //  -- sp[28]             : last JS argument
   //  -- ...
   //  -- sp[(argc + 6) * 4] : first JS argument
   //  -- sp[(argc + 7) * 4] : receiver
   // -----------------------------------
+  typedef FunctionCallbackArguments FCA;
+  const int kArgs = kFastApiCallArguments;
   // Save calling context.
-  __ sw(cp, MemOperand(sp));
+  __ sw(cp,
+        MemOperand(sp, (kArgs - 1 + FCA::kContextSaveIndex) * kPointerSize));
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(t1, function);
   __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
-  __ sw(t1, MemOperand(sp, 2 * kPointerSize));
+  __ sw(t1, MemOperand(sp, (kArgs - 1 + FCA::kCalleeIndex) * kPointerSize));
 
-  // Pass the additional arguments.
+  // Construct the FunctionCallbackInfo.
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
@@ -862,17 +860,20 @@
     __ li(t2, call_data);
   }
   // Store call data.
-  __ sw(t2, MemOperand(sp, 3 * kPointerSize));
+  __ sw(t2, MemOperand(sp, (kArgs - 1 + FCA::kDataIndex) * kPointerSize));
   // Store isolate.
   __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate())));
-  __ sw(t3, MemOperand(sp, 4 * kPointerSize));
+  __ sw(t3, MemOperand(sp, (kArgs - 1 + FCA::kIsolateIndex) * kPointerSize));
   // Store ReturnValue default and ReturnValue.
   __ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
-  __ sw(t1, MemOperand(sp, 5 * kPointerSize));
-  __ sw(t1, MemOperand(sp, 6 * kPointerSize));
+  __ sw(t1,
+        MemOperand(sp, (kArgs - 1 + FCA::kReturnValueOffset) * kPointerSize));
+  __ sw(t1,
+        MemOperand(sp,
+            (kArgs - 1 + FCA::kReturnValueDefaultValueIndex) * kPointerSize));
 
   // Prepare arguments.
-  __ Addu(a2, sp, Operand((kFastApiCallArguments - 1) * kPointerSize));
+  __ Addu(a2, sp, Operand((kArgs - 1) * kPointerSize));
 
   // Allocate the v8::Arguments structure in the arguments' space since
   // it's not controlled by GC.
@@ -896,7 +897,7 @@
   // v8::Arguments::is_construct_call = 0
   __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
 
-  const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
+  const int kStackUnwindSpace = argc + kArgs + 1;
   Address function_address = v8::ToCData<Address>(api_call_info->callback());
   ApiFunction fun(function_address);
   ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
@@ -912,9 +913,9 @@
 
   AllowExternalCallThatCantCauseGC scope(masm);
   MemOperand context_restore_operand(
-      fp, 2 * kPointerSize);
+      fp, (kArgs + 1 + FCA::kContextSaveIndex) * kPointerSize);
   MemOperand return_value_operand(
-      fp, (kFastApiCallArguments + 1) * kPointerSize);
+      fp, (kArgs + 1 + FCA::kReturnValueOffset) * kPointerSize);
   __ CallApiFunctionAndReturn(ref,
                               function_address,
                               thunk_ref,
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index df15ee2..797557d 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -100,6 +100,48 @@
 }
 
 
+uint64_t OS::TotalPhysicalMemory() {
+#if V8_OS_MACOSX
+  int mib[2];
+  mib[0] = CTL_HW;
+  mib[1] = HW_MEMSIZE;
+  int64_t size = 0;
+  size_t len = sizeof(size);
+  if (sysctl(mib, 2, &size, &len, NULL, 0) != 0) {
+    UNREACHABLE();
+    return 0;
+  }
+  return static_cast<uint64_t>(size);
+#elif V8_OS_FREEBSD
+  int pages, page_size;
+  size_t size = sizeof(pages);
+  sysctlbyname("vm.stats.vm.v_page_count", &pages, &size, NULL, 0);
+  sysctlbyname("vm.stats.vm.v_page_size", &page_size, &size, NULL, 0);
+  if (pages == -1 || page_size == -1) {
+    UNREACHABLE();
+    return 0;
+  }
+  return static_cast<uint64_t>(pages) * page_size;
+#elif V8_OS_CYGWIN
+  MEMORYSTATUS memory_info;
+  memory_info.dwLength = sizeof(memory_info);
+  if (!GlobalMemoryStatus(&memory_info)) {
+    UNREACHABLE();
+    return 0;
+  }
+  return static_cast<uint64_t>(memory_info.dwTotalPhys);
+#else
+  intptr_t pages = sysconf(_SC_PHYS_PAGES);
+  intptr_t page_size = sysconf(_SC_PAGESIZE);
+  if (pages == -1 || page_size == -1) {
+    UNREACHABLE();
+    return 0;
+  }
+  return static_cast<uint64_t>(pages) * page_size;
+#endif
+}
+
+
 int OS::ActivationFrameAlignment() {
 #if V8_TARGET_ARCH_ARM
   // On EABI ARM targets this is required for fp correctness in the
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 41a4f14..3283dfa 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1271,6 +1271,18 @@
 }
 
 
+uint64_t OS::TotalPhysicalMemory() {
+  MEMORYSTATUSEX memory_info;
+  memory_info.dwLength = sizeof(memory_info);
+  if (!GlobalMemoryStatusEx(&memory_info)) {
+    UNREACHABLE();
+    return 0;
+  }
+
+  return static_cast<uint64_t>(memory_info.ullTotalPhys);
+}
+
+
 #else  // __MINGW32__
 void OS::LogSharedLibraryAddresses(Isolate* isolate) { }
 void OS::SignalCodeMovingGC() { }
diff --git a/src/platform.h b/src/platform.h
index 527de16..8e524ae 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -302,6 +302,9 @@
   // positions indicated by the members of the CpuFeature enum from globals.h
   static uint64_t CpuFeaturesImpliedByPlatform();
 
+  // The total amount of physical memory available on the current system.
+  static uint64_t TotalPhysicalMemory();
+
   // Maximum size of the virtual memory.  0 means there is no artificial
   // limit.
   static intptr_t MaxVirtualMemory();
diff --git a/src/runtime.cc b/src/runtime.cc
index f097681..38d1d8d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -7952,21 +7952,18 @@
   // Allocate the elements if needed.
   if (length > 0) {
     // Allocate the fixed array.
-    Object* obj;
-    { MaybeObject* maybe_obj = isolate->heap()->AllocateRawFixedArray(length);
-      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+    FixedArray* array;
+    { MaybeObject* maybe_obj =
+          isolate->heap()->AllocateUninitializedFixedArray(length);
+      if (!maybe_obj->To(&array)) return maybe_obj;
     }
 
     DisallowHeapAllocation no_gc;
-    FixedArray* array = reinterpret_cast<FixedArray*>(obj);
-    array->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
-    array->set_length(length);
-
     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
     for (int i = 0; i < length; i++) {
       array->set(i, *--parameters, mode);
     }
-    JSObject::cast(result)->set_elements(FixedArray::cast(obj));
+    JSObject::cast(result)->set_elements(array);
   }
   return result;
 }
diff --git a/src/unique.h b/src/unique.h
index fdb7016..a93b046 100644
--- a/src/unique.h
+++ b/src/unique.h
@@ -120,6 +120,10 @@
     return handle_;
   }
 
+  template <class S> static Unique<T> cast(Unique<S> that) {
+    return Unique<T>(that.raw_address_, Handle<T>::cast(that.handle_));
+  }
+
   inline bool IsInitialized() const {
     return raw_address_ != NULL || handle_.is_null();
   }
@@ -169,6 +173,17 @@
     array_[size_++] = uniq;
   }
 
+  // Remove an element from this set. Mutates this set. O(|this|)
+  void Remove(Unique<T> uniq) {
+    for (int i = 0; i < size_; i++) {
+      if (array_[i] == uniq) {
+        while (++i < size_) array_[i - 1] = array_[i];
+        size_--;
+        return;
+      }
+    }
+  }
+
   // Compare this set against another set. O(|this|).
   bool Equals(UniqueSet<T>* that) const {
     if (that->size_ != this->size_) return false;
@@ -273,6 +288,10 @@
     return copy;
   }
 
+  void Clear() {
+    size_ = 0;
+  }
+
   inline int size() const {
     return size_;
   }
diff --git a/src/version.cc b/src/version.cc
index d4856ae..e310df0 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     22
-#define BUILD_NUMBER      2
-#define PATCH_LEVEL       0
+#define BUILD_NUMBER      3
+#define PATCH_LEVEL       2
 // 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/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index af8e55f..ef52cb4 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -447,49 +447,45 @@
                                 bool restore_context) {
   // ----------- S t a t e -------------
   //  -- rsp[0]              : return address
-  //  -- rsp[8]              : context save
-  //  -- rsp[16]             : object passing the type check
-  //                           (last fast api call extra argument,
-  //                            set by CheckPrototypes)
-  //  -- rsp[24]             : api function
-  //                           (first fast api call extra argument)
-  //  -- rsp[32]             : api call data
-  //  -- rsp[40]             : isolate
-  //  -- rsp[48]             : ReturnValue default value
-  //  -- rsp[56]             : ReturnValue
-  //
+  //  -- rsp[8] - rsp[58]    : FunctionCallbackInfo, incl.
+  //                         :  object passing the type check
+  //                            (set by CheckPrototypes)
   //  -- rsp[64]             : last argument
   //  -- ...
   //  -- rsp[(argc + 7) * 8] : first argument
   //  -- rsp[(argc + 8) * 8] : receiver
   // -----------------------------------
-  int api_call_argc = argc + kFastApiCallArguments;
-  StackArgumentsAccessor args(rsp, api_call_argc);
+  typedef FunctionCallbackArguments FCA;
+  StackArgumentsAccessor args(rsp, argc + kFastApiCallArguments);
 
   // Save calling context.
-  __ movq(args.GetArgumentOperand(api_call_argc), rsi);
+  __ movq(args.GetArgumentOperand(argc + 1 - FCA::kContextSaveIndex), rsi);
 
   // Get the function and setup the context.
   Handle<JSFunction> function = optimization.constant_function();
   __ LoadHeapObject(rdi, function);
   __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
-  // Pass the additional arguments.
-  __ movq(args.GetArgumentOperand(api_call_argc - 2), rdi);
+  // Construct the FunctionCallbackInfo on the stack.
+  __ movq(args.GetArgumentOperand(argc + 1 - FCA::kCalleeIndex), rdi);
   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
   Handle<Object> call_data(api_call_info->data(), masm->isolate());
   if (masm->isolate()->heap()->InNewSpace(*call_data)) {
     __ Move(rcx, api_call_info);
     __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
-    __ movq(args.GetArgumentOperand(api_call_argc - 3), rbx);
+    __ movq(args.GetArgumentOperand(argc + 1 - FCA::kDataIndex), rbx);
   } else {
-    __ Move(args.GetArgumentOperand(api_call_argc - 3), call_data);
+    __ Move(args.GetArgumentOperand(argc + 1 - FCA::kDataIndex), call_data);
   }
   __ movq(kScratchRegister,
           ExternalReference::isolate_address(masm->isolate()));
-  __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
+  __ movq(args.GetArgumentOperand(argc + 1 - FCA::kIsolateIndex),
+          kScratchRegister);
   __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
-  __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
-  __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister);
+  __ movq(
+      args.GetArgumentOperand(argc + 1 - FCA::kReturnValueDefaultValueIndex),
+      kScratchRegister);
+  __ movq(args.GetArgumentOperand(argc + 1 - FCA::kReturnValueOffset),
+          kScratchRegister);
 
   // Prepare arguments.
   STATIC_ASSERT(kFastApiCallArguments == 7);
@@ -524,16 +520,18 @@
 
   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
 
-  Operand context_restore_operand(rbp, 2 * kPointerSize);
+  Operand context_restore_operand(
+      rbp, (kFastApiCallArguments + 1 + FCA::kContextSaveIndex) * kPointerSize);
   Operand return_value_operand(
-      rbp, (kFastApiCallArguments + 1) * kPointerSize);
-  __ CallApiFunctionAndReturn(function_address,
-                              thunk_address,
-                              callback_arg,
-                              api_call_argc + 1,
-                              return_value_operand,
-                              restore_context ?
-                                  &context_restore_operand : NULL);
+      rbp,
+      (kFastApiCallArguments + 1 + FCA::kReturnValueOffset) * kPointerSize);
+  __ CallApiFunctionAndReturn(
+      function_address,
+      thunk_address,
+      callback_arg,
+      argc + kFastApiCallArguments + 1,
+      return_value_operand,
+      restore_context ? &context_restore_operand : NULL);
 }
 
 
diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc
index c3148ff..df4937e 100644
--- a/test/cctest/test-accessors.cc
+++ b/test/cctest/test-accessors.cc
@@ -354,7 +354,8 @@
 
 THREADED_TEST(EmptyResult) {
   LocalContext context;
-  v8::HandleScope scope(context->GetIsolate());
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
   obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data"));
   v8::Handle<v8::Object> inst = obj->NewInstance();
@@ -362,7 +363,7 @@
   Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
   for (int i = 0; i < 10; i++) {
     Local<Value> result = scr->Run();
-    CHECK(result == v8::Undefined());
+    CHECK(result == v8::Undefined(isolate));
   }
 }
 
@@ -370,7 +371,8 @@
 THREADED_TEST(NoReuseRegress) {
   // Check that the IC generated for the one test doesn't get reused
   // for the other.
-  v8::HandleScope scope(CcTest::isolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
   {
     v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
     obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data"));
@@ -380,7 +382,7 @@
     Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
     for (int i = 0; i < 2; i++) {
       Local<Value> result = scr->Run();
-      CHECK(result == v8::Undefined());
+      CHECK(result == v8::Undefined(isolate));
     }
   }
   {
@@ -405,14 +407,14 @@
     Local<String> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
-  v8::ThrowException(v8_str("g"));
+  info.GetIsolate()->ThrowException(v8_str("g"));
 }
 
 
 static void ThrowingSetAccessor(Local<String> name,
                                 Local<Value> value,
                                 const v8::PropertyCallbackInfo<void>& info) {
-  v8::ThrowException(value);
+  info.GetIsolate()->ThrowException(value);
 }
 
 
@@ -505,7 +507,7 @@
 static void AllocateHandles(Local<String> name,
                             const v8::PropertyCallbackInfo<v8::Value>& info) {
   for (int i = 0; i < i::kHandleBlockSize + 1; i++) {
-    v8::Local<v8::Value>::New(name);
+    v8::Local<v8::Value>::New(info.GetIsolate(), name);
   }
   info.GetReturnValue().Set(v8::Integer::New(100));
 }
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index cfebeff..7a2f9de 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -204,7 +204,7 @@
   CHECK(!local_env.IsEmpty());
   local_env->Enter();
 
-  v8::Handle<v8::Primitive> undef = v8::Undefined();
+  v8::Handle<v8::Primitive> undef = v8::Undefined(CcTest::isolate());
   CHECK(!undef.IsEmpty());
   CHECK(undef->IsUndefined());
 
@@ -391,8 +391,9 @@
 
 THREADED_TEST(HulIgennem) {
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
-  v8::Handle<v8::Primitive> undef = v8::Undefined();
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::Handle<v8::Primitive> undef = v8::Undefined(isolate);
   Local<String> undef_str = undef->ToString();
   char* value = i::NewArray<char>(undef_str->Utf8Length() + 1);
   undef_str->WriteUtf8(value);
@@ -403,7 +404,8 @@
 
 THREADED_TEST(Access) {
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
   Local<v8::Object> obj = v8::Object::New();
   Local<Value> foo_before = obj->Get(v8_str("foo"));
   CHECK(foo_before->IsUndefined());
@@ -1689,12 +1691,13 @@
 
 THREADED_TEST(ToNumber) {
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
   Local<String> str = v8_str("3.1415926");
   CHECK_EQ(3.1415926, str->NumberValue());
-  v8::Handle<v8::Boolean> t = v8::True();
+  v8::Handle<v8::Boolean> t = v8::True(isolate);
   CHECK_EQ(1.0, t->NumberValue());
-  v8::Handle<v8::Boolean> f = v8::False();
+  v8::Handle<v8::Boolean> f = v8::False(isolate);
   CHECK_EQ(0.0, f->NumberValue());
 }
 
@@ -1713,13 +1716,13 @@
 THREADED_TEST(Boolean) {
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
-  v8::Handle<v8::Boolean> t = v8::True();
+  v8::Handle<v8::Boolean> t = v8::True(CcTest::isolate());
   CHECK(t->Value());
-  v8::Handle<v8::Boolean> f = v8::False();
+  v8::Handle<v8::Boolean> f = v8::False(CcTest::isolate());
   CHECK(!f->Value());
-  v8::Handle<v8::Primitive> u = v8::Undefined();
+  v8::Handle<v8::Primitive> u = v8::Undefined(CcTest::isolate());
   CHECK(!u->BooleanValue());
-  v8::Handle<v8::Primitive> n = v8::Null();
+  v8::Handle<v8::Primitive> n = v8::Null(CcTest::isolate());
   CHECK(!n->BooleanValue());
   v8::Handle<String> str1 = v8_str("");
   CHECK(!str1->BooleanValue());
@@ -2451,7 +2454,7 @@
     Local<String> key,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
-  info.GetReturnValue().Set(v8::ThrowException(key));
+  info.GetReturnValue().Set(info.GetIsolate()->ThrowException(key));
 }
 
 
@@ -2459,7 +2462,7 @@
     Local<String> key,
     Local<Value>,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
-  v8::ThrowException(key);
+  info.GetIsolate()->ThrowException(key);
   info.GetReturnValue().SetUndefined();  // not the same as empty handle
 }
 
@@ -3254,7 +3257,7 @@
 THREADED_TEST(GlobalHandleUpcast) {
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
-  v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
+  v8::Local<String> local = v8::Local<String>::New(isolate, v8_str("str"));
   v8::Persistent<String> global_string(isolate, local);
   v8::Persistent<Value>& global_value =
       v8::Persistent<Value>::Cast(global_string);
@@ -3304,10 +3307,8 @@
 
 THREADED_TEST(LocalHandle) {
   v8::HandleScope scope(CcTest::isolate());
-  v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
-  CHECK_EQ(local->Length(), 3);
-
-  local = v8::Local<String>::New(CcTest::isolate(), v8_str("str"));
+  v8::Local<String> local =
+      v8::Local<String>::New(CcTest::isolate(), v8_str("str"));
   CHECK_EQ(local->Length(), 3);
 }
 
@@ -3762,15 +3763,16 @@
 
 TEST(MessageHandler3) {
   message_received = false;
-  v8::HandleScope scope(CcTest::isolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
   CHECK(!message_received);
   v8::V8::AddMessageListener(check_message_3);
   LocalContext context;
   v8::ScriptOrigin origin =
       v8::ScriptOrigin(v8_str("6.75"),
-                       v8::Integer::New(1),
-                       v8::Integer::New(2),
-                       v8::True());
+                       v8::Integer::New(1, isolate),
+                       v8::Integer::New(2, isolate),
+                       v8::True(isolate));
   v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
                                                   &origin);
   script->Run();
@@ -3790,15 +3792,16 @@
 
 TEST(MessageHandler4) {
   message_received = false;
-  v8::HandleScope scope(CcTest::isolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
   CHECK(!message_received);
   v8::V8::AddMessageListener(check_message_4);
   LocalContext context;
   v8::ScriptOrigin origin =
       v8::ScriptOrigin(v8_str("6.75"),
-                       v8::Integer::New(1),
-                       v8::Integer::New(2),
-                       v8::False());
+                       v8::Integer::New(1, isolate),
+                       v8::Integer::New(2, isolate),
+                       v8::False(isolate));
   v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
                                                   &origin);
   script->Run();
@@ -3826,15 +3829,16 @@
 
 TEST(MessageHandler5) {
   message_received = false;
-  v8::HandleScope scope(CcTest::isolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
   CHECK(!message_received);
   v8::V8::AddMessageListener(check_message_5a);
   LocalContext context;
   v8::ScriptOrigin origin =
       v8::ScriptOrigin(v8_str("6.75"),
-                       v8::Integer::New(1),
-                       v8::Integer::New(2),
-                       v8::True());
+                       v8::Integer::New(1, isolate),
+                       v8::Integer::New(2, isolate),
+                       v8::True(isolate));
   v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"),
                                                   &origin);
   script->Run();
@@ -3846,9 +3850,9 @@
   v8::V8::AddMessageListener(check_message_5b);
   origin =
       v8::ScriptOrigin(v8_str("6.75"),
-                       v8::Integer::New(1),
-                       v8::Integer::New(2),
-                       v8::False());
+                       v8::Integer::New(1, isolate),
+                       v8::Integer::New(2, isolate),
+                       v8::False(isolate));
   script = Script::Compile(v8_str("throw 'error'"),
                            &origin);
   script->Run();
@@ -4321,7 +4325,8 @@
 
 THREADED_TEST(ConversionException) {
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
   CompileRun(
     "function TestClass() { };"
     "TestClass.prototype.toString = function () { throw 'uncle?'; };"
@@ -4350,7 +4355,7 @@
   CHECK(to_int32_result.IsEmpty());
   CheckUncle(&try_catch);
 
-  Local<Value> to_object_result = v8::Undefined()->ToObject();
+  Local<Value> to_object_result = v8::Undefined(isolate)->ToObject();
   CHECK(to_object_result.IsEmpty());
   CHECK(try_catch.HasCaught());
   try_catch.Reset();
@@ -4375,7 +4380,7 @@
 
 void ThrowFromC(const v8::FunctionCallbackInfo<v8::Value>& args) {
   ApiTestFuzzer::Fuzz();
-  v8::ThrowException(v8_str("konto"));
+  args.GetIsolate()->ThrowException(v8_str("konto"));
 }
 
 
@@ -4658,7 +4663,7 @@
   int count = args[0]->Int32Value();
   int cInterval = args[2]->Int32Value();
   if (count == 0) {
-    v8::ThrowException(v8_str("FromC"));
+    args.GetIsolate()->ThrowException(v8_str("FromC"));
     return;
   } else {
     Local<v8::Object> global =
@@ -4798,7 +4803,7 @@
 void ThrowValue(const v8::FunctionCallbackInfo<v8::Value>& args) {
   ApiTestFuzzer::Fuzz();
   CHECK_EQ(1, args.Length());
-  v8::ThrowException(args[0]);
+  args.GetIsolate()->ThrowException(args[0]);
 }
 
 
@@ -4896,7 +4901,7 @@
     CHECK(try_catch.HasCaught());
     try_catch.ReThrow();
   } else {
-    v8::ThrowException(v8_str("back"));
+    CcTest::isolate()->ThrowException(v8_str("back"));
   }
 }
 
@@ -4976,8 +4981,8 @@
   CHECK(v8_num(0.0)->StrictEquals(v8_num(-0.0)));
   Local<Value> not_a_number = v8_num(i::OS::nan_value());
   CHECK(!not_a_number->StrictEquals(not_a_number));
-  CHECK(v8::False()->StrictEquals(v8::False()));
-  CHECK(!v8::False()->StrictEquals(v8::Undefined()));
+  CHECK(v8::False(isolate)->StrictEquals(v8::False(isolate)));
+  CHECK(!v8::False(isolate)->StrictEquals(v8::Undefined(isolate)));
 
   v8::Handle<v8::Object> obj = v8::Object::New();
   v8::Persistent<v8::Object> alias(isolate, obj);
@@ -4991,8 +4996,8 @@
   CHECK(!v8_num(1)->SameValue(v8_num(2)));
   CHECK(!v8_num(0.0)->SameValue(v8_num(-0.0)));
   CHECK(not_a_number->SameValue(not_a_number));
-  CHECK(v8::False()->SameValue(v8::False()));
-  CHECK(!v8::False()->SameValue(v8::Undefined()));
+  CHECK(v8::False(isolate)->SameValue(v8::False(isolate)));
+  CHECK(!v8::False(isolate)->SameValue(v8::Undefined(isolate)));
 }
 
 
@@ -6673,7 +6678,7 @@
 static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
                                              v8::Handle<Value> data) {
   CHECK(message->GetScriptResourceName()->IsUndefined());
-  CHECK_EQ(v8::Undefined(), message->GetScriptResourceName());
+  CHECK_EQ(v8::Undefined(CcTest::isolate()), message->GetScriptResourceName());
   message->GetLineNumber();
   message->GetSourceLine();
 }
@@ -6910,12 +6915,13 @@
 static void ArgumentsTestCallback(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   ApiTestFuzzer::Fuzz();
+  v8::Isolate* isolate = args.GetIsolate();
   CHECK_EQ(args_fun, args.Callee());
   CHECK_EQ(3, args.Length());
-  CHECK_EQ(v8::Integer::New(1), args[0]);
-  CHECK_EQ(v8::Integer::New(2), args[1]);
-  CHECK_EQ(v8::Integer::New(3), args[2]);
-  CHECK_EQ(v8::Undefined(), args[3]);
+  CHECK_EQ(v8::Integer::New(1, isolate), args[0]);
+  CHECK_EQ(v8::Integer::New(2, isolate), args[1]);
+  CHECK_EQ(v8::Integer::New(3, isolate), args[2]);
+  CHECK_EQ(v8::Undefined(isolate), args[3]);
   v8::HandleScope scope(args.GetIsolate());
   CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
 }
@@ -7163,7 +7169,8 @@
 
 
 THREADED_TEST(ObjectInstantiation) {
-  v8::HandleScope scope(CcTest::isolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
   templ->SetAccessor(v8_str("t"), PGetter2);
   LocalContext context;
@@ -7175,7 +7182,7 @@
     context->Global()->Set(v8_str("o2"), obj);
     v8::Handle<Value> value =
         Script::Compile(v8_str("o.__proto__ === o2.__proto__"))->Run();
-    CHECK_EQ(v8::True(), value);
+    CHECK_EQ(v8::True(isolate), value);
     context->Global()->Set(v8_str("o"), obj);
   }
 }
@@ -9794,7 +9801,8 @@
 
 THREADED_TEST(ConstructorForObject) {
   LocalContext context;
-  v8::HandleScope handle_scope(context->GetIsolate());
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope handle_scope(isolate);
 
   { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
     instance_template->SetCallAsFunctionHandler(ConstructorCallback);
@@ -9843,7 +9851,7 @@
     CHECK(value->IsBoolean());
     CHECK_EQ(true, value->BooleanValue());
 
-    Handle<Value> args3[] = { v8::True() };
+    Handle<Value> args3[] = { v8::True(isolate) };
     Local<Value> value_obj3 = instance->CallAsConstructor(1, args3);
     CHECK(value_obj3->IsObject());
     Local<Object> object3 = Local<Object>::Cast(value_obj3);
@@ -9853,7 +9861,7 @@
     CHECK_EQ(true, value->BooleanValue());
 
     // Call the Object's constructor with undefined.
-    Handle<Value> args4[] = { v8::Undefined() };
+    Handle<Value> args4[] = { v8::Undefined(isolate) };
     Local<Value> value_obj4 = instance->CallAsConstructor(1, args4);
     CHECK(value_obj4->IsObject());
     Local<Object> object4 = Local<Object>::Cast(value_obj4);
@@ -9862,7 +9870,7 @@
     CHECK(value->IsUndefined());
 
     // Call the Object's constructor with null.
-    Handle<Value> args5[] = { v8::Null() };
+    Handle<Value> args5[] = { v8::Null(isolate) };
     Local<Value> value_obj5 = instance->CallAsConstructor(1, args5);
     CHECK(value_obj5->IsObject());
     Local<Object> object5 = Local<Object>::Cast(value_obj5);
@@ -11259,7 +11267,7 @@
 
 void ThrowingDirectApiCallback(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
-  v8::ThrowException(v8_str("g"));
+  args.GetIsolate()->ThrowException(v8_str("g"));
 }
 
 
@@ -11327,7 +11335,7 @@
 void ThrowingDirectGetterCallback(
     Local<String> name,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
-  v8::ThrowException(v8_str("g"));
+  info.GetIsolate()->ThrowException(v8_str("g"));
 }
 
 
@@ -11938,7 +11946,7 @@
     info.GetReturnValue().Set(call_ic_function3);
   }
   if (interceptor_ic_exception_get_count == 20) {
-    v8::ThrowException(v8_num(42));
+    info.GetIsolate()->ThrowException(v8_num(42));
     return;
   }
 }
@@ -11983,7 +11991,7 @@
       const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (++interceptor_ic_exception_set_count > 20) {
-    v8::ThrowException(v8_num(42));
+    info.GetIsolate()->ThrowException(v8_num(42));
   }
 }
 
@@ -12055,7 +12063,7 @@
 static void ThrowingGetter(Local<String> name,
                            const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
-  ThrowException(Handle<Value>());
+  info.GetIsolate()->ThrowException(Handle<Value>());
   info.GetReturnValue().SetUndefined();
 }
 
@@ -12140,7 +12148,7 @@
 
 
 static void ThrowViaApi(Handle<Message> message, Handle<Value> data) {
-  if (--call_depth) ThrowException(v8_str("ThrowViaApi"));
+  if (--call_depth) CcTest::isolate()->ThrowException(v8_str("ThrowViaApi"));
 }
 
 
@@ -12499,13 +12507,14 @@
 
 
 static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  CHECK(v8::Locker::IsLocked(CcTest::isolate()));
+  v8::Isolate* isolate = args.GetIsolate();
+  CHECK(v8::Locker::IsLocked(isolate));
   ApiTestFuzzer::Fuzz();
-  v8::Unlocker unlocker(CcTest::isolate());
+  v8::Unlocker unlocker(isolate);
   const char* code = "throw 7;";
   {
-    v8::Locker nested_locker(CcTest::isolate());
-    v8::HandleScope scope(args.GetIsolate());
+    v8::Locker nested_locker(isolate);
+    v8::HandleScope scope(isolate);
     v8::Handle<Value> exception;
     { v8::TryCatch try_catch;
       v8::Handle<Value> value = CompileRun(code);
@@ -12514,9 +12523,9 @@
       // Make sure to wrap the exception in a new handle because
       // the handle returned from the TryCatch is destroyed
       // when the TryCatch is destroyed.
-      exception = Local<Value>::New(try_catch.Exception());
+      exception = Local<Value>::New(isolate, try_catch.Exception());
     }
-    v8::ThrowException(exception);
+    args.GetIsolate()->ThrowException(exception);
   }
 }
 
@@ -13732,11 +13741,12 @@
 
 THREADED_TEST(DisableAccessChecksWhileConfiguring) {
   LocalContext context;
-  v8::HandleScope scope(context->GetIsolate());
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New();
   templ->SetAccessCheckCallbacks(NamedSetAccessBlocker,
                                  IndexedSetAccessBlocker);
-  templ->Set(v8_str("x"), v8::True());
+  templ->Set(v8_str("x"), v8::True(isolate));
   Local<v8::Object> instance = templ->NewInstance();
   context->Global()->Set(v8_str("obj"), instance);
   Local<Value> value = CompileRun("obj.x");
@@ -14153,14 +14163,14 @@
   // Test LoadIC.
   for (int i = 0; i < 2; i++) {
     LocalContext context;
-    context->Global()->Set(v8_str("tmp"), v8::True());
+    context->Global()->Set(v8_str("tmp"), v8::True(CcTest::isolate()));
     context->Global()->Delete(v8_str("tmp"));
     CompileRun("for (var j = 0; j < 10; j++) new RegExp('');");
   }
   // Test CallIC.
   for (int i = 0; i < 2; i++) {
     LocalContext context;
-    context->Global()->Set(v8_str("tmp"), v8::True());
+    context->Global()->Set(v8_str("tmp"), v8::True(CcTest::isolate()));
     context->Global()->Delete(v8_str("tmp"));
     CompileRun("for (var j = 0; j < 10; j++) RegExp('')");
   }
@@ -19394,20 +19404,20 @@
   CHECK(result1->Equals(simple_object->GetPrototype()));
 
   Local<Value> result2 = CompileRun("Object.getPrototypeOf(protected)");
-  CHECK(result2->Equals(Undefined()));
+  CHECK(result2->Equals(Undefined(isolate)));
 
   Local<Value> result3 = CompileRun("Object.getPrototypeOf(global)");
   CHECK(result3->Equals(global_object->GetPrototype()));
 
   Local<Value> result4 = CompileRun("Object.getPrototypeOf(proxy)");
-  CHECK(result4->Equals(Undefined()));
+  CHECK(result4->Equals(Undefined(isolate)));
 
   Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)");
   CHECK(result5->Equals(
       object_with_hidden->GetPrototype()->ToObject()->GetPrototype()));
 
   Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
-  CHECK(result6->Equals(Undefined()));
+  CHECK(result6->Equals(Undefined(isolate)));
 }
 
 
@@ -19706,16 +19716,12 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   i::Handle<i::Object> undefined_value = factory->undefined_value();
-  CHECK(*v8::Utils::OpenHandle(*v8::Undefined()) == *undefined_value);
   CHECK(*v8::Utils::OpenHandle(*v8::Undefined(isolate)) == *undefined_value);
   i::Handle<i::Object> null_value = factory->null_value();
-  CHECK(*v8::Utils::OpenHandle(*v8::Null()) == *null_value);
   CHECK(*v8::Utils::OpenHandle(*v8::Null(isolate)) == *null_value);
   i::Handle<i::Object> true_value = factory->true_value();
-  CHECK(*v8::Utils::OpenHandle(*v8::True()) == *true_value);
   CHECK(*v8::Utils::OpenHandle(*v8::True(isolate)) == *true_value);
   i::Handle<i::Object> false_value = factory->false_value();
-  CHECK(*v8::Utils::OpenHandle(*v8::False()) == *false_value);
   CHECK(*v8::Utils::OpenHandle(*v8::False(isolate)) == *false_value);
 }
 
@@ -20158,10 +20164,11 @@
 
 THREADED_TEST(Regress2746) {
   LocalContext context;
-  v8::HandleScope scope(context->GetIsolate());
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope scope(isolate);
   Local<Object> obj = Object::New();
   Local<String> key = String::New("key");
-  obj->SetHiddenValue(key, v8::Undefined());
+  obj->SetHiddenValue(key, v8::Undefined(isolate));
   Local<Value> value = obj->GetHiddenValue(key);
   CHECK(!value.IsEmpty());
   CHECK(value->IsUndefined());
@@ -20341,7 +20348,8 @@
                              Local<v8::Value> data) {
   access_check_fail_thrown = true;
   i::PrintF("Access check failed. Error thrown.\n");
-  v8::ThrowException(v8::Exception::Error(v8_str("cross context")));
+  CcTest::isolate()->ThrowException(
+      v8::Exception::Error(v8_str("cross context")));
 }
 
 
@@ -20584,3 +20592,24 @@
   CHECK_EQ(v8::Integer::New(17, isolate), result2);
 }
 
+
+TEST(EscapeableHandleScope) {
+  HandleScope outer_scope(CcTest::isolate());
+  LocalContext context;
+  const int runs = 10;
+  Local<String> values[runs];
+  for (int i = 0; i < runs; i++) {
+    v8::EscapableHandleScope inner_scope(CcTest::isolate());
+    Local<String> value;
+    if (i != 0) value = v8_str("escape value");
+    values[i] = inner_scope.Escape(value);
+  }
+  for (int i = 0; i < runs; i++) {
+    Local<String> expected;
+    if (i != 0) {
+      CHECK_EQ(v8_str("escape value"), values[i]);
+    } else {
+      CHECK(values[i].IsEmpty());
+    }
+  }
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 8a3bfa4..df6d1f5 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -2400,7 +2400,8 @@
 // the correct results.
 TEST(DebugEvaluate) {
   DebugLocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
   env.ExposeDebug();
 
   // Create a function for checking the evaluation when hitting a break point.
@@ -2413,13 +2414,13 @@
   // Different expected vaules of x and a when in a break point (u = undefined,
   // d = Hello, world!).
   struct EvaluateCheck checks_uu[] = {
-    {"x", v8::Undefined()},
-    {"a", v8::Undefined()},
+    {"x", v8::Undefined(isolate)},
+    {"a", v8::Undefined(isolate)},
     {NULL, v8::Handle<v8::Value>()}
   };
   struct EvaluateCheck checks_hu[] = {
     {"x", v8::String::New("Hello, world!")},
-    {"a", v8::Undefined()},
+    {"a", v8::Undefined(isolate)},
     {NULL, v8::Handle<v8::Value>()}
   };
   struct EvaluateCheck checks_hh[] = {
@@ -2485,7 +2486,7 @@
   // parameter.
   checks = checks_uu;
   v8::Handle<v8::Value> argv_bar_1[2] = {
-    v8::Undefined(),
+    v8::Undefined(isolate),
     v8::Number::New(barbar_break_position)
   };
   bar->Call(env->Global(), 2, argv_bar_1);
@@ -3105,7 +3106,8 @@
 
 TEST(DebugStepIf) {
   DebugLocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
 
   // Register a debug event listener which steps and counts.
   v8::Debug::SetDebugEventListener2(DebugEventStep);
@@ -3129,14 +3131,14 @@
   // Stepping through the true part.
   step_action = StepIn;
   break_point_hit_count = 0;
-  v8::Handle<v8::Value> argv_true[argc] = { v8::True() };
+  v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) };
   foo->Call(env->Global(), argc, argv_true);
   CHECK_EQ(4, break_point_hit_count);
 
   // Stepping through the false part.
   step_action = StepIn;
   break_point_hit_count = 0;
-  v8::Handle<v8::Value> argv_false[argc] = { v8::False() };
+  v8::Handle<v8::Value> argv_false[argc] = { v8::False(isolate) };
   foo->Call(env->Global(), argc, argv_false);
   CHECK_EQ(5, break_point_hit_count);
 
@@ -3507,7 +3509,8 @@
 
 TEST(DebugConditional) {
   DebugLocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
 
   // Register a debug event listener which steps and counts.
   v8::Debug::SetDebugEventListener2(DebugEventStep);
@@ -3531,7 +3534,7 @@
   step_action = StepIn;
   break_point_hit_count = 0;
   const int argc = 1;
-  v8::Handle<v8::Value> argv_true[argc] = { v8::True() };
+  v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) };
   foo->Call(env->Global(), argc, argv_true);
   CHECK_EQ(5, break_point_hit_count);
 
@@ -3759,7 +3762,8 @@
 // Test that step in works with function.call.
 TEST(DebugStepFunctionCall) {
   DebugLocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
 
   // Create a function for testing stepping.
   v8::Local<v8::Function> foo = CompileFunction(
@@ -3786,7 +3790,7 @@
   // Check stepping where the if condition in bar is true.
   break_point_hit_count = 0;
   const int argc = 1;
-  v8::Handle<v8::Value> argv[argc] = { v8::True() };
+  v8::Handle<v8::Value> argv[argc] = { v8::True(isolate) };
   foo->Call(env->Global(), argc, argv);
   CHECK_EQ(8, break_point_hit_count);
 
diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc
index e82c090..de27286 100644
--- a/test/cctest/test-decls.cc
+++ b/test/cctest/test-decls.cc
@@ -228,13 +228,14 @@
 // about and doesn't handle.
 TEST(Unknown) {
   HandleScope scope(CcTest::isolate());
+  v8::V8::Initialize();
 
   { DeclarationContext context;
     context.Check("var x; x",
                   1,  // access
                   1,  // declaration
                   2,  // declaration + initialization
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { DeclarationContext context;
@@ -258,15 +259,16 @@
                   1,  // access
                   2,  // declaration + initialization
                   1,  // declaration
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { DeclarationContext context;
+    // SB 0 - BUG 1213579
     context.Check("const x = 0; x",
                   1,  // access
                   2,  // declaration + initialization
                   1,  // declaration
-                  EXPECT_RESULT, Undefined());  // SB 0 - BUG 1213579
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 }
 
@@ -313,7 +315,7 @@
                   1,  // access
                   1,  // initialization
                   1,  // (re-)declaration
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { PresentPropertyContext context;
@@ -336,14 +338,16 @@
 
 
 TEST(Absent) {
-  HandleScope scope(CcTest::isolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::V8::Initialize();
+  HandleScope scope(isolate);
 
   { AbsentPropertyContext context;
     context.Check("var x; x",
                   1,  // access
                   1,  // declaration
                   2,  // declaration + initialization
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(isolate));
   }
 
   { AbsentPropertyContext context;
@@ -367,7 +371,7 @@
                   1,  // access
                   2,  // declaration + initialization
                   1,  // declaration
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(isolate));
   }
 
   { AbsentPropertyContext context;
@@ -375,7 +379,7 @@
                   1,  // access
                   2,  // declaration + initialization
                   1,  // declaration
-                  EXPECT_RESULT, Undefined());  // SB 0 - BUG 1213579
+                  EXPECT_RESULT, Undefined(isolate));  // SB 0 - BUG 1213579
   }
 
   { AbsentPropertyContext context;
@@ -383,7 +387,7 @@
                   1,  // access
                   1,  // declaration
                   1,  // declaration + initialization
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(isolate));
   }
 }
 
@@ -426,6 +430,7 @@
 
 
 TEST(Appearing) {
+  v8::V8::Initialize();
   HandleScope scope(CcTest::isolate());
 
   { AppearingPropertyContext context;
@@ -433,7 +438,7 @@
                   1,  // access
                   1,  // declaration
                   2,  // declaration + initialization
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { AppearingPropertyContext context;
@@ -457,7 +462,7 @@
                   1,  // access
                   2,  // declaration + initialization
                   1,  // declaration
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { AppearingPropertyContext context;
@@ -465,7 +470,7 @@
                   1,  // access
                   2,  // declaration + initialization
                   1,  // declaration
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
                   // Result is undefined because declaration succeeded but
                   // initialization to 0 failed (due to context behavior).
   }
@@ -518,6 +523,7 @@
 
 
 TEST(Reappearing) {
+  v8::V8::Initialize();
   HandleScope scope(CcTest::isolate());
 
   { ReappearingPropertyContext context;
@@ -525,7 +531,7 @@
                   0,
                   3,  // const declaration+initialization, var initialization
                   3,  // 2 x declaration + var initialization
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 }
 
@@ -564,7 +570,7 @@
                   0,
                   0,
                   0,
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { ExistsInPrototypeContext context;
@@ -580,7 +586,7 @@
                   0,
                   0,
                   0,
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { ExistsInPrototypeContext context;
@@ -610,6 +616,7 @@
 
 TEST(AbsentInPrototype) {
   i::FLAG_es52_globals = true;
+  v8::V8::Initialize();
   HandleScope scope(CcTest::isolate());
 
   { AbsentInPrototypeContext context;
@@ -617,7 +624,7 @@
                   0,
                   0,
                   0,
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 }
 
@@ -689,7 +696,7 @@
                   0,
                   0,
                   1,  // (re-)declaration
-                  EXPECT_RESULT, Undefined());
+                  EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   // TODO(mstarzinger): The semantics of global const is vague.
diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc
index 0c8e1cd..bf10295 100644
--- a/test/cctest/test-object-observe.cc
+++ b/test/cctest/test-object-observe.cc
@@ -394,7 +394,7 @@
     { obj, "updated", "foo", Number::New(75) }
   };
   EXPECT_RECORDS(CompileRun("records"), expected_records);
-  obj->SetPrototype(Null());
+  obj->SetPrototype(Null(isolate.GetIsolate()));
   CompileRun("obj.foo = 43");
   const RecordExpectation expected_records2[] = {
     { obj, "new", "foo", Handle<Value>() }
diff --git a/test/cctest/test-unique.cc b/test/cctest/test-unique.cc
index 8a81dec..0936908 100644
--- a/test/cctest/test-unique.cc
+++ b/test/cctest/test-unique.cc
@@ -165,6 +165,46 @@
 }
 
 
+TEST(UniqueSet_Remove) {
+  CcTest::InitializeVM();
+  MAKE_HANDLES_AND_DISALLOW_ALLOCATION;
+  MAKE_UNIQUES_A_B_C;
+
+  Zone zone(isolate);
+
+  UniqueSet<String>* set = new(&zone) UniqueSet<String>();
+
+  set->Add(A, &zone);
+  set->Add(B, &zone);
+  set->Add(C, &zone);
+  CHECK_EQ(3, set->size());
+
+  set->Remove(A);
+  CHECK_EQ(2, set->size());
+  CHECK(!set->Contains(A));
+  CHECK(set->Contains(B));
+  CHECK(set->Contains(C));
+
+  set->Remove(A);
+  CHECK_EQ(2, set->size());
+  CHECK(!set->Contains(A));
+  CHECK(set->Contains(B));
+  CHECK(set->Contains(C));
+
+  set->Remove(B);
+  CHECK_EQ(1, set->size());
+  CHECK(!set->Contains(A));
+  CHECK(!set->Contains(B));
+  CHECK(set->Contains(C));
+
+  set->Remove(C);
+  CHECK_EQ(0, set->size());
+  CHECK(!set->Contains(A));
+  CHECK(!set->Contains(B));
+  CHECK(!set->Contains(C));
+}
+
+
 TEST(UniqueSet_Contains) {
   CcTest::InitializeVM();
   MAKE_HANDLES_AND_DISALLOW_ALLOCATION;
diff --git a/test/mjsunit/compiler/escape-analysis.js b/test/mjsunit/compiler/escape-analysis.js
index 74e638a..21ebcbb 100644
--- a/test/mjsunit/compiler/escape-analysis.js
+++ b/test/mjsunit/compiler/escape-analysis.js
@@ -271,3 +271,33 @@
   %OptimizeFunctionOnNextCall(oob);
   assertEquals(7, oob(cons2, true));
 })();
+
+
+// Test non-shallow nested graph of captured objects.
+(function testDeep() {
+  var deopt = { deopt:false };
+  function constructor1() {
+    this.x = 23;
+  }
+  function constructor2(nested) {
+    this.a = 17;
+    this.b = nested;
+    this.c = 42;
+  }
+  function deep() {
+    var o1 = new constructor1();
+    var o2 = new constructor2(o1);
+    assertEquals(17, o2.a);
+    assertEquals(23, o2.b.x);
+    assertEquals(42, o2.c);
+    o1.x = 99;
+    deopt.deopt;
+    assertEquals(99, o1.x);
+    assertEquals(99, o2.b.x);
+  }
+  deep(); deep();
+  %OptimizeFunctionOnNextCall(deep);
+  deep(); deep();
+  delete deopt.deopt;
+  deep(); deep();
+})();
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 1850c0e..94c79fb 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -270,6 +270,7 @@
         '../../src/debug-agent.h',
         '../../src/debug.cc',
         '../../src/debug.h',
+        '../../src/defaults.cc',
         '../../src/deoptimizer.cc',
         '../../src/deoptimizer.h',
         '../../src/disasm.h',
@@ -333,6 +334,8 @@
         '../../src/hydrogen-bch.h',
         '../../src/hydrogen-canonicalize.cc',
         '../../src/hydrogen-canonicalize.h',
+        '../../src/hydrogen-check-elimination.cc',
+        '../../src/hydrogen-check-elimination.h',
         '../../src/hydrogen-dce.cc',
         '../../src/hydrogen-dce.h',
         '../../src/hydrogen-dehoist.cc',